A comprehensive guide to all Discord.js v14 client events with complete examples and descriptions
This cheatsheet covers all available events in Discord.js 14.25.1 with detailed explanations, parameters, and usage examples. Learn from this resource and apply it to your own projects!
- Setup & Configuration
- Ready Events
- Application Command Events
- Auto Moderation Events
- Channel Events
- Guild Events
- Guild Member Events
- Guild Scheduled Events
- Guild Soundboard Events
- Interaction Events
- Invite Events
- Message Events
- Message Reaction Events
- Presence & User Events
- Role Events
- Shard Events
- Stage Instance Events
- Sticker & Emoji Events
- Subscription Events
- Thread Events
- Voice Events
- Misc Events
Before listening to events, you need to set up your bot client with proper intents and login credentials.
// Import required modules from discord.js
const { Client, GatewayIntentBits, Events } = require('discord.js');
// Create a new client instance with specific intents
// Intents specify which events your bot will receive
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.GuildBans,
GatewayIntentBits.GuildEmojisAndStickers,
GatewayIntentBits.GuildIntegrations,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildScheduledEvents,
GatewayIntentBits.AutoModerationExecution,
GatewayIntentBits.AutoModerationConfiguration,
],
});
// Login to Discord with your bot token
client.login(process.env.DISCORD_TOKEN);Store your token securely using environment variables or config files:
// Using .env file with dotenv package
require('dotenv').config();
const token = process.env.DISCORD_TOKEN;
// Or using config.json (don't commit this to git!)
const { token } = require('./config.json');
// Always store sensitive data in .gitignore
// .gitignore should contain:
// - .env
// - config.json
// - node_modulesEmitted when the client becomes ready to start working. This is the first event that fires and indicates the bot has successfully connected to Discord's gateway.
// Event fires when the bot successfully logs in and is ready
client.on(Events.ClientReady, readyClient => {
// Get the authenticated user information
console.log(`✅ Bot is ready! Logged in as ${readyClient.user.tag}`);
console.log(`👥 Serving ${readyClient.users.cache.size} users`);
console.log(`�� In ${readyClient.guilds.cache.size} guilds`);
console.log(`� In ${readyClient.channels.cache.size} channels`);
// Set bot activity/status
readyClient.user.setActivity('your favorite command', { type: 'WATCHING' });
// Activity types: PLAYING, STREAMING, LISTENING, WATCHING, COMPETING
});Emitted whenever permissions for an application command in a guild were updated. This includes permission updates for other applications in addition to the logged-in client.
// Triggered when an app command's permissions change in a guild
client.on(Events.ApplicationCommandPermissionsUpdate, data => {
console.log(`⚙� Command permissions updated for application: ${data.applicationId}`);
console.log(`�� Guild: ${data.guild?.id || 'Global'}`);
console.log(`� New permissions:`, data);
// You can check if it's your bot's application
if (data.applicationId === client.application?.id) {
console.log('Your bot\'s command permissions were updated!');
}
});Emitted whenever an auto moderation rule is triggered and an action is executed.
// Triggered when an auto moderation rule executes an action
client.on(Events.AutoModerationActionExecution, autoModerationActionExecution => {
console.log(`🚫 Auto Moderation Action Executed`);
console.log(`⚠� Rule: ${autoModerationActionExecution.ruleId}`);
console.log(`� Action: ${autoModerationActionExecution.action.type}`);
console.log(`👤 User: ${autoModerationActionExecution.userId}`);
console.log(`💬 Reason: ${autoModerationActionExecution.reason}`);
});Emitted whenever an auto moderation rule is created in a guild.
// Triggered when a new auto moderation rule is created
client.on(Events.AutoModerationRuleCreate, autoModerationRule => {
console.log(`✨ New Auto Moderation Rule Created`);
console.log(`🔖 Rule ID: ${autoModerationRule.id}`);
console.log(`📋 Rule Name: ${autoModerationRule.name}`);
console.log(`�� Guild: ${autoModerationRule.guildId}`);
console.log(`� Trigger: ${autoModerationRule.triggerType}`);
});Emitted whenever an auto moderation rule is deleted.
// Triggered when an auto moderation rule is deleted
client.on(Events.AutoModerationRuleDelete, autoModerationRule => {
console.log(`🗑� Auto Moderation Rule Deleted`);
console.log(`🔖 Rule ID: ${autoModerationRule.id}`);
console.log(`📋 Rule Name: ${autoModerationRule.name}`);
});Emitted whenever an auto moderation rule is updated.
// Triggered when an auto moderation rule is updated
client.on(Events.AutoModerationRuleUpdate, (oldRule, newRule) => {
console.log(`�� Auto Moderation Rule Updated`);
console.log(`🔖 Rule ID: ${newRule.id}`);
// Compare old and new values to see what changed
if (oldRule.name !== newRule.name) {
console.log(`📋 Name changed: "${oldRule.name}" → "${newRule.name}"`);
}
if (oldRule.enabled !== newRule.enabled) {
console.log(`🔄 Enabled changed: ${oldRule.enabled} → ${newRule.enabled}`);
}
});Emitted whenever a channel is created.
// Triggered when a new channel is created in a guild
client.on(Events.ChannelCreate, channel => {
console.log(`✨ New Channel Created`);
console.log(`#�⃣ Channel: ${channel.name} (${channel.id})`);
console.log(`�� Guild: ${channel.guild?.name || 'Unknown'}`);
console.log(`📊 Type: ${channel.type}`);
// Channel types: GUILD_TEXT, GUILD_VOICE, GUILD_CATEGORY, DM, GROUP_DM, etc.
});Emitted whenever a channel is deleted.
// Triggered when a channel is deleted
client.on(Events.ChannelDelete, channel => {
console.log(`🗑� Channel Deleted`);
console.log(`#�⃣ Channel: ${channel.name}`);
console.log(`�� Guild: ${channel.guild?.name || 'Unknown'}`);
});Emitted whenever a channel is updated (name, topic, permissions, etc.).
// Triggered when channel properties change
client.on(Events.ChannelUpdate, (oldChannel, newChannel) => {
console.log(`�� Channel Updated`);
console.log(`#�⃣ Channel: ${newChannel.name}`);
// Check what changed
if (oldChannel.name !== newChannel.name) {
console.log(`� Name: "${oldChannel.name}" → "${newChannel.name}"`);
}
if (oldChannel.topic !== newChannel.topic) {
console.log(`📌 Topic: "${oldChannel.topic}" → "${newChannel.topic}"`);
}
if (oldChannel.nsfw !== newChannel.nsfw) {
console.log(`🔞 NSFW: ${oldChannel.nsfw} → ${newChannel.nsfw}`);
}
});Emitted whenever the pins of a channel are updated. Due to the nature of the WebSocket event, you need to manually check the pins yourself.
// Triggered when a message is pinned or unpinned
client.on(Events.ChannelPinsUpdate, (channel, date) => {
console.log(`📌 Channel Pins Updated`);
console.log(`#�⃣ Channel: ${channel.name}`);
console.log(`� Update Time: ${date}`);
// Manually fetch pins if needed
channel.messages.fetchPinned().then(pins => {
console.log(`� Total Pinned Messages: ${pins.size}`);
pins.forEach(pin => {
console.log(` - ${pin.author.username}: ${pin.content.substring(0, 50)}`);
});
}).catch(console.error);
});Emitted whenever the client joins a guild (bot added to a server or bot starts up).
// Triggered when bot joins a new guild or connects
client.on(Events.GuildCreate, guild => {
console.log(`✨ Bot Added to Guild`);
console.log(`�� Guild: ${guild.name} (${guild.id})`);
console.log(`👥 Members: ${guild.memberCount}`);
console.log(`👑 Owner: ${guild.ownerId}`);
console.log(`📅 Created: ${guild.createdAt}`);
// Send welcome message to guild owner
guild.owner?.send(`Thanks for adding me to ${guild.name}!`).catch(console.error);
});Emitted whenever a guild is deleted or the bot is kicked/removed from a guild.
// Triggered when bot is removed from a guild or guild is deleted
client.on(Events.GuildDelete, guild => {
console.log(`🗑� Bot Removed from Guild`);
console.log(`�� Guild: ${guild.name}`);
console.log(`👥 Members: ${guild.memberCount}`);
// Clean up any data associated with this guild
// (database records, cached data, etc.)
});Emitted whenever a guild is updated (name change, icon change, etc.).
// Triggered when guild properties change
client.on(Events.GuildUpdate, (oldGuild, newGuild) => {
console.log(`�� Guild Updated`);
console.log(`�� Guild: ${newGuild.name}`);
// Check what changed
if (oldGuild.name !== newGuild.name) {
console.log(`� Name: "${oldGuild.name}" → "${newGuild.name}"`);
}
if (oldGuild.icon !== newGuild.icon) {
console.log(`🖼� Icon Updated`);
}
if (oldGuild.ownerId !== newGuild.ownerId) {
console.log(`👑 Owner: ${oldGuild.ownerId} → ${newGuild.ownerId}`);
}
if (oldGuild.description !== newGuild.description) {
console.log(`📌 Description: "${oldGuild.description}" → "${newGuild.description}"`);
}
});Emitted whenever a guild becomes available or the client's connection to a guild is restored.
// Triggered when a guild becomes available
client.on(Events.GuildAvailable, guild => {
console.log(`✅ Guild Available`);
console.log(`�� Guild: ${guild.name}`);
console.log(`👥 Members: ${guild.memberCount}`);
});Emitted whenever a guild becomes unavailable, likely due to a server outage.
// Triggered when a guild becomes unavailable
client.on(Events.GuildUnavailable, guild => {
console.error(`⚠� Guild Unavailable`);
console.error(`�� Guild: ${guild.name}`);
console.error(`📵 The guild is temporarily unavailable`);
// Don't try to perform operations on this guild
});Emitted whenever a guild integration is updated (Twitch, YouTube subscriptions, etc.).
// Triggered when guild integrations are updated
client.on(Events.GuildIntegrationsUpdate, guild => {
console.log(`🔗 Guild Integrations Updated`);
console.log(`�� Guild: ${guild.name}`);
// Fetch integrations if needed
guild.fetchIntegrations().then(integrations => {
console.log(`📊 Total Integrations: ${integrations.size}`);
integrations.forEach(integration => {
console.log(` - ${integration.type}: ${integration.name}`);
});
}).catch(console.error);
});Emitted whenever a guild audit log entry is created.
// Triggered when an action that creates an audit log entry occurs
client.on(Events.GuildAuditLogEntryCreate, (auditLogEntry, guild) => {
console.log(`📋 Audit Log Entry Created`);
console.log(`�� Guild: ${guild.name}`);
console.log(`👤 Executor: ${auditLogEntry.executor?.tag || 'Unknown'}`);
console.log(`� Action: ${auditLogEntry.action}`);
console.log(`📌 Target: ${auditLogEntry.targetId}`);
// Useful for logging moderator actions, config changes, etc.
});Emitted whenever a user joins a guild.
// Triggered when a user joins a guild
client.on(Events.GuildMemberAdd, member => {
console.log(`👋 New Member Joined`);
console.log(`👤 User: ${member.user.tag}`);
console.log(`�� Guild: ${member.guild.name}`);
console.log(`📅 Account Created: ${member.user.createdAt}`);
// Send welcome message to guild's welcome channel
const welcomeChannel = member.guild.channels.cache.find(
ch => ch.name === 'welcome' && ch.isTextBased()
);
if (welcomeChannel) {
welcomeChannel.send(`Welcome to the server, ${member}!`).catch(console.error);
}
// Optionally assign a default role
const defaultRole = member.guild.roles.cache.find(r => r.name === 'Member');
if (defaultRole) {
member.roles.add(defaultRole).catch(console.error);
}
});Emitted whenever a member leaves a guild or is kicked.
// Triggered when a user leaves or is kicked from a guild
client.on(Events.GuildMemberRemove, member => {
console.log(`👋 Member Left/Kicked`);
console.log(`👤 User: ${member.user.tag}`);
console.log(`�� Guild: ${member.guild.name}`);
// Log member removal to an audit channel
const auditChannel = member.guild.channels.cache.find(
ch => ch.name === 'audit-logs' && ch.isTextBased()
);
if (auditChannel) {
auditChannel.send(`${member.user.tag} has left the server.`).catch(console.error);
}
});Emitted whenever a guild member changes (new role, removed role, nickname, etc.).
// Triggered when member properties change
client.on(Events.GuildMemberUpdate, (oldMember, newMember) => {
console.log(`�� Member Updated`);
console.log(`👤 User: ${newMember.user.tag}`);
// Check if nickname changed
if (oldMember.nickname !== newMember.nickname) {
console.log(`� Nickname: "${oldMember.nickname}" → "${newMember.nickname}"`);
}
// Check if roles changed
const addedRoles = newMember.roles.cache.filter(
role => !oldMember.roles.cache.has(role.id)
);
const removedRoles = oldMember.roles.cache.filter(
role => !newMember.roles.cache.has(role.id)
);
if (addedRoles.size > 0) {
console.log(`✅ Roles Added: ${addedRoles.map(r => r.name).join(', ')}`);
}
if (removedRoles.size > 0) {
console.log(`� Roles Removed: ${removedRoles.map(r => r.name).join(', ')}`);
}
// Check if muted
if (oldMember.communicationDisabledUntil !== newMember.communicationDisabledUntil) {
console.log(`🔇 Mute Status: ${newMember.communicationDisabledUntil ? 'Muted' : 'Unmuted'}`);
}
});Emitted whenever a member becomes available in a large guild.
// Triggered when a member's data becomes available
client.on(Events.GuildMemberAvailable, member => {
console.log(`✅ Member Data Available`);
console.log(`👤 User: ${member.user.tag}`);
console.log(`�� Guild: ${member.guild.name}`);
});Emitted whenever a chunk of guild members is received (all members from the same guild).
// Triggered when a batch of members is fetched
client.on(Events.GuildMembersChunk, (members, guild, data) => {
console.log(`📦 Members Chunk Received`);
console.log(`�� Guild: ${guild.name}`);
console.log(`👥 Members in chunk: ${members.size}`);
console.log(`📊 Chunk Index: ${data.index} / ${data.count}`);
// Process all members in this chunk
members.forEach(member => {
// Do something with each member
});
});Emitted whenever a guild scheduled event is created.
// Triggered when a scheduled event is created
client.on(Events.GuildScheduledEventCreate, guildScheduledEvent => {
console.log(`✨ Scheduled Event Created`);
console.log(`📅 Event: ${guildScheduledEvent.name}`);
console.log(`�� Guild: ${guildScheduledEvent.guild?.name}`);
console.log(`� Scheduled For: ${guildScheduledEvent.scheduledStartAt}`);
console.log(`� Description: ${guildScheduledEvent.description}`);
console.log(`🎯 Type: ${guildScheduledEvent.entityType}`);
});Emitted whenever a guild scheduled event is deleted.
// Triggered when a scheduled event is deleted
client.on(Events.GuildScheduledEventDelete, guildScheduledEvent => {
console.log(`🗑� Scheduled Event Deleted`);
console.log(`📅 Event: ${guildScheduledEvent.name}`);
console.log(`�� Guild: ${guildScheduledEvent.guild?.name}`);
});Emitted whenever a guild scheduled event is updated.
// Triggered when a scheduled event is modified
client.on(Events.GuildScheduledEventUpdate, (oldEvent, newEvent) => {
console.log(`�� Scheduled Event Updated`);
console.log(`📅 Event: ${newEvent.name}`);
if (oldEvent?.name !== newEvent.name) {
console.log(`� Name: "${oldEvent?.name}" → "${newEvent.name}"`);
}
if (oldEvent?.description !== newEvent.description) {
console.log(`📋 Description: "${oldEvent?.description}" → "${newEvent.description}"`);
}
if (oldEvent?.scheduledStartAt !== newEvent.scheduledStartAt) {
console.log(`� Start Time: ${oldEvent?.scheduledStartAt} → ${newEvent.scheduledStartAt}`);
}
});Emitted whenever a user subscribes to a guild scheduled event.
// Triggered when a user RSVP'd 'interested' to an event
client.on(Events.GuildScheduledEventUserAdd, (guildScheduledEvent, user) => {
console.log(`� User Interested in Event`);
console.log(`📅 Event: ${guildScheduledEvent.name}`);
console.log(`👤 User: ${user.tag}`);
});Emitted whenever a user unsubscribes from a guild scheduled event.
// Triggered when a user cancels interest in an event
client.on(Events.GuildScheduledEventUserRemove, (guildScheduledEvent, user) => {
console.log(`👎 User Cancelled Event Interest`);
console.log(`📅 Event: ${guildScheduledEvent.name}`);
console.log(`👤 User: ${user.tag}`);
});Emitted whenever a guild soundboard sound is created.
// Triggered when a soundboard sound is created
client.on(Events.GuildSoundboardSoundCreate, soundboardSound => {
console.log(`🔊 Soundboard Sound Created`);
console.log(`🎵 Sound: ${soundboardSound.name}`);
console.log(`�� Guild: ${soundboardSound.guild?.name}`);
console.log(`🎯 Volume: ${soundboardSound.volume}`);
});Emitted whenever a soundboard sound is deleted from a guild.
// Triggered when a soundboard sound is deleted
client.on(Events.GuildSoundboardSoundDelete, soundboardSound => {
console.log(`🗑� Soundboard Sound Deleted`);
console.log(`🎵 Sound: ${soundboardSound.name}`);
console.log(`�� Guild: ${soundboardSound.guild?.name}`);
});Emitted whenever a soundboard sound is updated.
// Triggered when a soundboard sound is modified
client.on(Events.GuildSoundboardSoundUpdate, (oldSound, newSound) => {
console.log(`�� Soundboard Sound Updated`);
console.log(`🎵 Sound: ${newSound.name}`);
if (oldSound?.name !== newSound.name) {
console.log(`� Name: "${oldSound?.name}" → "${newSound.name}"`);
}
if (oldSound?.volume !== newSound.volume) {
console.log(`🔊 Volume: ${oldSound?.volume} → ${newSound.volume}`);
}
});Emitted whenever multiple soundboard sounds are updated at once.
// Triggered when multiple soundboard sounds are updated
client.on(Events.GuildSoundboardSoundsUpdate, (soundboardSounds, guild) => {
console.log(`🔊 Soundboard Sounds Batch Updated`);
console.log(`�� Guild: ${guild.name}`);
console.log(`📊 Total Sounds: ${soundboardSounds.size}`);
soundboardSounds.forEach(sound => {
console.log(` - ${sound.name}`);
});
});Emitted when any interaction is created (slash commands, buttons, select menus, modals, etc.).
// Triggered when user interacts with bot (slash command, button, select menu, etc.)
client.on(Events.InteractionCreate, async interaction => {
// Handle slash commands
if (interaction.isChatInputCommand()) {
const { commandName } = interaction;
if (commandName === 'ping') {
await interaction.reply('Pong! �');
} else if (commandName === 'user') {
const user = interaction.options.getUser('user');
await interaction.reply(`You selected: ${user.tag}`);
}
}
// Handle button clicks
if (interaction.isButton()) {
const { customId } = interaction;
if (customId === 'accept_rules') {
await interaction.reply('✅ You accepted the rules!');
} else if (customId === 'decline_rules') {
await interaction.reply('� You declined the rules.');
}
}
// Handle select menus
if (interaction.isStringSelectMenu()) {
const selected = interaction.values;
await interaction.reply(`You selected: ${selected.join(', ')}`);
}
// Handle modals (form submissions)
if (interaction.isModalSubmit()) {
const email = interaction.fields.getTextInputValue('email_input');
await interaction.reply(`Your email: ${email}`);
}
// Handle autocomplete
if (interaction.isAutocomplete()) {
const focusedValue = interaction.options.getFocused();
const choices = ['Apple', 'Apricot', 'Avocado'];
const filtered = choices.filter(choice =>
choice.startsWith(focusedValue)
);
await interaction.respond(filtered.map(choice => ({ name: choice, value: choice })));
}
});Emitted when an invite is created. This event requires MANAGE_GUILD or MANAGE_CHANNELS permissions.
// Triggered when an invite is created
client.on(Events.InviteCreate, invite => {
console.log(`✨ Invite Created`);
console.log(`🔗 Invite Code: ${invite.code}`);
console.log(`#�⃣ Channel: ${invite.channel?.name || 'Unknown'}`);
console.log(`👤 Created By: ${invite.inviter?.tag || 'Unknown'}`);
console.log(`� Expires: ${invite.expiresAt || 'Never'}`);
console.log(`✅ Uses: ${invite.uses}/${invite.maxUses || 'Unlimited'}`);
});Emitted when an invite is deleted. This event requires MANAGE_GUILD or MANAGE_CHANNELS permissions.
// Triggered when an invite is deleted or expires
client.on(Events.InviteDelete, invite => {
console.log(`🗑� Invite Deleted`);
console.log(`🔗 Invite Code: ${invite.code}`);
console.log(`#�⃣ Channel: ${invite.channel?.name || 'Unknown'}`);
});Emitted whenever a message is created.
// Triggered when a message is sent
client.on(Events.MessageCreate, async message => {
// Ignore bot messages
if (message.author.bot) return;
console.log(`💬 Message Created`);
console.log(`👤 Author: ${message.author.tag}`);
console.log(`#�⃣ Channel: ${message.channel.name}`);
console.log(`� Content: ${message.content}`);
// Respond to mentions
if (message.mentions.has(client.user)) {
await message.reply('👋 Hello! How can I help you?');
}
// Simple prefix commands
if (message.content.startsWith('!')) {
const args = message.content.slice(1).split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'ping') {
await message.reply('� Pong!');
} else if (command === 'hello') {
await message.reply(`👋 Hello, ${message.author}!`);
} else if (command === 'user') {
await message.reply(`📊 Your account was created on ${message.author.createdAt}`);
}
}
// Respond to specific keywords
if (message.content.toLowerCase().includes('hello')) {
await message.reply('👋 Hello there!');
}
});Emitted whenever a message is deleted.
// Triggered when a message is deleted
client.on(Events.MessageDelete, message => {
console.log(`🗑� Message Deleted`);
console.log(`👤 Author: ${message.author?.tag || 'Unknown'}`);
console.log(`#�⃣ Channel: ${message.channel?.name || 'Unknown'}`);
console.log(`� Content: ${message.content || 'No content'}`);
// Log deleted messages to an audit channel
const auditChannel = message.guild?.channels.cache.find(
ch => ch.name === 'deleted-messages' && ch.isTextBased()
);
if (auditChannel) {
auditChannel.send(
`🗑� Message deleted: ${message.author?.tag} in ${message.channel}: "${message.content}"`
).catch(console.error);
}
});Emitted whenever messages are deleted in bulk.
// Triggered when multiple messages are deleted at once
client.on(Events.MessageDeleteBulk, (messages, channel) => {
console.log(`🗑� Bulk Message Deletion`);
console.log(`#�⃣ Channel: ${channel.name}`);
console.log(`� Messages Deleted: ${messages.size}`);
// Log bulk deletion
const auditChannel = messages.first()?.guild?.channels.cache.find(
ch => ch.name === 'audit-logs' && ch.isTextBased()
);
if (auditChannel) {
auditChannel.send(
`🗑� ${messages.size} messages were deleted in ${channel}`
).catch(console.error);
}
});Emitted whenever a message is updated (edited).
// Triggered when a message is edited
client.on(Events.MessageUpdate, (oldMessage, newMessage) => {
console.log(`�� Message Updated`);
console.log(`👤 Author: ${newMessage.author?.tag || 'Unknown'}`);
console.log(`#�⃣ Channel: ${newMessage.channel?.name || 'Unknown'}`);
if (oldMessage.content !== newMessage.content) {
console.log(`� Old Content: ${oldMessage.content}`);
console.log(`� New Content: ${newMessage.content}`);
// You could log message edits for moderation purposes
}
});Emitted whenever a user votes on a poll in a message.
// Triggered when a user votes on a poll
client.on(Events.MessagePollVoteAdd, (pollAnswer, userId) => {
console.log(`🗳� Poll Vote Added`);
console.log(`👤 User: ${userId}`);
console.log(`📊 Answer: ${pollAnswer.text}`);
});Emitted whenever a user removes their vote from a poll in a message.
// Triggered when a user removes a poll vote
client.on(Events.MessagePollVoteRemove, (pollAnswer, userId) => {
console.log(`🗳� Poll Vote Removed`);
console.log(`👤 User: ${userId}`);
console.log(`📊 Answer: ${pollAnswer.text}`);
});Emitted whenever a reaction is added to a message.
// Triggered when a user reacts to a message
client.on(Events.MessageReactionAdd, async (reaction, user) => {
// Ignore bot reactions
if (user.bot) return;
console.log(`😀 Reaction Added`);
console.log(`👤 User: ${user.tag}`);
console.log(`😊 Emoji: ${reaction.emoji.name || reaction.emoji.id}`);
console.log(`💬 Message: ${reaction.message.content.substring(0, 50)}`);
// Fetch full message if partial
if (reaction.message.partial) {
try {
await reaction.message.fetch();
} catch (error) {
console.error('Failed to fetch message:', error);
return;
}
}
// Role reaction example: React with ✅ to join role
if (reaction.emoji.name === '✅') {
const role = reaction.message.guild?.roles.cache.find(
r => r.name === 'Approved'
);
if (role) {
await reaction.message.member?.roles.add(role).catch(console.error);
}
}
});Emitted whenever a reaction is removed from a message.
// Triggered when a user removes a reaction
client.on(Events.MessageReactionRemove, async (reaction, user) => {
if (user.bot) return;
console.log(`😢 Reaction Removed`);
console.log(`👤 User: ${user.tag}`);
console.log(`😔 Emoji: ${reaction.emoji.name || reaction.emoji.id}`);
// Role reaction example: React to remove role
if (reaction.emoji.name === '✅') {
const role = reaction.message.guild?.roles.cache.find(
r => r.name === 'Approved'
);
if (role) {
await reaction.message.member?.roles.remove(role).catch(console.error);
}
}
});Emitted whenever all reactions are removed from a message.
// Triggered when all reactions are removed from a message
client.on(Events.MessageReactionRemoveAll, (message, reactions) => {
console.log(`💔 All Reactions Removed`);
console.log(`💬 Message: ${message.content.substring(0, 50)}`);
console.log(`😔 Reactions Removed: ${reactions.size}`);
});Emitted when a bot removes an emoji reaction from a cached message.
// Triggered when a specific emoji is removed from a message
client.on(Events.MessageReactionRemoveEmoji, reaction => {
console.log(`😶 Emoji Reaction Removed`);
console.log(`😔 Emoji: ${reaction.emoji.name || reaction.emoji.id}`);
console.log(`💬 Message: ${reaction.message.content.substring(0, 50)}`);
});Emitted whenever a guild member's presence changes (status, activity, device status, etc.).
// Triggered when user's status/activity changes
client.on(Events.PresenceUpdate, (oldPresence, newPresence) => {
console.log(`🟢 Presence Updated`);
console.log(`👤 User: ${newPresence.user?.tag || 'Unknown'}`);
// Check status change
if (oldPresence?.status !== newPresence.status) {
console.log(`📊 Status: ${oldPresence?.status} → ${newPresence.status}`);
// Statuses: online, idle, dnd (do not disturb), offline
}
// Check activity change
if (oldPresence?.activities !== newPresence.activities) {
console.log(`🎮 Activity Changed`);
newPresence.activities.forEach(activity => {
console.log(` - ${activity.name}: ${activity.details || 'No details'}`);
});
}
});Emitted whenever a user's details are changed (username, avatar, etc.).
// Triggered when user profile changes
client.on(Events.UserUpdate, (oldUser, newUser) => {
console.log(`�� User Profile Updated`);
if (oldUser.username !== newUser.username) {
console.log(`� Username: ${oldUser.username} → ${newUser.username}`);
}
if (oldUser.avatar !== newUser.avatar) {
console.log(`🖼� Avatar Changed`);
}
if (oldUser.discriminator !== newUser.discriminator) {
console.log(`�� Discriminator: ${oldUser.discriminator} → ${newUser.discriminator}`);
}
});Emitted whenever a role is created in a guild.
// Triggered when a new role is created
client.on(Events.RoleCreate, role => {
console.log(`✨ Role Created`);
console.log(`�� Role: ${role.name} (${role.id})`);
console.log(`�� Guild: ${role.guild.name}`);
console.log(`🎨 Color: ${role.color}`);
console.log(`� Permissions: ${role.permissions.toArray().join(', ')}`);
});Emitted whenever a guild role is deleted.
// Triggered when a role is deleted
client.on(Events.RoleDelete, role => {
console.log(`🗑� Role Deleted`);
console.log(`�� Role: ${role.name}`);
console.log(`�� Guild: ${role.guild.name}`);
});Emitted whenever a guild role is updated (name, color, permissions, etc.).
// Triggered when role properties change
client.on(Events.RoleUpdate, (oldRole, newRole) => {
console.log(`�� Role Updated`);
console.log(`�� Role: ${newRole.name}`);
if (oldRole.name !== newRole.name) {
console.log(`� Name: "${oldRole.name}" → "${newRole.name}"`);
}
if (oldRole.color !== newRole.color) {
console.log(`🎨 Color: #${oldRole.color.toString(16)} → #${newRole.color.toString(16)}`);
}
if (oldRole.permissions !== newRole.permissions) {
console.log(`� Permissions Updated`);
}
if (oldRole.hoist !== newRole.hoist) {
console.log(`📊 Hoist: ${oldRole.hoist} → ${newRole.hoist}`);
}
if (oldRole.mentionable !== newRole.mentionable) {
console.log(`@�⃣ Mentionable: ${oldRole.mentionable} → ${newRole.mentionable}`);
}
});Emitted when a shard (connection to Discord) turns ready.
// Triggered when a shard is ready (for sharded bots)
client.on(Events.ShardReady, (shardId, unavailableGuilds) => {
console.log(`✅ Shard Ready`);
console.log(`🔢 Shard ID: ${shardId}`);
if (unavailableGuilds) {
console.log(`⚠� Unavailable Guilds: ${unavailableGuilds.size}`);
}
});Emitted when a shard's WebSocket disconnects and will no longer reconnect.
// Triggered when a shard disconnects
client.on(Events.ShardDisconnect, (event, shardId) => {
console.error(`📵 Shard Disconnected`);
console.error(`🔢 Shard ID: ${shardId}`);
console.error(`🔌 Close Code: ${event.code}`);
console.error(`� Reason: ${event.reason}`);
});Emitted whenever a shard's WebSocket encounters a connection error.
// Triggered when a shard encounters an error
client.on(Events.ShardError, (error, shardId) => {
console.error(`⚠� Shard Error`);
console.error(`🔢 Shard ID: ${shardId}`);
console.error(`� Error: ${error.message}`);
});Emitted when a shard is attempting to reconnect or re-identify.
// Triggered when a shard is reconnecting
client.on(Events.ShardReconnecting, shardId => {
console.log(`🔄 Shard Reconnecting`);
console.log(`🔢 Shard ID: ${shardId}`);
});Emitted when a shard resumes successfully.
// Triggered when a shard successfully resumes
client.on(Events.ShardResume, (shardId, replayedEvents) => {
console.log(`✅ Shard Resumed`);
console.log(`🔢 Shard ID: ${shardId}`);
console.log(`📊 Replayed Events: ${replayedEvents}`);
});Emitted whenever a stage instance (live stage) is created.
// Triggered when a stage event starts
client.on(Events.StageInstanceCreate, stageInstance => {
console.log(`✨ Stage Instance Created`);
console.log(`🎤 Topic: ${stageInstance.topic}`);
console.log(`#�⃣ Channel: ${stageInstance.channel?.name}`);
console.log(`👥 Privacy: ${stageInstance.privacyLevel}`);
});Emitted whenever a stage instance is deleted (stage ended).
// Triggered when a stage event ends
client.on(Events.StageInstanceDelete, stageInstance => {
console.log(`🗑� Stage Instance Ended`);
console.log(`🎤 Topic: ${stageInstance.topic}`);
console.log(`#�⃣ Channel: ${stageInstance.channel?.name}`);
});Emitted whenever a stage instance is updated (topic or privacy level change).
// Triggered when stage details are modified
client.on(Events.StageInstanceUpdate, (oldInstance, newInstance) => {
console.log(`�� Stage Instance Updated`);
console.log(`🎤 Topic: ${newInstance.topic}`);
if (oldInstance?.topic !== newInstance.topic) {
console.log(`� Topic: "${oldInstance?.topic}" → "${newInstance.topic}"`);
}
if (oldInstance?.privacyLevel !== newInstance.privacyLevel) {
console.log(`🔒 Privacy: ${oldInstance?.privacyLevel} → ${newInstance.privacyLevel}`);
}
});Emitted whenever a custom sticker is created in a guild.
// Triggered when a sticker is created
client.on(Events.StickerCreate, sticker => {
console.log(`✨ Sticker Created`);
console.log(`🖼� Sticker: ${sticker.name}`);
console.log(`�� Guild: ${sticker.guild?.name}`);
console.log(`�� Tags: ${sticker.tags || 'None'}`);
console.log(`👤 Created By: ${sticker.user?.tag || 'Unknown'}`);
});Emitted whenever a custom sticker is deleted in a guild.
// Triggered when a sticker is deleted
client.on(Events.StickerDelete, sticker => {
console.log(`🗑� Sticker Deleted`);
console.log(`🖼� Sticker: ${sticker.name}`);
console.log(`�� Guild: ${sticker.guild?.name}`);
});Emitted whenever a custom sticker is updated in a guild.
// Triggered when sticker details change
client.on(Events.StickerUpdate, (oldSticker, newSticker) => {
console.log(`�� Sticker Updated`);
console.log(`🖼� Sticker: ${newSticker.name}`);
if (oldSticker.name !== newSticker.name) {
console.log(`� Name: "${oldSticker.name}" → "${newSticker.name}"`);
}
if (oldSticker.tags !== newSticker.tags) {
console.log(`�� Tags: "${oldSticker.tags}" → "${newSticker.tags}"`);
}
});Emitted whenever a custom emoji is created in a guild.
// Triggered when an emoji is created
client.on(Events.EmojiCreate, emoji => {
console.log(`✨ Emoji Created`);
console.log(`😊 Emoji: ${emoji.name}`);
console.log(`�� Guild: ${emoji.guild.name}`);
console.log(`🔗 URL: ${emoji.url}`);
console.log(`👤 Created By: ${emoji.author?.tag || 'Unknown'}`);
});Emitted whenever a custom emoji is deleted in a guild.
// Triggered when an emoji is deleted
client.on(Events.EmojiDelete, emoji => {
console.log(`🗑� Emoji Deleted`);
console.log(`😊 Emoji: ${emoji.name}`);
console.log(`�� Guild: ${emoji.guild.name}`);
});Emitted whenever a custom emoji is updated in a guild.
// Triggered when emoji details change
client.on(Events.EmojiUpdate, (oldEmoji, newEmoji) => {
console.log(`�� Emoji Updated`);
console.log(`😊 Emoji: ${newEmoji.name}`);
if (oldEmoji.name !== newEmoji.name) {
console.log(`� Name: "${oldEmoji.name}" → "${newEmoji.name}"`);
}
if (oldEmoji.roles !== newEmoji.roles) {
console.log(`� Role Restrictions Updated`);
}
});Emitted whenever a user starts a subscription to a guild.
// Triggered when a user subscribes to a guild
client.on(Events.SubscriptionCreate, subscription => {
console.log(`✨ Subscription Created`);
console.log(`👤 User: ${subscription.userId}`);
console.log(`�� Guild: ${subscription.guildId}`);
console.log(`🎯 Tier: ${subscription.tier}`);
});Emitted whenever a user cancels a subscription to a guild.
// Triggered when a user cancels subscription
client.on(Events.SubscriptionDelete, subscription => {
console.log(`🗑� Subscription Cancelled`);
console.log(`👤 User: ${subscription.userId}`);
console.log(`�� Guild: ${subscription.guildId}`);
});Emitted whenever a user updates their subscription tier.
// Triggered when subscription details change
client.on(Events.SubscriptionUpdate, (oldSubscription, newSubscription) => {
console.log(`�� Subscription Updated`);
console.log(`👤 User: ${newSubscription.userId}`);
if (oldSubscription?.tier !== newSubscription.tier) {
console.log(`⬆� Tier: ${oldSubscription?.tier} → ${newSubscription.tier}`);
}
});Emitted whenever a thread is created or when the client user is added to a thread.
// Triggered when a thread is created or bot is added to thread
client.on(Events.ThreadCreate, (thread, newlyCreated) => {
console.log(`✨ Thread Created/Joined`);
console.log(`💬 Thread: ${thread.name}`);
console.log(`#�⃣ Parent Channel: ${thread.parent?.name}`);
console.log(`🆕 Newly Created: ${newlyCreated}`);
if (newlyCreated) {
console.log(`� Archive Duration: ${thread.autoArchiveDuration} minutes`);
console.log(`👥 Thread Creator: ${thread.ownerId}`);
}
});Emitted whenever a thread is deleted.
// Triggered when a thread is deleted
client.on(Events.ThreadDelete, thread => {
console.log(`🗑� Thread Deleted`);
console.log(`💬 Thread: ${thread.name}`);
console.log(`#�⃣ Parent Channel: ${thread.parent?.name}`);
});Emitted whenever a thread is updated (name, archive state, lock state, etc.).
// Triggered when thread details change
client.on(Events.ThreadUpdate, (oldThread, newThread) => {
console.log(`�� Thread Updated`);
console.log(`💬 Thread: ${newThread.name}`);
if (oldThread.name !== newThread.name) {
console.log(`� Name: "${oldThread.name}" → "${newThread.name}"`);
}
if (oldThread.archived !== newThread.archived) {
console.log(`📦 Archived: ${oldThread.archived} → ${newThread.archived}`);
}
if (oldThread.locked !== newThread.locked) {
console.log(`🔒 Locked: ${oldThread.locked} → ${newThread.locked}`);
}
});Emitted whenever the client user gains access to a text channel with threads.
// Triggered when sync thread list
client.on(Events.ThreadListSync, (threads, guild) => {
console.log(`📋 Thread List Synced`);
console.log(`�� Guild: ${guild.name}`);
console.log(`💬 Total Threads: ${threads.size}`);
threads.forEach(thread => {
console.log(` - ${thread.name} (${thread.id})`);
});
});Emitted whenever members are added or removed from a thread.
// Triggered when thread members change
client.on(Events.ThreadMembersUpdate, (addedMembers, removedMembers, thread) => {
console.log(`👥 Thread Members Updated`);
console.log(`💬 Thread: ${thread.name}`);
if (addedMembers.size > 0) {
console.log(`✅ Members Added: ${addedMembers.size}`);
addedMembers.forEach(member => {
console.log(` - ${member.user?.tag || 'Unknown'}`);
});
}
if (removedMembers.size > 0) {
console.log(`� Members Removed: ${removedMembers.size}`);
removedMembers.forEach(member => {
console.log(` - ${member.user?.tag || 'Unknown'}`);
});
}
});Emitted whenever the client user's thread member object is updated.
// Triggered when bot's thread membership changes
client.on(Events.ThreadMemberUpdate, (oldMember, newMember) => {
console.log(`�� Bot Thread Member Updated`);
console.log(`💬 Thread: ${newMember.thread?.name}`);
if (oldMember.flags !== newMember.flags) {
console.log(`🚩 Flags Updated`);
}
});Emitted whenever a user changes voice state (joins/leaves voice channel, mutes/unmutes, etc.).
// Triggered when user's voice state changes
client.on(Events.VoiceStateUpdate, (oldState, newState) => {
console.log(`🎤 Voice State Updated`);
console.log(`👤 User: ${newState.member?.user.tag || 'Unknown'}`);
// User joined voice channel
if (!oldState.channel && newState.channel) {
console.log(`🟢 User Joined: ${newState.channel.name}`);
}
// User left voice channel
if (oldState.channel && !newState.channel) {
console.log(`🔴 User Left: ${oldState.channel.name}`);
}
// User switched channels
if (oldState.channel && newState.channel && oldState.channelId !== newState.channelId) {
console.log(`🔀 Channel Changed: ${oldState.channel.name} → ${newState.channel.name}`);
}
// User muted/unmuted
if (oldState.mute !== newState.mute) {
console.log(`🔇 Muted: ${newState.mute}`);
}
// User deafened/undeafened
if (oldState.deaf !== newState.deaf) {
console.log(`🔇 Deafened: ${newState.deaf}`);
}
// User self-muted/unmuted
if (oldState.selfMute !== newState.selfMute) {
console.log(`🔇 Self-Muted: ${newState.selfMute}`);
}
// User video on/off
if (oldState.streaming !== newState.streaming) {
console.log(`📹 Streaming: ${newState.streaming}`);
}
});Emitted whenever a user sends a voice channel effect (sound effects, animations).
// Triggered when a voice effect is sent
client.on(Events.VoiceChannelEffectSend, voiceChannelEffect => {
console.log(`✨ Voice Channel Effect Sent`);
console.log(`🎤 Channel: ${voiceChannelEffect.channel?.name}`);
console.log(`👤 User: ${voiceChannelEffect.user?.tag}`);
console.log(`🎵 Effect ID: ${voiceChannelEffect.emoji}`);
});Emitted for general debugging information. Very verbose.
// Debug information - useful for troubleshooting
client.on(Events.Debug, info => {
// Be careful: this fires A LOT
// Consider using a logger or filtering
if (info.includes('Something important')) {
console.log(`� Debug: ${info}`);
}
});Emitted for general warnings.
// Warnings that don't cause fatal errors
client.on(Events.Warn, info => {
console.warn(`⚠� Warning: ${info}`);
});Emitted when the client encounters an error. It's recommended to not use async functions as error event handlers.
// Handle uncaught errors
client.on(Events.Error, error => {
console.error(`� Client Error: ${error.message}`);
console.error(error.stack);
// You might want to send this to a logging service
// But don't use await or complex async operations here
});Emitted whenever the client sweeps the cache (removes old items to free memory).
// Triggered when cache is cleaned up
client.on(Events.CacheSweep, message => {
console.log(`🧹 Cache Sweep: ${message}`);
});Emitted when the client's session becomes invalidated. You should handle graceful shutdown here.
// Session is invalid - bot needs to reconnect
client.on(Events.Invalidated, () => {
console.error('� Bot session invalidated!');
console.error('The bot will now need to reconnect...');
// Perform cleanup before process exit
// Don't use this to restart - let process manager handle it
});Emitted whenever a channel has its webhooks changed.
// Triggered when webhooks are created/updated/deleted
client.on(Events.WebhooksUpdate, channel => {
console.log(`� Webhooks Updated`);
console.log(`#�⃣ Channel: ${channel.name}`);
// Fetch webhooks if you need details
channel.fetchWebhooks().then(webhooks => {
console.log(`📊 Total Webhooks: ${webhooks.size}`);
}).catch(console.error);
});Emitted whenever a user purchases a SKU (premium features).
// Triggered when a user buys premium features
client.on(Events.EntitlementCreate, entitlement => {
console.log(`💳 Entitlement Created`);
console.log(`👤 User: ${entitlement.userId}`);
console.log(`�� SKU: ${entitlement.skuId}`);
console.log(`📅 Expires: ${entitlement.expiresAt}`);
});Emitted whenever an entitlement is deleted (subscription expired, refund issued, etc.).
// Triggered when entitlement is removed
client.on(Events.EntitlementDelete, entitlement => {
console.log(`💔 Entitlement Deleted`);
console.log(`👤 User: ${entitlement.userId}`);
console.log(`�� SKU: ${entitlement.skuId}`);
});Emitted whenever an entitlement is updated.
// Triggered when entitlement details change
client.on(Events.EntitlementUpdate, (oldEntitlement, newEntitlement) => {
console.log(`�� Entitlement Updated`);
console.log(`👤 User: ${newEntitlement.userId}`);
if (oldEntitlement?.expiresAt !== newEntitlement.expiresAt) {
console.log(`📅 Expires: ${oldEntitlement?.expiresAt} → ${newEntitlement.expiresAt}`);
}
});Emitted whenever the soundboard sounds in a guild are updated.
// Triggered when multiple soundboard sounds are batch updated
client.on(Events.SoundboardSounds, (soundboardSounds, guild) => {
console.log(`🔊 Soundboard Sounds Batch Updated`);
console.log(`�� Guild: ${guild.name}`);
console.log(`📊 Total Sounds: ${soundboardSounds.size}`);
});Emitted whenever a user starts typing in a channel.
// Triggered when a user begins typing
client.on(Events.TypingStart, typing => {
console.log(`⌨� User Typing`);
console.log(`👤 User: ${typing.user?.tag || 'Unknown'}`);
console.log(`#�⃣ Channel: ${typing.channel?.name || 'Unknown'}`);
console.log(`� Timestamp: ${typing.createdTimestamp}`);
});Always use the Events enum instead of string literals for type safety:
// ✅ Good
client.on(Events.MessageCreate, message => { });
// � Avoid
client.on('messageCreate', message => { });Some events return partial objects. Always check and fetch if needed:
client.on(Events.MessageReactionAdd, async (reaction, user) => {
if (reaction.message.partial) {
try {
await reaction.message.fetch();
} catch (error) {
console.error('Failed to fetch:', error);
return;
}
}
// Now safe to use reaction.message
});Always verify your bot has the necessary permissions before performing actions:
client.on(Events.MessageCreate, async message => {
if (message.guild && !message.guild.members.me?.permissions.has(PermissionFlagsBits.SendMessages)) {
console.error('Bot lacks SendMessages permission');
return;
}
// Safe to send messages
});Request only the intents you need. Some intents are privileged and require verification:
const client = new Client({
intents: [
GatewayIntentBits.Guilds, // Always needed
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent, // Privileged Intent
GatewayIntentBits.GuildMembers, // Privileged Intent
GatewayIntentBits.GuildPresences, // Privileged Intent
],
});Always wrap event handlers in try-catch blocks:
client.on(Events.MessageCreate, async message => {
try {
// Your code here
} catch (error) {
console.error('Message handler error:', error);
// Handle gracefully
}
});Be mindful of Discord's rate limits when handling frequent events:
const cooldowns = new Map();
client.on(Events.MessageCreate, message => {
const cooldownKey = `${message.author.id}-command`;
if (cooldowns.has(cooldownKey)) {
console.log('On cooldown');
return;
}
// Execute command
// Set cooldown
cooldowns.set(cooldownKey, true);
setTimeout(() => cooldowns.delete(cooldownKey), 3000); // 3 second cooldown
});Never hardcode tokens or secrets:
// .env file
DISCORD_TOKEN=your_token_here
DATABASE_URL=your_db_url
// Load with dotenv
require('dotenv').config();
const token = process.env.DISCORD_TOKEN;Organize your events in separate files:
src/
├── events/
│ ├── messageCreate.js
│ ├── guildMemberAdd.js
│ └── ready.js
├── commands/
│ ├── fun/
│ └── moderation/
└── index.js
Keep detailed logs for troubleshooting:
const fs = require('fs');
function log(level, message) {
const timestamp = new Date().toISOString();
const logMessage = `[${timestamp}] ${level}: ${message}\n`;
console.log(logMessage);
fs.appendFileSync('bot.log', logMessage);
}
client.on(Events.ClientReady, () => {
log('INFO', `Bot ready as ${client.user.tag}`);
});
client.on(Events.Error, error => {
log('ERROR', error.message);
});Clean up resources and avoid memory leaks:
// Use .cache.clear() to free memory if needed
// But be careful - Discord.js relies on cache
// Better approach: implement cache sweeping
client.options.sweepers = {
messages: {
interval: 3600, // every hour
lifetime: 1800, // keep messages for 30 minutes
},
};These events are deprecated and should be replaced:
| Deprecated Event | Replacement |
|---|---|
ready |
clientReady |
webhookUpdate |
webhooksUpdate |
- Official Documentation: https://discord.js.org/docs/packages/discord.js/14.25.1
- Discord.js Guide: https://discordjs.guide/
- Discord API Documentation: https://discord.com/developers/docs/intro
- GitHub Repository: https://github.com/discordjs/discord.js
Found an error or want to add examples? Feel free to contribute to the Discord.js documentation!
This cheatsheet is provided as-is for educational purposes. Discord.js is licensed under Apache 2.0.
Last Updated: December 2025 | Discord.js Version: 14.25.1
Learn from this resource, but always apply it thoughtfully to your own projects!