Skip to main content

Overview

Context types provide type-safe access to event data and response methods. All contexts include msg, reply(), and edit() properties.

BaseContext

Base type for all event contexts.
type BaseContext<TPayload> = {
  msg: TPayload
  reply: (content: string | MessageReplyOptions) => Promise<void>
  edit: (content: string | MessageEditOptions) => Promise<void>
}

Properties

msg
TPayload
The event payload containing all event-specific data
reply
(content: string | MessageReplyOptions) => Promise<void>
Send a reply message
edit
(content: string | MessageEditOptions) => Promise<void>
Edit the original message (for bot messages)

MessageContext

Context for messageCreate events.
type MessageContext = BaseContext<EventMessage>

Event Payload (msg)

id
string
The message’s unique snowflake ID
channelId
string
The channel where the message was sent
guildId
string | undefined
The guild ID (undefined for DMs)
content
string
The message text content
author
EventUser
The user who sent the message
member
EventMember | undefined
Member data if sent in a guild

Example

on('messageCreate', async (ctx: MessageContext) => {
  console.log(`${ctx.msg.author.username}: ${ctx.msg.content}`)
  
  if (ctx.msg.content === 'ping') {
    await ctx.reply('Pong!')
  }
})

InteractionContext

Context for slash command interactions.
type InteractionContext = BaseContext<EventInteractionCreate> & {
  options: SlashCommandOptions
}

Event Payload (msg)

interactionId
string
Unique interaction ID
interactionToken
string
Token for responding to the interaction
commandName
string
Name of the invoked command
user
EventUser
User who invoked the command
member
EventMember | undefined
Member data if invoked in a guild
channelId
string | undefined
Channel where command was invoked
guildId
string | undefined
Guild where command was invoked
data
JsonValue
Raw interaction data from Discord
locale
string | undefined
User’s locale (e.g., β€˜en-US’)
guildLocale
string | undefined
Guild’s preferred locale

Additional Property

options
SlashCommandOptions
Flattened command options as key-value pairs
type SlashCommandOptions = Record<string, string | number | boolean | undefined>

Example

slash({
  name: 'greet',
  description: 'Greet a user',
  options: [{
    name: 'name',
    type: 'string',
    required: true
  }],
  run: async (ctx: InteractionContext) => {
    const name = ctx.options.name as string
    const userId = ctx.msg.user.id
    
    await ctx.reply(`Hello ${name}! (from ${userId})`)
  }
})

ComponentInteractionContext

Context for button clicks and select menu interactions.
type ComponentInteractionContext = BaseContext<EventComponentInteraction>

Event Payload (msg)

interactionId
string
Unique interaction ID
interactionToken
string
Token for responding
user
EventUser
User who clicked/selected
data
JsonValue
Component interaction data (includes custom_id, values, etc.)
messageId
string | undefined
ID of the message containing the component

Example

on('componentInteraction', async (ctx: ComponentInteractionContext) => {
  const data = ctx.msg.data as any
  
  if (data.custom_id === 'accept_button') {
    await ctx.reply('You clicked accept!')
  }
})

ModalSubmitContext

Context for modal (form) submissions.
type ModalSubmitContext = BaseContext<EventModalSubmit>

Event Payload (msg)

interactionId
string
Unique interaction ID
interactionToken
string
Token for responding
user
EventUser
User who submitted the modal
data
JsonValue
Modal submission data (includes field values)

Example

on('modalSubmit', async (ctx: ModalSubmitContext) => {
  const data = ctx.msg.data as any
  // Extract field values from data.components
  
  await ctx.reply('Form submitted successfully!')
})

MessageUpdateContext

Context for message edit events.
type MessageUpdateContext = BaseContext<EventMessageUpdate>

Event Payload (msg)

id
string
Message ID
channelId
string
Channel ID
content
string | undefined
New content (partial update)
editedTimestamp
string | undefined
ISO8601 timestamp of the edit
old
EventMessage | undefined
Previous message state (if cached)
new
EventMessage | undefined
New message state (if cached)

Example

on('messageUpdate', async (ctx: MessageUpdateContext) => {
  if (ctx.msg.old && ctx.msg.new) {
    console.log('Before:', ctx.msg.old.content)
    console.log('After:', ctx.msg.new.content)
  }
})

MessageDeleteContext

Context for message deletion events.
type MessageDeleteContext = BaseContext<EventMessageDelete>

Event Payload (msg)

id
string
Deleted message ID
channelId
string
Channel ID
guildId
string | undefined
Guild ID

ReactionContext

Context for reaction add/remove events.
type ReactionContext = BaseContext<EventReaction>

Event Payload (msg)

userId
string | undefined
User who added/removed the reaction
messageId
string
Message that was reacted to
channelId
string
Channel ID
emoji
JsonValue
Emoji object (includes name, id for custom emoji)
burst
boolean
Whether it’s a super reaction

Example

on('reactionAdd', async (ctx: ReactionContext) => {
  const emoji = ctx.msg.emoji as any
  console.log(`User ${ctx.msg.userId} reacted with ${emoji.name}`)
})

CronContext

Context for scheduled cron jobs.
type CronContext = {
  name: string
  scheduledAt: string
}

Properties

name
string
The cron job name
scheduledAt
string
ISO8601 timestamp when execution was scheduled

Example

cron('daily-task', '0 0 * * *', async (ctx: CronContext) => {
  console.log(`Running ${ctx.name} at ${ctx.scheduledAt}`)
})

Notes

  • All contexts with msg property follow the BaseContext<TPayload> pattern
  • Use type guards to safely access optional properties
  • The reply() method works for both messages and interactions
  • Interaction contexts include automatic token handling
  • Guild-only bots can safely assume guildId is always present

Build docs developers (and LLMs) love