Skip to main content

Discord Slash Commands

When a bot module declares "discord" in its platforms array, its commands are automatically registered as Discord slash commands. This page explains the mapping, discord_options, and the registration lifecycle.

How it works

Extension developers declare commands once in lumio.config.json. Lumio handles the platform-specific dispatch:

PlatformUser typesMatching method
Twitch!points 100IRC prefix match
YouTube!points 100Chat prefix match
Kick!points 100Chat prefix match
Trovo!points 100Chat prefix match
Discord/points amount:100Slash command interaction

Your handler code is identical for all platforms. The args array is populated the same way regardless of where the command originated:

  • Prefix command !points 100 produces args: ["100"]
  • Discord slash command /points amount:100 produces args: ["100"] (positional from option order)

Registration flow

When an extension with Discord support is installed on an account that has a Discord connection:

  1. The API reads the extension manifest commands
  2. The API registers Discord slash commands via the Discord API (POST /applications/\{app_id\}/guilds/\{guild_id\}/commands)
  3. The Discord bot receives interactions via the Discord Gateway
  4. The bot dispatches to the Worker using the same sync HTTP path as prefix commands

Discord may take up to 1 hour to propagate guild-level command changes.

Adding discord_options

By default, commands are registered as simple slash commands with no options. To add typed parameters, use the discord_options field:

{
"triggers": {
"commands": [
{
"name": "points",
"description": "Show a user's points balance",
"cooldown_global": 5,
"min_role": "everyone",
"discord_options": [
{
"name": "user",
"type": "user",
"description": "User to check",
"required": false
}
]
},
{
"name": "give",
"description": "Give points to another user",
"cooldown_global": 10,
"min_role": "moderator",
"discord_options": [
{
"name": "user",
"type": "user",
"description": "Recipient",
"required": true
},
{
"name": "amount",
"type": "integer",
"description": "Points to give",
"required": true
}
]
}
]
}
}

Option types

TypeDiscord typeDescription
"string"STRINGText input
"integer"INTEGERWhole number
"boolean"BOOLEANTrue/false toggle
"user"USERDiscord user mention picker
"channel"CHANNELChannel picker
"role"ROLERole picker

Non-Discord platforms ignore the discord_options field entirely.

Args mapping

Discord options are mapped to the args array by position (order of declaration):

{
"discord_options": [
{ "name": "user", "type": "user", "required": true },
{ "name": "amount", "type": "integer", "required": true }
]
}

When a user runs /give user:@jane amount:50, the handler receives args: ["jane_user_id", "50"] — matching the declaration order.

For prefix platforms, !give @jane 50 produces the same args: ["@jane", "50"].

Handling Discord-specific behavior

Your handler can check ctx.user.platform to detect which platform triggered the command:

import { command } from "@zaflun/lumio-sdk/server";

export const points = command("points", async (ctx, args) => {
const targetUser = args[0] ?? ctx.user.id;
const points = await ctx.db.get("user_points", targetUser);

if (ctx.user.platform === "discord") {
// Discord supports richer formatting
return { reply: `**${ctx.user.displayName}** has **${points?.balance ?? 0}** points` };
}

return { reply: `${ctx.user.displayName} has ${points?.balance ?? 0} points` };
});

Sync on update

When you publish a new version that changes commands:

  1. Old Discord slash commands are removed
  2. New commands are registered with the Discord API
  3. Discord propagates changes (up to 1 hour for guild commands)

During the propagation window, users may see stale commands in the Discord autocomplete. This is a Discord API limitation.

Discord-only triggers

Keywords and patterns work in Discord the same as other platforms — they match against message content in text channels. Events use Discord-specific event types if available.

Timers fire to Discord channels the same way they fire to other platforms.