Contents
1. アプリ作成と Bot トークン取得
Discord の公式開発者ポータルでアプリを登録し、Bot ユーザーとトークンを入手するのが最初のステップです。この段階で Gateway Intents を正しく設定しておかないと、メッセージ内容やサーバーメンバー情報にアクセスできません。
1‑1. Developer Portal でのアプリ作成手順
以下は2026 年 3 月時点の画面構成(公式ドキュメント https://discord.com/developers/docs/getting-started) に基づく手順です。
- ログイン → Discord の開発者ポータルにサインイン。
- New Application をクリックし、アプリ名を入力して Create。
- 左メニューの Bot タブへ移動し Add Bot → Yes, do it! と確認。
- 表示された TOKEN をコピーし、後述の
.envに保存する。
注意:トークンは一度だけ表示されます。再取得したい場合は「Reset Token」してください。ただし、既存コードがすべて無効になる点に留意しましょう。
1‑2. Gateway Intents(Privileged Intent)の設定
Discord API v10 では MESSAGE_CONTENT と SERVER_MEMBERS が Privileged に分類され、デフォルトで OFF です(公式リファレンス https://discord.com/developers/docs/topics/gateway#gateway-intents)。これらを有効にしないと以下のようなエラーが発生します。
Missing Access– メッセージ本文取得が不可Privileged Intent Required– サーバーメンバー情報が取得できず
設定手順
- Bot 設定ページ の下部にある Privileged Gateway Intents スイッチを ON にする。
- 必要なものだけ選択し、必ず Save Changes をクリック。
ベストプラクティス:機能実装前に最小限の Intent だけ有効化し、不要になったら即オフにします。これによりトークン漏洩時の被害範囲を最小化できます。
2. 開発環境の構築
Node.js と npm の最新版をインストールし、プロジェクト雛形と必要パッケージを整えます。この章では Docker 非依存 な純粋な Node 環境構築手順を示します。
2‑1. Node.js v20 と npm のインストール
| OS | 推奨インストール方法 | 補足 |
|---|---|---|
| macOS | Homebrew brew install node@20 |
LTS 版は 2023 年10月リリース(https://nodejs.org/ja/about/releases) |
| Windows | 公式サイトの MSI インストーラ | https://nodejs.org/en/download/ |
| Linux (Ubuntu) | curl -fsSL https://deb.nodesource.com/setup_20.x \| sudo -E bash - && sudo apt-get install -y nodejs |
NodeSource が提供する 20 系 LTS |
インストール後はバージョン確認:
|
1 2 3 |
node -v # v20.14.0(執筆時点) npm -v # 10.8.0 |
2‑2. discord.js v15 の導入とクライアント初期化
discord.js v15 は 2024 年 8 月にリリースされ、ESM(ECMAScript Modules) がデフォルトとなりました(公式 changelog https://github.com/discordjs/discord.js/releases/tag/v15.0.0)。以下の手順でプロジェクトを作成し、最小構成のクライアントコードを用意します。
|
1 2 3 4 5 6 7 |
# プロジェクト作成 mkdir my-discord-bot && cd my-discord-bot npm init -y # 必要パッケージインストール npm install discord.js@15 dotenv |
index.mjs(ESM 形式)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// index.mjs import { Client, GatewayIntentBits } from 'discord.js'; import 'dotenv/config'; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, // Privileged Intents GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers, ], }); export default client; |
ポイント:
dotenv/configをインポートするだけで.envの内容がprocess.envに自動展開されます。
3. シンプルボット実装:スラッシュコマンドとイベントハンドラ
Bot の基本的な動作は ready と interactionCreate イベントで管理します。本節では最小限の /ping コマンドを実装し、ローカル環境でのコマンド登録手順も併せて紹介します。
3‑1. スラッシュコマンドの一括登録
Discord の REST API(バージョン10)に対して 一度だけ コマンド情報を送信すれば、以降はリアルタイムでイベントとして受け取れます。以下スクリプトはプロジェクト初回実行時にだけ走らせる想定です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// register-commands.mjs import { REST, Routes } from 'discord.js'; import 'dotenv/config'; const commands = [ { name: 'ping', description: 'Bot の応答速度を測ります', }, ]; const rest = new REST({ version: '10' }).setToken(process.env.BOT_TOKEN); (async () => { try { console.log('▶ スラッシュコマンドの登録開始...'); await rest.put(Routes.applicationCommands(process.env.CLIENT_ID), { body: commands }); console.log('✅ コマンド登録完了'); } catch (err) { console.error('⚠ 登録失敗:', err); } })(); |
実行例:
node register-commands.mjs
3‑2. イベントハンドラと起動コード
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// index.mjs(続き) import client from './client.mjs'; import 'dotenv/config'; const { BOT_TOKEN } = process.env; // ready イベント client.once('ready', () => { console.log(`✅ Bot がログインしました → ${client.user.tag}`); }); // interactionCreate ハンドラ client.on('interactionCreate', async (interaction) => { if (!interaction.isChatInputCommand()) return; if (interaction.commandName === 'ping') { await interaction.reply('Pong! 🏓'); } }); // エラー捕捉(後述のローカルデバッグで共通利用) import './error-handling.mjs'; // 起動 client.login(BOT_TOKEN); |
4. ローカルテストとデバッグ
開発サイクルの早期段階でエラーハンドリングとログ出力を整備しておくと、クラッシュや予期せぬ挙動をすぐに検知できます。
4‑1. グローバル例外処理
|
1 2 3 4 5 6 7 8 9 |
// error-handling.mjs process.on('unhandledRejection', (reason) => { console.error('❗ 未処理の Promise 拒否:', reason); }); process.on('uncaughtException', (err) => { console.error('❗ 捕捉できなかった例外:', err); }); |
4‑2. Winston による構造化ロギング(任意)
|
1 2 |
npm install winston |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// logger.mjs import { createLogger, format, transports } from 'winston'; export const logger = createLogger({ level: 'info', format: format.combine( format.timestamp(), format.printf(({ timestamp, level, message }) => `${timestamp} [${level}] ${message}`) ), transports: [new transports.Console()], }); |
index.mjs の適所で logger.info(...) や logger.error(...) を呼び出すだけです。
メリット:本番環境では CloudWatch、Loggly 等の外部サービスへ転送し、アラート設定も容易になります。
5. デプロイと運用
Bot を常時稼働させるにはクラウドホスティングが必須です。2026 年現在、Heroku の無料枠は終了しているため、以下の3サービスが代表的な選択肢となります。
| サービス | 無料枠 | 永続ストレージ | 常時稼働(Always‑On) |
|---|---|---|---|
| Railway | 500 h/月 (1 vCPU) | 5 GB ボリューム(有料プランで拡張可) | 有料プランで always-on オプション利用可能 |
| Fly.io | 750 h/月 + 3 GB RAM | ボリュームは有料 | デフォルトで常駐コンテナが保持される(無料枠でも一定時間稼働) |
| Vercel | 100 GB 転送、125 kB/s 実行時間 | なし(サーバーレス) | 無料プランでは不可。Always‑On は有料 Enterprise プラン限定 |
5‑1. Railway デプロイ手順
-
リポジトリ連携
GitHub にコードをプッシュし、Railway のダッシュボードで「New Project」→「Deploy from GitHub」を選択。 -
Dockerfile(任意)
カスタム設定が必要な場合は以下をプロジェクトルートに配置。
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "index.mjs"]
-
環境変数設定
「Variables」タブでBOT_TOKEN、CLIENT_IDを追加。 -
デプロイ実行
「Deploy」ボタンをクリックすると自動ビルド・起動し、ログは UI から確認可能。
5‑2. Fly.io デプロイ手順
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 1. CLI インストール curl -L https://fly.io/install.sh | sh # 2. アプリ作成(対話形式) fly launch # Region, App Name 等を入力 # 3. シークレット登録 fly secrets set BOT_TOKEN=$BOT_TOKEN CLIENT_ID=$CLIENT_ID # 4. デプロイ(Dockerfile が自動検出される) fly deploy |
永続ボリュームが必要な場合は fly volumes create bot-data --size 1 とし、docker-compose.yml 等でマウント設定します。
5‑3. Vercel デプロイ手順と Always‑On の注意点
Vercel は サーバーレス関数 としてコードを実行するため、常駐プロセス(WebSocket 接続等)は保持できません。2026 年現在、無料枠では「Always‑On」機能は提供されず、有料プラン(Enterprise)でのみ 永続的に Node.js プロセスを稼働 させることが可能です。
デプロイ手順
|
1 2 3 4 5 |
npm i -g vercel # Vercel CLI インストール vercel init # Node.js テンプレートで初期化 # .env の代わりに Vercel Dashboard → Settings → Environment Variables に設定 vercel --prod # 本番デプロイ |
結論:無料プランでの常時稼働は不可能です。24/7 稼働が必須の場合は Railway(有料)か Fly.io の無料枠を利用することを推奨します。
5‑4. 永続化・自動復旧策
-
PM2(プロセスマネージャ)
bash
npm i -g pm2
pm2 start index.mjs --name discord-bot --interpreter node
pm2 save # 再起動時に自動復元 -
Docker コンテナ化(上記 Dockerfile を利用)
各ホスティングサービスは Docker イメージを直接デプロイできるため、コンテナ単位でのロールバックやスケーリングが容易です。
6. 安全な運用ベストプラクティスと規約遵守
Discord の利用規約は 最小権限 と ユーザーデータ保護 を厳格に求めています。違反すると Bot アカウントの停止やサーバー削除リスクがあります。本節では実践的な対策をまとめます。
6‑1. 権限最小化とトークン管理
| 項目 | 推奨手順 |
|---|---|
| Intents | 必要なものだけ有効化し、不要になったら即オフ。MESSAGE_CONTENT と SERVER_MEMBERS は本当に使用する機能があるか再確認。 |
| トークン保管 | .env + GitHub Secrets → CI/CD でのみ参照可能にし、リポジトリに平文を書かない。 |
| 権限付与 | Bot をサーバーへ招待する際は applications.commands と最低限のスコープだけを指定(例: bot, applications.commands)。 |
6‑2. 依存パッケージの定期更新と脆弱性対策
-
npm audit の実行
bash
npm install -g npm-check-updates # バージョン確認ツール
ncu -u # package.json を最新に更新
npm install # 依存関係を再インストール
npm audit fix --force # 脆弱性自動修正(必要に応じて手動対応) -
GitHub Dependabot の有効化
リポジトリ設定 →Settings > Security & analysisで「Dependabot alerts」と「Dependabot security updates」をオンにする。 -
CI パイプラインでの自動チェック(例: GitHub Actions)
yaml
name: Security Scan
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm audit --audit-level=high
6‑3. ログ監視と規約遵守
| 項目 | 実装例 |
|---|---|
| 構造化ログ | Winston → CloudWatch、Loggly 等へ転送し、error レベルでアラートを設定。 |
| スパム防止 | コマンドレートリミット(1 分間に 5 回まで)やメッセージ内容のフィルタリングを実装。 |
| データ保持ポリシー | ユーザー情報は必要最小限だけ保存し、90 日以上保持しない。削除要求があったら即レスポンス。 |
規約ポイント:Discord の開発者向け利用規約(https://discord.com/developers/docs/legal) では「自動化された大量メッセージ送信」や「個人情報の無断取得・保存」を明確に禁止しています。上記ベストプラクティスを守ることで、アカウント停止リスクを大幅に低減できます。
7. まとめ
- Developer Portal → アプリ作成 → Bot トークン取得 → 必要な Privileged Intent のみ有効化
- Node.js v20 + discord.js v15 環境で
dotenvを用いた安全な設定管理 - 最小構成の
/pingスラッシュコマンドとイベントハンドラで Bot 本体を実装 - ローカルテストは グローバル例外処理 + Winston で可視化し、デバッグ効率を向上
- デプロイは Railway / Fly.io(無料枠あり)か Vercel 有料プラン を選択。Vercel の無料プランでは常時稼働不可に注意
- 運用は 最小権限・トークン管理・依存パッケージ更新・ログ監視 を徹底し、Discord 規約を遵守
以上の手順とベストプラクティスを踏めば、2026 年現在でも安全かつ安定した Discord Bot の開発・運用が可能です。Happy coding!