Skip to main content

Overview

The on() function registers event handlers for Discord gateway events. Use it to respond to messages, reactions, interactions, and other bot events.

Signature

function on<E extends keyof FloraEventMap>(
  event: E,
  handler: (ctx: FloraEventMap[E]) => void | Promise<void>
): void

Parameters

event
string
required
The name of the event to listen for. See Available Events below.
handler
function
required
Async or sync function that receives the event context

Available Events

ready

Fired when the bot successfully connects to Discord.
on('ready', (ctx) => {
  console.log(`Bot logged in as ${ctx.msg.user.username}`)
})
Context properties:
  • msg.user - The bot user object
  • msg.guildIds - Array of guild IDs the bot is in

messageCreate

Fired when a new message is sent in a channel the bot can see.
on('messageCreate', async (ctx) => {
  if (ctx.msg.content === 'hello') {
    await ctx.reply('Hi there!')
  }
})
Context properties:
  • msg.id - Message ID
  • msg.content - Message text
  • msg.author - User who sent the message
  • msg.channelId - Channel ID
  • msg.guildId - Guild ID (if in a server)
  • msg.member - Member object (if in a server)
  • reply() - Reply to the message
  • edit() - Edit the message (bot messages only)

messageUpdate

Fired when a message is edited.
on('messageUpdate', async (ctx) => {
  if (ctx.msg.old && ctx.msg.new) {
    console.log('Message edited:', ctx.msg.old.content, '->', ctx.msg.new.content)
  }
})
Context properties:
  • msg.id - Message ID
  • msg.content - New content (partial)
  • msg.old - Previous message state (if cached)
  • msg.new - New message state (if cached)
  • msg.editedTimestamp - ISO8601 timestamp of edit

messageDelete

Fired when a message is deleted.
on('messageDelete', (ctx) => {
  console.log(`Message ${ctx.msg.id} was deleted from ${ctx.msg.channelId}`)
})
Context properties:
  • msg.id - Deleted message ID
  • msg.channelId - Channel ID
  • msg.guildId - Guild ID

messageDeleteBulk

Fired when multiple messages are deleted at once.
on('messageDeleteBulk', (ctx) => {
  console.log(`${ctx.msg.ids.length} messages deleted`)
})
Context properties:
  • msg.ids - Array of deleted message IDs
  • msg.channelId - Channel ID
  • msg.guildId - Guild ID

interactionCreate

Fired when a slash command is invoked. Usually handled automatically by createBot().
on('interactionCreate', async (ctx) => {
  console.log(`Command ${ctx.msg.commandName} used by ${ctx.msg.user.username}`)
})
Context properties:
  • msg.commandName - Name of the command
  • msg.interactionId - Unique interaction ID
  • msg.interactionToken - Token for responding
  • msg.user - User who invoked the command
  • msg.member - Member object (if in guild)
  • msg.data - Raw interaction data
  • options - Flattened command options
  • reply() - Respond to the interaction

componentInteraction

Fired when a user interacts with a button or select menu.
on('componentInteraction', async (ctx) => {
  const customId = (ctx.msg.data as any)?.custom_id
  if (customId === 'my_button') {
    await ctx.reply('Button clicked!')
  }
})
Context properties:
  • msg.interactionId - Unique interaction ID
  • msg.interactionToken - Token for responding
  • msg.user - User who clicked
  • msg.data - Component interaction data (includes custom_id)
  • msg.messageId - ID of message containing the component
  • reply() - Respond to the interaction

modalSubmit

Fired when a user submits a modal (form).
on('modalSubmit', async (ctx) => {
  const data = ctx.msg.data as any
  await ctx.reply('Form submitted!')
})
Context properties:
  • msg.interactionId - Unique interaction ID
  • msg.interactionToken - Token for responding
  • msg.user - User who submitted
  • msg.data - Modal submission data
  • reply() - Respond to the submission

reactionAdd

Fired when a reaction is added to a message.
on('reactionAdd', (ctx) => {
  console.log(`User ${ctx.msg.userId} reacted with emoji`, ctx.msg.emoji)
})
Context properties:
  • msg.userId - User who reacted
  • msg.messageId - Message that was reacted to
  • msg.channelId - Channel ID
  • msg.emoji - Emoji object
  • msg.burst - Whether it’s a super reaction

reactionRemove

Fired when a reaction is removed from a message.
on('reactionRemove', (ctx) => {
  console.log('Reaction removed')
})
Context properties: Same as reactionAdd

reactionRemoveEmoji

Fired when all instances of a specific emoji are removed.
on('reactionRemoveEmoji', (ctx) => {
  console.log('All reactions of type removed:', ctx.msg.emoji)
})
Context properties: Same as reactionAdd

reactionRemoveAll

Fired when all reactions are removed from a message.
on('reactionRemoveAll', (ctx) => {
  console.log('All reactions cleared from', ctx.msg.messageId)
})
Context properties:
  • msg.messageId - Message ID
  • msg.channelId - Channel ID
  • msg.guildId - Guild ID

Multiple Handlers

You can register multiple handlers for the same event:
on('messageCreate', async (ctx) => {
  // Handler 1: Log messages
  console.log('Message:', ctx.msg.content)
})

on('messageCreate', async (ctx) => {
  // Handler 2: Auto-react to keywords
  if (ctx.msg.content.includes('flora')) {
    await ctx.reply('Did someone mention me?')
  }
})
All handlers are executed in order of registration.

Notes

  • Event handlers can be async or sync
  • Multiple handlers for the same event are supported
  • The ready event fires once when the bot connects
  • Most events include reply() and edit() helper methods
  • For slash commands, use createBot() instead of manually handling interactionCreate

Build docs developers (and LLMs) love