Docs
Developer Documentation

Commands, Events & Clocks

Register Discord slash and prefix commands, listen to gateway events, and schedule background cron jobs.

Medusa features a unified interaction layer. Commands defined by modules can be executed either as modern Discord slash commands or legacy prefix text commands without duplicating implementation logic.

Discord Commands

Commands extend Commands from #medusa/modules and live in src/commands/:

modules/moderation/src/commands/kick.js
import { Commands } from "#medusa/modules";

export class KickCommand extends Commands {
    constructor(medusa, module) {
        super(medusa, module, {
            name: "kick",
            description: "Remove a member from the Discord server.",
            baselinePermission: "moderator",
            options: [
                {
                    type: "user",
                    name: "target",
                    description: "The server member to kick.",
                    required: true
                },
                {
                    type: "string",
                    name: "reason",
                    description: "Reason for the kick.",
                    required: false
                }
            ]
        });
    }

    async run(context) {
        const target = context.options.getUser("target");
        const reason = context.options.getString("reason") || "No reason provided.";

        const handler = this.medusa.modules.handlers.get(this.module, "moderation");
        await handler.kick(context.guild, target, context.member, reason);

        return context.reply({
            embeds: [
                this.medusa.embeds.success({
                    description: `Successfully kicked **${target.tag}**.`
                })
            ]
        });
    }
}

Friendly Option Types

Medusa uses friendly string types for application command options rather than raw Discord API integer enums:

  • "string"
  • "integer"
  • "number"
  • "boolean"
  • "user"
  • "channel"
  • "role"
  • "mentionable"
  • "attachment"
  • "subcommand"
  • "subcommandGroup"

Gateway Events

Listen to Discord gateway events by creating classes in src/events/ that extend Events:

modules/management/src/events/guildMemberAdd.js
import { Events } from "#medusa/modules";

export class GuildMemberAddEvent extends Events {
    constructor(medusa, module) {
        super(medusa, module, {
            name: "guildMemberAdd"
        });
    }

    async handle(member) {
        const greetings = this.medusa.modules.handlers.get(this.module, "greetings");
        if (greetings) {
            await greetings.welcome(member);
        }
    }
}
  • name: The Discord.js event identifier (e.g. "guildMemberAdd", "messageCreate", "voiceStateUpdate").
  • handle(...args): The callback executed when the event triggers.

Scheduled Clocks (Cron Jobs)

Modules execute recurring background tasks by creating classes in src/clocks/ that extend Clocks:

modules/alerts/src/clocks/poll.js
import { Clocks } from "#medusa/modules";

export class StreamPollClock extends Clocks {
    constructor(medusa, module) {
        super(medusa, module, {
            name: "stream-poll",
            schedule: "*/2 * * * *"
        });
    }

    async run() {
        const alerts = this.medusa.modules.handlers.get(this.module, "alerts");
        if (alerts) {
            await alerts.pollAllStreams();
        }
    }
}
  • schedule: A standard 5-part cron pattern (e.g. "*/2 * * * *" for every 2 minutes, "0 * * * *" for every hour).
  • run(): The method executed on each cron interval.

On this page