Events
Events are declared with createEvent and map to Discord.js event names.
Arcscord does not add gateway intents automatically. Instead, the event manager
can warn or throw when a loaded event is not covered by the client intents.
Discord documents gateway intents in the Gateway intents reference, and discord.js documents client setup in its guide.
import { ArcClient, createEvent } from "arcscord";
export const messageEvent = createEvent({
event: "messageCreate",
name: "messageLogger",
run: (ctx, msg) => {
ctx.client.logger.info(`message sent by ${msg.author.username}`);
return ctx.ok(true);
},
});
const client = new ArcClient(process.env.DISCORD_TOKEN!, {
intents: ["Guilds", "GuildMessages"],
managers: {
event: {
intentCheck: {
missing: "warn",
partialCoverage: "off",
coverage: {
guild: true,
dm: true,
},
ignore: [],
},
},
},
});
await client.loadEvents([messageEvent]);
Loading events
Use client.loadEvents when you already have an array of event handlers:
import { ArcClient } from "arcscord";
import { messageEvent } from "./events/message";
import { readyEvent } from "./events/ready";
const client = new ArcClient(process.env.DISCORD_TOKEN!, {
intents: ["Guilds", "GuildMessages"],
});
await client.loadEvents([messageEvent, readyEvent]);
loadEvents returns the number of loaded handlers:
const loadedEvents = await client.loadEvents([messageEvent, readyEvent]);
client.logger.info(`Loaded ${loadedEvents} events`);
For applications that keep commands, components, and events in one generated
handler list, use client.loadHandlers:
import handlers from "./_handlers";
await client.loadHandlers(handlers, true /* info logs */);
loadHandlers loads events first, then components, then waits for the client to
be ready before registering commands.
You can also access the manager directly:
await client.eventManager.loadEvent(messageEvent);
await client.eventManager.loadEvents([messageEvent, readyEvent]);
To remove a loaded handler, unload it by handler name:
client.eventManager.unloadEvent("messageLogger");
unloadEvent removes the Discord.js listener registered by Arcscord and returns
true when a handler was found.
Intent checks
intentCheck validates the events you load against client.options.intents.
It never mutates the client intents.
const client = new ArcClient(process.env.DISCORD_TOKEN!, {
intents: ["Guilds"],
managers: {
event: {
intentCheck: {
missing: "throw",
partialCoverage: "warn",
coverage: {
guild: true,
dm: false,
},
ignore: ["presenceUpdate"],
},
},
},
});
Arcscord models event intent requirements in three categories:
none: the event does not require a gateway intent.all: every listed intent must be configured.oneOf: at least one listed intent can receive the event.
missing is used when an event cannot be received with the configured intents:
- for
all, one or more required intents are missing; - for
oneOf, none of the possible intents are configured.
For example, guildCreate requires Guilds, while messageCreate can be
received through GuildMessages for guild messages or DirectMessages for DM
messages.
partialCoverage is used only for oneOf events. It reports that the event is
covered, but not for every target you expect. The coverage object defines
those expectations:
const guildOnlyClient = new ArcClient(process.env.DISCORD_TOKEN!, {
intents: ["Guilds", "GuildMessages"],
managers: {
event: {
intentCheck: {
missing: "warn",
partialCoverage: "warn",
coverage: {
guild: true,
dm: false,
},
},
},
},
});
With this configuration, messageCreate is accepted with only GuildMessages
because DM coverage is explicitly disabled.
For a bot that should receive both guild and DM messages:
const guildAndDmClient = new ArcClient(process.env.DISCORD_TOKEN!, {
intents: ["Guilds", "GuildMessages", "DirectMessages"],
managers: {
event: {
intentCheck: {
missing: "warn",
partialCoverage: "warn",
coverage: {
guild: true,
dm: true,
},
},
},
},
});
If DirectMessages is missing in that setup, Arcscord reports partial coverage
instead of pretending the event is fully configured.
coverage does not weaken missing: if neither GuildMessages nor
DirectMessages is configured for messageCreate, missing still applies even
when coverage.dm is false.
The default intent check configuration is:
{
missing: "warn",
partialCoverage: "off",
coverage: {
guild: true,
dm: true,
},
ignore: [],
}
Set intentCheck: false to disable the check.
Readiness
Handlers are registered immediately. Use beforeReady to control what happens
if Discord.js emits the event before ArcClient.waitReady() has completed.
export const queuedMessageEvent = createEvent({
event: "messageCreate",
options: {
beforeReady: "queue",
},
run: (ctx, msg) => {
ctx.client.logger.info(msg.id);
return ctx.ok(true);
},
});
Available modes:
"run": run immediately, even before ready. This is the default."queue": wait forclient.waitReady()before running the handler."drop": ignore events received before ready.
Once
Use once for handlers that should run once. Arcscord also removes the handler
from the event manager registry after the first event.
export const startupEvent = createEvent({
event: "clientReady",
options: {
once: true,
},
run: (ctx) => {
ctx.client.logger.info("client ready");
return ctx.ok(true);
},
});