本文へスキップ

2026年6月23日

Discordスラッシュコマンドを作る — Application Commandsの実装ガイド

CommunityDiscordEngineeringAI

スラッシュコマンドが「運営の動線」を変える

Discord Bot・APIで何ができるのかで触れたように、Discordの自動化の入口はメッセージ操作と双方向UIです。その中でもスラッシュコマンド(Application Commands)は、参加者が自然に使えるインターフェースを持つ最も重要な機能の一つです。

/help と打つだけでFAQが表示される。/report @ユーザー でモデレーターに通知が届く。/event を実行するとイベント一覧がボタン付きで表示される。こうした「コマンドで操作できる場」は、Botを入れるだけでは生まれません。設計して、実装して、サーバーに登録して初めて動くものです。

この記事では、スラッシュコマンドの仕組みと実装手順をTypeScriptのコード例とともに解説します。

スラッシュコマンドの仕組み

スラッシュコマンドはDiscordのApplication Commands APIで定義します。コマンドを実行すると、DiscordはBotにインタラクション(Interaction)を送ります。

ユーザーが /hello を実行
 → Discord がBot(またはWorkerのURL)にインタラクションを送信
 → BotがJSONで応答(返答メッセージ、Embed、ボタン等)
 → Discordがレスポンスを表示

Interactionsに応答する実装は2通りあります。

方式仕組み向く用途
Gateway(WebSocket)常時接続、全イベント受信リアクション監視・全発言処理
Interactions Endpoint(HTTP)HTTPリクエストで受け取るコマンド・ボタン・モーダル中心

スラッシュコマンドはHTTP方式(Interactions Endpoint)が使え、サーバーレスで動かせます。具体的な構成はCloudflareでDiscord Botをサーバーレスで動かすで解説しています。

コマンドの種類

Application Commandsには3種類あります。

種類説明
スラッシュコマンド(CHAT_INPUT)/コマンド名 で実行/help, /report
ユーザーコンテキストメニューユーザーを右クリックして実行「このユーザーを報告」
メッセージコンテキストメニューメッセージを右クリックして実行「このメッセージを要約」

最もよく使われるのはスラッシュコマンドです。本記事もこれを中心に扱います。

実装:discord.js v14 でコマンドを作る

前提パッケージ

npm install discord.js @discordjs/rest discord-api-types

ステップ1:コマンドを定義する

// src/commands/hello.ts
import { SlashCommandBuilder } from 'discord.js';

export const helloCommand = new SlashCommandBuilder()
  .setName('hello')
  .setDescription('Botが挨拶を返します')
  .addStringOption((option) =>
    option
      .setName('name')
      .setDescription('呼ぶ名前')
      .setRequired(false)
  );

SlashCommandBuilder で名前・説明・引数を定義します。引数には文字列(addStringOption)の他に、数値(addIntegerOption)、ユーザー指定(addUserOption)、真偽値(addBooleanOption)などが使えます。

ステップ2:コマンドを登録する

// scripts/register-commands.ts
import { REST, Routes } from 'discord.js';
import { helloCommand } from '../src/commands/hello';

const token = process.env.DISCORD_BOT_TOKEN!;
const clientId = process.env.DISCORD_CLIENT_ID!;
const guildId = process.env.DISCORD_GUILD_ID; // 開発時のみ

const rest = new REST({ version: '10' }).setToken(token);

const commands = [helloCommand.toJSON()];

async function main() {
  if (guildId) {
    // ギルドコマンド(即時反映・テスト用)
    await rest.put(
      Routes.applicationGuildCommands(clientId, guildId),
      { body: commands }
    );
    console.log('Guild commands registered.');
  } else {
    // グローバルコマンド(最大1時間後に反映・本番用)
    await rest.put(
      Routes.applicationCommands(clientId),
      { body: commands }
    );
    console.log('Global commands registered.');
  }
}

main();

開発中はギルドコマンドで即時確認し、本番デプロイ時にグローバル登録するのが一般的な運用です。

ステップ3:インタラクションに応答する

// src/index.ts
import { Client, GatewayIntentBits, Events, EmbedBuilder } from 'discord.js';

const client = new Client({
  intents: [GatewayIntentBits.Guilds],
});

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === 'hello') {
    const name = interaction.options.getString('name') ?? 'みなさん';

    const embed = new EmbedBuilder()
      .setColor(0x5865f2) // Discord Blurple
      .setTitle(`こんにちは、${name}!`)
      .setDescription('コミュニティへようこそ。何かあれば気軽に相談してください。')
      .setTimestamp();

    await interaction.reply({ embeds: [embed] });
  }
});

client.login(process.env.DISCORD_BOT_TOKEN);

interaction.reply() で即時応答します。処理が3秒以上かかる場合は await interaction.deferReply() で先に応答を保留し、処理完了後に interaction.editReply() で内容を更新します。

運営でよく使うコマンドパターン

パターン1:モデレーション通知

// /report @ユーザー [理由] でモデレーターチャンネルに転送
.setName('report')
.addUserOption(opt => opt.setName('user').setDescription('報告するユーザー').setRequired(true))
.addStringOption(opt => opt.setName('reason').setDescription('理由').setRequired(false))

参加者から通報を受け付け、モデレーターチャンネルにEmbedで転送するパターンです。

パターン2:FAQ応答

