Event Listeners
To hook onto any background actions happening within your bot—such as message creation (messageCreate), voice channel state updates (voiceStateUpdate), or interaction handling (interactionCreate)—you utilize Disapp's robust Event module.
Disapp seamlessly catches the Event classes you construct, registers them, and passes them along to their corresponding Discord API hook methods.
Constructing an Event
To create an Event, you begin by structuring your module using the Event class originating from the core package.
Every file dropped under the events/ subdirectory is scanned by the DisappClient upon initialization.
import { Event, DisappClient } from "@disapp/core";
import { Events, PresenceUpdateStatus, ActivityType } from "discord.js";
export default class ReadyEvent extends Event {
constructor() {
super({
name: Events.ClientReady,
once: true,
execute: async () => {},
});
}
async execute(client: DisappClient) {
client.logger.info(`🔥 Successfully logged in as: ${client.user?.tag}`);
client.user?.setPresence({
activities: [
{ name: "Running Disapp Core!", type: ActivityType.Playing },
],
status: PresenceUpdateStatus.Online,
});
}
}
Event Types
Once vs On
- once: true - Event triggers only once (e.g.,
readyevent) - once: false - Event triggers every time (e.g.,
messageCreateevent)
export default class MessageCreateEvent extends Event {
constructor() {
super({
name: Events.MessageCreate,
once: false,
execute: async () => {},
});
}
async execute(message: Message) {
if (message.author.bot) return;
console.log(`Message from ${message.author.tag}: ${message.content}`);
}
}
Common Events
Ready Event
import { Event } from "@disapp/core";
import { Events } from "discord.js";
export default class ReadyEvent extends Event {
constructor() {
super({
name: Events.ClientReady,
once: true,
execute: async () => {},
});
}
async execute(client: any) {
console.log(`Logged in as ${client.user.tag}`);
}
}
Message Create Event
import { Event } from "@disapp/core";
import { Events, Message } from "discord.js";
export default class MessageCreateEvent extends Event {
constructor() {
super({
name: Events.MessageCreate,
once: false,
execute: async () => {},
});
}
async execute(message: Message) {
if (message.author.bot) return;
if (message.content.toLowerCase() === "hello") {
await message.reply("Hello! 👋");
}
}
}
Interaction Create Event
import { Event } from "@disapp/core";
import { Events, Interaction } from "discord.js";
export default class InteractionCreateEvent extends Event {
constructor() {
super({
name: Events.InteractionCreate,
once: false,
execute: async () => {},
});
}
async execute(interaction: Interaction) {
if (!interaction.isChatInputCommand()) return;
console.log(`Command used: ${interaction.commandName}`);
}
}
VoiceTracker Implementation
If you wish to measure tracking analytics on your Discord servers regarding voice channel activity, you can use the VoiceTracker in conjunction with the Repository ecosystem inside Disapp Core.
Voice State Update Event
import { Event, VoiceTracker } from "@disapp/core";
import { Events, VoiceState } from "discord.js";
export default class VoiceStateUpdateEvent extends Event {
constructor() {
super({
name: Events.VoiceStateUpdate,
once: false,
execute: async () => {},
});
}
async execute(oldState: VoiceState, newState: VoiceState) {
const voiceTracker = new VoiceTracker(oldState.client);
await voiceTracker.handleVoiceStateUpdate(oldState, newState);
}
}
Required Intents
For VoiceTracker to accurately record data, you must include GuildVoiceStates intent:
import { GatewayIntentBits } from "discord.js";
const client = new DisappClient({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates],
});
i18n (Multi-Language) in Events
You can leverage the power of i18n within your Events to determine dynamic user languages:
import { Event, I18nHelper } from "@disapp/core";
import { Events, Message } from "discord.js";
export default class MessageCreateEvent extends Event {
constructor() {
super({
name: Events.MessageCreate,
once: false,
execute: async () => {},
});
}
async execute(message: Message) {
if (message.author.bot) return;
const userId = message.author.id;
const greeting = I18nHelper.tUser(userId, "messages.greeting");
if (message.content.toLowerCase() === "hello") {
await message.reply(greeting);
}
}
}
Error Handling
Always wrap event logic in try-catch blocks:
async execute(message: Message) {
try {
if (message.author.bot) return;
// Your event logic here
} catch (error) {
console.error('Error in MessageCreate event:', error);
}
}
Best Practices
- Use once: true for one-time events - Like
readyevent - Check for bots - Always check
message.author.botin message events - Handle errors - Wrap logic in try-catch blocks
- Keep events focused - One event per file
- Use type guards - Check interaction types before processing
Learn More
- API Reference - Complete event API
- Examples - Event usage examples
- VoiceTracker - Voice tracking guide