Contents
1. Discord Developer Portal で Bot を作成・トークン取得
Discord 側の設定が不十分だとメッセージ取得や送信ができません。まずは公式ポータルで Bot アプリケーション と トークン を安全に取得し、後続のコードから参照できるようにします。
1‑1. アプリケーション登録
以下の手順で新規アプリケーションを作成します。
- https://discord.com/developers/applications にアクセスしてログイン
- 「New Application」ボタン → 任意の名前を入力 → Create
- 左メニューの Bot を選択し Add Bot → Yes, do it!
1‑2. Bot ユーザーと権限設定
Bot がメッセージ内容にアクセスできるよう Intent とパーミッションを有効化します。
- Privileged Gateway Intents
MESSAGE_CONTENT(必須)SERVER MEMBERS(必要に応じて)- OAuth2 → URL Generator
- スコープ:
bot、applications.commands - パーミッション:
Send Messages、Read Message History、Manage Messages
生成された URL を開き、Bot を自分のサーバへ招待してください。
1‑3. トークン管理と .env 設定
トークンは 一度しか表示されません。漏洩防止のため、取得直後にローカル環境の .env ファイル に保存します。
|
1 2 |
DISCORD_TOKEN=YOUR_DISCORD_BOT_TOKEN |
重要ポイント
-.envは絶対にリポジトリへコミットしない。
- 同時に.gitignoreに.envを追加 して除外します(後述)。
2. Python 環境構築と必須パッケージのインストール
Python と仮想環境を正しくセットアップすれば、依存関係がプロジェクト単位に閉じ、デプロイ時のトラブルを大幅に減らせます。
2‑1. Python と仮想環境 (venv) の準備
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Python 3.12 がインストールされていることを確認 python3.12 --version # → Python 3.12.x # プロジェクトディレクトリ作成・移動 mkdir discord-ai-bot && cd discord-ai-bot # 仮想環境作成 python3.12 -m venv .venv # 仮想環境を有効化(Linux/macOS) source .venv/bin/activate # Windows の場合は .venv\Scripts\activate.bat を実行 |
仮想環境が有効になると、ターミナルの先頭に (.venv) が表示されます。
2‑2. 必要パッケージのインストール & requirements.txt の作成
|
1 2 3 4 5 6 |
# pip を最新化 pip install --upgrade pip # パッケージ一括インストール pip install "discord.py>=2.3" python-dotenv aiohttp openai |
インストールしたパッケージは requirements.txt に出力しておくと、デプロイ時に自動で再現できます。
|
1 2 3 |
# requirements.txt 生成 pip freeze > requirements.txt |
requirements.txt の例(抜粋):
|
1 2 3 4 5 |
discord.py>=2.3 python-dotenv aiohttp openai |
3. AI 応答機能の実装
ここでは Intent 有効化、基本ハンドラ、そして OpenAI API への非同期呼び出し を組み合わせて、!ai <質問> に対して GPT‑4o-mini が応答するロジックを構築します。
3‑1. Intent の有効化と基本ハンドラ
|
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 27 28 29 30 31 |
# bot.py import os, asyncio import discord from dotenv import load_dotenv load_dotenv() TOKEN = os.getenv("DISCORD_TOKEN") intents = discord.Intents.default() intents.message_content = True # メッセージ本文取得に必須 client = discord.Client(intents=intents) @client.event async def on_ready(): print(f"✅ Bot が起動しました: {client.user}") @client.event async def on_message(message): # 自己メッセージは無視(ループ防止) if message.author == client.user: return # コマンドプレフィックスが "!ai " で始まるか判定 if message.content.startswith("!ai "): prompt = message.content[4:].strip() reply = await safe_chat(prompt) # 後述のバックオフ付き呼び出し await message.reply(reply) client.run(TOKEN) |
message_contentが無効だとon_messageが発火しません(2026 年現在の必須設定)。- 自己メッセージ除外は 無限ループ防止 の基本です。
3‑2. OpenAI 非同期呼び出しの実装
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import openai, aiohttp, random openai.api_key = os.getenv("OPENAI_API_KEY") async def _chat_once(user_prompt: str) -> str: """OpenAI ChatCompletion を非同期で 1 回だけ呼び出す""" async with aiohttp.ClientSession() as session: resp = await openai.ChatCompletion.acreate( model="gpt-4o-mini", messages=[{"role": "user", "content": user_prompt}], temperature=0.7, max_tokens=150, timeout=15, # ネットワークタイムアウト ) return resp.choices[0].message.content.strip() |
注記
OpenAI のレートリミットは API ドキュメントで随時確認してください。数値が変わる可能性があるため、ハードコーディングは避けます。
3‑3. 例外処理と指数バックオフ戦略
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
async def safe_chat(prompt: str) -> str: """レートリミットやネットワーク障害時に再試行するラッパー""" max_retries = 5 for attempt in range(max_retries + 1): try: return await _chat_once(prompt) except openai.error.RateLimitError: if attempt == max_retries: return "⚠️ OpenAI のレートリミットが上限に達しました。しばらくお待ちください。" except (aiohttp.ClientError, openai.error.APIError) as e: if attempt == max_retries: return f"❗ ネットワークエラー: {e}" # バックオフ:2^n 秒 + ランダム 0‑1 秒 wait = (2 ** attempt) + random.random() await asyncio.sleep(wait) |
RateLimitErrorは API 側がリクエスト過多と判断したときに送出されます。- ネットワーク障害 (
aiohttp.ClientError) も同様に再試行対象です。
4. 安全なキー管理とローカルテスト
4‑1. 環境変数のロードと .gitignore 設定
|
1 2 3 4 |
# .env(リポジトリに含めない) DISCORD_TOKEN=YOUR_DISCORD_BOT_TOKEN OPENAI_API_KEY=YOUR_OPENAI_API_KEY |
.gitignoreに必ず以下を追記し、機密情報がコミットされないようにします。
|
1 2 3 |
# Secrets .env |
python-dotenvのload_dotenv()をスクリプト冒頭で呼び出すだけで、os.getenv()が利用可能になります。
4‑2. ローカル実行とデバッグのポイント
- 仮想環境を有効化した状態で
python bot.pyを実行 - コンソールに 「✅ Bot が起動しました」 と表示されたら、Discord 上で
!ai こんにちはと送信して応答を確認
| エラー | 主な原因 | 対策 |
|---|---|---|
discord.errors.LoginFailure |
トークンが間違っている・.env 未ロード |
.env 内容と load_dotenv() 呼び出しを再確認 |
openai.error.AuthenticationError |
API キーが無効または期限切れ | OpenAI コンソールでキーを再生成 |
aiohttp.ClientConnectorError |
ネットワーク接続不良(プロキシ・ファイアウォール) | 環境変数 HTTPS_PROXY でプロキシ設定、もしくはネットワーク管理者に確認 |
- デバッグ支援:VS Code の「Python: Attach」や
print()でハンドラが呼び出されたかを随時確認できます。 - 自動リロード:開発中は
watchdogやdiscord.ext.tasksを利用してコード変更時に Bot を再起動すると作業効率が上がります。
5. 無料クラウドホスティングへデプロイ
以下では代表的な無料プラン Replit, Fly.io, Railway の手順を示します。いずれも GitHub リポジトリからインポートでき、環境変数は Web UI で設定可能です。
5‑1. Replit
- 概要:ブラウザ上だけでコード実行・永続化が完結。無料枠は 24 時間ごとにスリープしますが、UptimeRobot 等で定期的に ping すれば自動復帰できます。
- 手順
- Replit にサインアップ → 「Create」→「Import from GitHub」
- リポジトリ URL を貼り付けてインポート
- UI の
.envタブでDISCORD_TOKENとOPENAI_API_KEYを設定 .replitファイルを作成しエントリーポイントを指定
|
1 2 |
run = "python bot.py" |
- 「Run」ボタンで起動確認。ログに 「✅ Bot が起動しました」 と出れば完了です。
5‑2. Fly.io(コンテナデプロイ)
- 概要:Docker コンテナを直接実行でき、無料プランは月間 3 時間の CPU 使用が許可されます。軽量な Bot であれば十分です。
- 手順
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Fly CLI インストール(ローカル) curl -L https://fly.io/install.sh | sh # プロジェクトディレクトリに Dockerfile を作成 cat > Dockerfile <<'EOF' FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "bot.py"] EOF # 初回デプロイとシークレット設定 fly launch # アプリ名・リージョンを入力 fly secrets set DISCORD_TOKEN=$DISCORD_TOKEN OPENAI_API_KEY=$OPENAI_API_KEY fly deploy |
- デプロイ後は
fly logsで起動ログを確認できます。 - レートリミット対策:頻繁に API を呼び出す場合は、1 分あたりの最大リクエスト数を制限するロジック(例:
asyncio.Semaphore(10)) を組み込むと安全です。
5‑3. Railway
- 概要:GitHub と連携して自動ビルド・デプロイが行える PaaS。無料プランは「Monthly Hours」制限がありますが、Bot が軽量なら余裕で稼働します。
-
手順
-
Railway にサインアップ → 「New Project」→「Deploy from GitHub」
- リポジトリを選択し、Environment Variables タブで
DISCORD_TOKENとOPENAI_API_KEYを登録 Procfile(もしくはrailway.json)で起動コマンドを指定
|
1 2 |
worker: python bot.py |
- デプロイが完了したら、Web コンソールの Logs タブで「Bot が起動しました」を確認。
5‑4. レートリミットと例外ハンドリングのベストプラクティス(共通)
| 項目 | 推奨実装 |
|---|---|
| OpenAI のレートリミット | ドキュメントで上限を取得し、指数バックオフ で再試行。 |
| Discord のレートリミット | discord.py が自動スロットリングするが、大量返信は asyncio.Semaphore や キューイング で抑制。 |
| エラーログの一元化 | 標準出力だけでなく、管理者専用チャンネルへ通知(例: notify_admin()) |
|
1 2 3 4 5 6 7 |
ADMIN_CHANNEL_ID = 123456789012345678 async def notify_admin(msg): ch = client.get_channel(ADMIN_CHANNEL_ID) if ch: await ch.send(f"⚠️ {msg}") |
6. GitHub リポジトリ構成例と README の必須項目
6‑1. 推奨ディレクトリ構成
|
1 2 3 4 5 6 7 8 9 10 |
discord-ai-bot/ │─ .gitignore # .env を除外 │─ .env.example # サンプル(キーは省略) │─ bot.py # メインコード │─ requirements.txt # 依存パッケージ一覧 (openai 含む) │─ README.md # 本ガイド本文 │─ Dockerfile # Fly.io 用 │─ Procfile # Railway 用 └─ LICENSE # 任意のライセンス (MIT 推奨) |
6‑2. README に記載すべき情報
|
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 27 28 29 30 |
# Discord AI Bot (Python) ## 概要 GPT‑4o-mini を利用した自然言語応答を行う Discord Bot。 ## 必要環境 - Python 3.12+ - discord.py >= 2.3 - OpenAI API キー(gpt‑4o 系モデル) ## セットアップ手順 1. リポジトリのクローン `git clone https://github.com/yourname/discord-ai-bot.git && cd discord-ai-bot` 2. 仮想環境作成・依存関係インストール `python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt` 3. `.env` を作成しトークンと API キーを設定(`.gitignore` で除外済み) 4. Bot 起動 `python bot.py` ## デプロイ例 - Replit: https://replit.com/… - Fly.io: https://fly.io/… - Railway: https://railway.app/… ## ライセンス MIT License ## コントリビューション Issue または Pull Request を歓迎します。 |
まとめ
- Discord ポータルで Bot とトークンを取得 →
.envに安全保存。 - Python 3.12 + venv で環境を分離し、
discord.py>=2.3,python-dotenv,openaiを含むrequirements.txtを用意。 - Intent 有効化・基本ハンドラ と 非同期 OpenAI 呼び出し(バックオフ付き)で
!aiコマンドに応答させる。 - dotenv と .gitignore でシークレットを管理し、ローカルテスト時のデバッグポイントとエラーハンドリング表を活用。
- Replit / Fly.io / Railway のいずれかにデプロイし、無料枠でも 24 時間稼働できる構成を実現。
- レートリミット対策と例外通知 を共通化すれば、運用中の予期せぬ停止を最小限に抑えられます。
この手順に沿って進めれば、初心者でも安全かつ安定した AI Discord Bot を構築し、無料クラウド上で公開できます。ぜひ実際に動かしてみて、自分だけのカスタム機能を追加してみましょう!