// /faq [キーワード] でよくある質問に答える
.setName('faq')
.addStringOption(opt =>
  opt.setName('topic')
    .setDescription('知りたいこと')
    .addChoices(
      { name: '参加方法', value: 'join' },
      { name: 'イベント', value: 'events' },
      { name: 'ルール', value: 'rules' }
    )
)

選択肢(addChoices)で入力補完付きのFAQを作れます。LLM連携で自由入力に対応させると更に強力です。

パターン3:ロール申請

// /role @ロール名 でセルフサービスのロール付与
.setName('role')
.addRoleOption(opt =>
  opt.setName('name').setDescription('希望するロール').setRequired(true)
)

許可ロールのリストと照合して、自己申告によるロール付与を自動化します。

バイブコーディングで実装する

上記のような構成を、AIコーディング(Claude等)に「こう動いてほしい」と伝えて実装させるのがバイブコーディングです。

効果的なプロンプトの例:

Discord BotのスラッシュコマンドをTypeScriptで作りたい。
コマンド名は /report
引数: user(ユーザー指定・必須)、reason(文字列・任意)
実行すると:
  - 実行者に「報告を受け付けました」とEphemeral(本人のみ見える)で返す
  - #moderators チャンネルにEmbedで通知する(報告者・対象・理由・時刻)

使用ライブラリ: discord.js v14
コマンド登録スクリプトとBot起動ファイルもセットで作ってください。

受け取ったコードには必ず確認すること:

  • 署名検証(Interactions Endpoint方式の場合)
  • エラーハンドリング(チャンネルが見つからない、権限不足など)
  • レート制限への配慮

コードの意味が分からない箇所は「この処理が必要な理由を説明して」と追加で聞きます。動く理由を理解してから本番環境に入れるのが安全な進め方です。

権限設計:誰がコマンドを使えるか

コマンドをサーバーに登録する際、defaultMemberPermissions で実行できる権限を制限できます。

new SlashCommandBuilder()
  .setName('ban')
  .setDescription('ユーザーをBANします')
  .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers) // BAN権限を持つ人のみ
  .addUserOption(opt =>
    opt.setName('user').setDescription('対象ユーザー').setRequired(true)
  )

サーバー管理者はDiscordの「サーバー設定 → 統合 → Botアプリ」からさらに細かく上書きできます。コマンド設計の段階で「誰が使うか」を想定し、適切な権限を設定してください。

まとめ

  • スラッシュコマンドはDiscord Application Commands APIに登録し、インタラクションで応答する仕組み
  • 開発中はギルドコマンド(即時反映)、本番はグローバルコマンドで運用する
  • 引数に型・選択肢・必須/任意を設定でき、入力補完が標準で使える
  • モデレーション通知・FAQ応答・ロール申請など、運営の定型業務を自動化できる
  • バイブコーディングでコマンド名・引数・挙動・ライブラリを明示して実装させると効率的
  • 権限設計(defaultMemberPermissions)で「誰が使えるか」をコード側で制御する

スラッシュコマンドをフルに活用すると、運営が手作業で捌いていた定型業務の多くがコマンドで完結します。次のステップはボタンやモーダルを組み合わせて、より複雑な対話フローを作ることです。


コミュニティ運営の自動化設計から実装の伴走支援をお探しの方は、六瀬のコミュニティ開発サービスもご覧ください。

関連記事

Contact · 六瀬合同会社

コミュニティの話を、続けませんか。

読みながら「自分のところはどうなんだろう」と思った瞬間があれば、その問いをそのまま送ってください。整理されていなくても、相談の入口を一緒に言葉にしていきます。

よくある質問

Q. スラッシュコマンドとプレフィックスコマンド(!help等)は何が違いますか?
A. スラッシュコマンドはDiscord公式のApplication Commandsとして登録するもので、入力補完・権限制御・型付き引数・ローカライズなどが標準で使えます。一方のプレフィックスコマンド(!help等)はBotがメッセージを受け取って文字列マッチするだけで、入力補完がなく、権限も細かく制御しにくいです。Discord公式はスラッシュコマンドへの移行を推奨しており、新規実装はスラッシュコマンドを選ぶのが現実的です。
Q. スラッシュコマンドの登録はどのくらい時間がかかりますか?
A. グローバルコマンド(全サーバーに反映)は最大1時間かかります。開発・テスト時はギルドコマンド(特定サーバーのみ)で登録すると即時反映されます。本番環境ではグローバル登録をデプロイパイプラインに組み込んで、コードの変更と同時にコマンドも更新されるようにするのが理想的です。
Q. バイブコーディングでスラッシュコマンドを作るとき、何を伝えればいいですか?
A. 「Discord BotのスラッシュコマンドをTypeScriptで作りたい。コマンド名は/report、引数はtextフィールド(文字列・必須)。実行するとEmbedで確認メッセージを返し、指定のチャンネルに転送する。discord.js v14を使う実装と、コマンド登録スクリプトも含めてください。」のように、コマンド名・引数の型と必須/任意・返答の形式・使用ライブラリを具体的に伝えると、精度の高いコードが出てきます。
Q. スラッシュコマンドで権限を制限する方法は?
A. Discord側で「デフォルトの権限(defaultMemberPermissions)」を設定することで、特定権限を持つメンバーのみがコマンドを実行できるよう制限できます。たとえばモデレーターのみが使える/banコマンドには、PermissionsBitField.Flags.BanMembersを設定します。サーバー管理者はDiscordの「統合」設定からコマンドごとにさらに細かく権限を上書きできます。