Events
Gateway event handlers with frequency control and concurrent execution.
Event handlers are created by placing files in the src/events/ directory. The file name matches the Discord.js event name, and the default export is the handler function.
File structure
Handler signature
The default export receives the same arguments as the corresponding Discord.js event:
import type { Message } from 'discord.js'
export default (message: Message) => {
if (message.content === '!hello') {
message.reply('Hello there!')
}
}export default (message) => {
if (message.content === '!hello') {
message.reply('Hello there!')
}
}Event config
Export a config object to configure the event handler.
Prop
Type
import type { EventConfig } from '@robojs/discordjs'
import type { Client } from 'discord.js'
export const config: EventConfig = {
frequency: 'once'
}
export default (client: Client) => {
console.log(`Logged in as ${client.user?.tag}`)
}export const config = {
frequency: 'once'
}
export default (client) => {
console.log(`Logged in as ${client.user?.tag}`)
}Multiple handlers per event
Create a directory with the event name and place multiple handler files inside. Each handler runs independently.
When multiple handlers exist for the same event, Robo starts them in priority order and waits for them concurrently. Each handler runs independently.
Priority field
The priority field controls the order handlers are started. Lower values run first. Async handlers still complete independently, so use shared functions or middleware when later logic must wait on earlier logic.
import type { EventConfig } from '@robojs/discordjs'
export const config: EventConfig = {
priority: -10 // starts before handlers with priority 0
}
export default (message) => {
// Starts before default-priority messageCreate handlers
}If you need one handler to wait for another handler's async work, call shared functions explicitly from a single handler.
Frequency control
When frequency: 'once' is set, the handler is disabled at runtime after its first execution. Internally, this sets the handler record's enabled flag to false, preventing it from running again. The handler re-enables on restart since the flag is not persisted.
This is useful for one-time setup logic like the clientReady event:
import type { EventConfig } from '@robojs/discordjs'
import type { Client } from 'discord.js'
export const config: EventConfig = {
frequency: 'once'
}
export default (client: Client) => {
console.log(`Logged in as ${client.user?.tag}`)
}Plugin options argument
If an event handler belongs to a plugin, pluginOptions is appended as an additional argument after the Discord.js event arguments. This allows plugin handlers to access their configuration at runtime.
import type { Message } from 'discord.js'
interface MyPluginOptions {
prefix: string
}
export default (message: Message, pluginOptions: MyPluginOptions) => {
// message is from Discord.js
// pluginOptions contains the plugin's config
if (message.content.startsWith(pluginOptions.prefix)) {
// handle prefixed message
}
}export default (message, pluginOptions) => {
// message is from Discord.js
// pluginOptions contains the plugin's config
if (message.content.startsWith(pluginOptions.prefix)) {
// handle prefixed message
}
}For non-plugin handlers, this extra argument is undefined.
Intent requirements
Events require specific gateway intents. The plugin infers required intents from your registered events automatically. If you use events that require privileged intents, you must enable them explicitly. See Intents & permissions for details.
