Events

Client extends an EventEmitter. Listen with client.on('name', handler). Handlers are fully typed.

Client extends an EventEmitter. Listen with client.on('name', handler). Handlers are fully typed.

client.on('messageCreate', (message) => {
  // message is a Message
});

Lifecycle

EventArguments
ready() once all shards are ready
connect(shardID)
disconnect(error?)
resume()
shardPreReady(shardID) REST queue released
shardReady(shardID)
shardResume(shardID)
shardDisconnect(error, shardID)
hello(trace, shardID)
error(error, shard?) always handle this
debug(info, shard?) verbose; dev only
warn(info, shard?)
rateLimited(data, shardID) Discord rate limited a gateway send (member chunk requests); data is the raw { opcode, retry_after, meta: { guild_id, nonce? } }
rawWS(packet, shardID) every gateway packet
rawREST(data) after every REST call
unknown(packet, shardID) dispatch Athena does not recognise

Users, members, voice

userUpdate, presenceUpdate, voiceStateUpdate, voiceChannelJoin, voiceChannelLeave, voiceChannelSwitch, typingStart, guildMemberAdd, guildMemberUpdate, guildMemberRemove, guildMemberChunk.

Messages

messageCreate, messageUpdate, messageDelete, messageDeleteBulk, messageReactionAdd, messageReactionRemove, messageReactionRemoveAll, messageReactionRemoveEmoji, channelPinUpdate, messagePollVoteAdd, messagePollVoteRemove.

For events on objects not in cache, Athena gives a partial (for example a message with only id, channel, guildID). Guard with instanceof Message when you need full data.

Guilds, channels, threads

guildAvailable, guildCreate, unavailableGuildCreate, guildUpdate, guildUnavailable, guildDelete, guildBanAdd, guildBanRemove, guildRoleCreate, guildRoleUpdate, guildRoleDelete, guildEmojisUpdate, guildStickersUpdate, inviteCreate, inviteDelete, channelCreate, channelUpdate, channelDelete, webhooksUpdate, threadCreate, threadUpdate, threadDelete, threadListSync, threadMemberUpdate, threadMembersUpdate, stageInstanceCreate, stageInstanceUpdate, stageInstanceDelete, guildAuditLogEntryCreate, voiceChannelStatusUpdate, voiceChannelStartTimeUpdate, channelInfo.

The last three carry raw payloads: voiceChannelStatusUpdate gives (data: { id, guild_id, status }), voiceChannelStartTimeUpdate gives (data: { id, guild_id, voice_start_time? }), and channelInfo gives (data: { guild_id, channels: [...] }) in answer to client.requestChannelInfo.

guildAuditLogEntryCreate gives you a GuildAuditLogEntry. Its entry.target resolves the cached thing the action was performed on, or null when Athena caches nothing for that action type (webhooks, integrations, soundboard sounds, monetization, onboarding, home settings, and anything Discord adds next). entry.targetID is always set, so fetch from the API when you need more. Voice channel status changes (action types 192 and 193) resolve the voice channel, and the new status is on entry.status.

Integrations, soundboard, automod, scheduled events

integrationCreate, integrationUpdate, integrationDelete, guildIntegrationsUpdate, soundboardSounds, guildSoundboardSoundCreate, guildSoundboardSoundUpdate, guildSoundboardSoundDelete, guildSoundboardSoundsUpdate, voiceChannelEffectSend, applicationCommandPermissionsUpdate, autoModerationRuleCreate, autoModerationRuleUpdate, autoModerationRuleDelete, autoModerationActionExecution, guildScheduledEventCreate, guildScheduledEventUpdate, guildScheduledEventDelete, guildScheduledEventUserAdd, guildScheduledEventUserRemove.

Interactions

interactionCreate fires for every interaction. Narrow it with type guards:

client.on('interactionCreate', (interaction) => {
  if (interaction.isCommand()) { /* CommandInteraction */ }
  else if (interaction.isComponent()) { /* ComponentInteraction */ }
  else if (interaction.isModal()) { /* ModalSubmitInteraction */ }
  else if (interaction.isAutocomplete()) { /* AutocompleteInteraction */ }
});

Monetization

entitlementCreate, entitlementUpdate, entitlementDelete, subscriptionCreate, subscriptionUpdate, subscriptionDelete.

CommandClient extras

When using the commands framework: commandError and commandExecuted.

The catch-all

event fires for every emit: (eventName, ...args). Handy for one central logger.

Tips

  • Always attach an error listener.
  • Subscribe to debug only in development; it is very chatty.
  • Uncached objects are normal for bots that restart often. Handle the partial case.