このリポジトリは、金属価格コマンド・ChatGPT 会話 Bot・サーバーアクティビティログ・高度なセキュリティ対策を
1 つに統合した Discord ボット実装です。
単なる娯楽 Bot ではなく、
「情報取得」「会話」「監査」「防衛」
を同時に担う 運用向け Bot として設計されています。
/gold/silver/platinum/all- JPY ベースのリアルタイム金属価格を取得
- グラム指定に対応
- Embed 形式で視認性の高い表示
- 日本語限定・ヴォルデモート人格
- ユーザーごとに会話履歴を保持し、文脈の続いた会話が可能
- OpenAI の検索機能付きモデルを使用
使用モデル:
gpt-4o-search-preview(会話)gpt-4o-mini(セキュリティ補助判定)
以下のイベントを 指定ログチャンネルへ Embed 形式 で出力します(JST 時刻付き)。
- メッセージ送信 / 削除 / 編集
- ボイスチャンネル参加 / 退出 / 移動 / 状態変化
- メンバー参加 / 退出
- ロール変更 / ニックネーム変更
- チャンネル作成 / 削除
- Bot コマンド実行 / エラー
ギルドごとに以下の設定を settings.json に保存します。
- ログチャンネル ID
- ログレベル(
NONE / ERROR / INFO / DEBUG) - ChatGPT 応答チャンネル
- 信頼済みユーザー ID リスト
- セキュリティバイパスロール ID リスト
すべて Slash コマンド経由で安全に操作可能です。
- メッセージレート監視
- Unicode 異常検出
- GPT による危険コンテンツ判定
- VirusTotal 連携(URL / ファイル)
- VC レイド検知
- 危険時の自動ロール剥奪 + 注意喚起
/
├── main.py
├── config.py
├── bot_setup.py
├── commands/
│ ├── metal_commands.py
│ ├── chat_commands.py
│ └── logging_commands.py
├── services/
│ ├── metal_service.py
│ ├── chatgpt_service.py
│ ├── discord_utils.py
│ ├── logging_service.py
│ ├── settings_store.py
│ └── security_service.py
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
DISCORD_BOT_TOKEN=your_bot_token
METALPRICE_API_KEY=your_metalprice_api_key
OPENAI_API_KEY=your_openai_api_key
VIRUSTOTAL_API_KEY=your_virustotal_api_key※ VirusTotal を使用しない場合は未設定でも可。
pip install -r requirements.txt
python main.py起動後、Slash コマンドは自動同期されます。
/help を実行すると、登録済みコマンドが Embed で表示されます。
/set_log_channel/set_log_level/set_response_channel/clear_response_channel
/add_trusted_members/remove_trusted_members/list_trusted_members/add_bypass_roles/remove_bypass_roles/list_bypass_roles
/gold g:<number>/silver g:<number>/platinum g:<number>/all g:<number>
- 指定された応答チャンネルでのみ反応
- ユーザー ID ごとに会話履歴を保持
- システムプロンプトに以下を含む:
- ヴォルデモート人格
- 日本語限定
- 威圧的・尊大な口調
- 現在日時(JST)
OpenAI API:
- Endpoint:
https://api.openai.com/v1/chat/completions - Model:
gpt-4.1-mini - Temperature:
0.45
- すべて
logging_service.log_action経由 - Embed Author にユーザー名とアイコン表示
- 通常ログはアイコン色から Embed 色を自動抽出
- セキュリティ関連ログは 常に赤色で強調
- フッターに JST 時刻を表示
以下に該当するユーザーは 全セキュリティチェックをスキップ。
- 信頼済みユーザー
- バイパスロール保持者
非除外ユーザーに対し、以下を順に評価します。
-
レート監視
- 1 秒以内に 3 件以上でスパム判定
-
Unicode 異常検出
- 極端な長文
- 同一文字の連続
- ゼロ幅 / Bidi / 制御文字の大量使用
-
GPT モデレーション
- モデル:
gpt-5-mini - 危険判定・理由・カテゴリを JSON で取得
- モデル:
-
VirusTotal
- URL / 添付ファイルをスキャン
- キャッシュによる API 節約
- メッセージ削除
@everyone以外のロール剥奪- ログ出力
- チャンネルで注意喚起メッセージ送信
- 20 秒以内
- 同一 VC
- 名前の先頭が類似したユーザーが 5 人以上
→ レイドと判定しロール剥奪 + 警告
-
初期設定
/set_log_channel/set_log_level/set_response_channel
-
信頼設定
/add_trusted_members/add_bypass_roles
-
定期確認
/list_trusted_members/list_bypass_roles
Discord Bot とは別に、金・銀・プラチナの価格を JST 0:00 に日次保存 し、
Web画面でチャート表示できる機能を追加しています。
さらに、Bot ロジック準拠で金属の純度別価格計算も可能です。
PWA 対応により、Web Push 通知で日次の価格変動を受け取れます。
- FastAPI
- PostgreSQL(
asyncpg+ SQLAlchemy) - APScheduler(JST 0:00 実行)
- Chart.js(価格推移 + 前日差)
- 純度計算 API(
/api/prices/calculate) - Web Push(JST 11:00 に前日差最大の金属を通知)
metal_price_daily テーブルに以下を保存します。
- 金属キー(
gold/silver/platinum) - 取得日(JST 日付)
- 1gあたり価格(円)
- 前日差分(円)
python web_main.pyアクセス先:
http://localhost:${WEB_HOST_PORT:-8001}/- API:
http://localhost:${WEB_HOST_PORT:-8001}/api/prices/history?days=365
METALPRICE_API_KEY
POSTGRES_DSN は任意です。未指定時は以下を組み合わせて自動構成します。
POSTGRES_HOST(デフォルト:localhost)POSTGRES_PORT(デフォルト:5432)POSTGRES_DB(デフォルト:metal_prices)POSTGRES_USER(デフォルト:postgres)POSTGRES_PASSWORDまたはPOSTGRES_PASSWORD_FILE
任意:
API_RATE_LIMIT_PER_MINUTE(デフォルト: 120)API_CALCULATE_RATE_LIMIT_PER_MINUTE(デフォルト: 60)API_RESPONSE_CACHE_SECONDS(デフォルト: 20)PURITY_OPTIONS_CACHE_SECONDS(デフォルト: 3600)PUSH_PUBLIC_KEY_CACHE_SECONDS(デフォルト: 3600)FORECAST_REFRESH_MINUTE_JST(デフォルト: 5。毎時この分に予測のみ再計算)FORECAST_SARIMAX_ENABLED(デフォルト: true。統計モデルを有効化)FORECAST_SARIMAX_MIN_HISTORY(デフォルト: 24。SARIMAXを使う最小履歴件数)PUSH_NOTIFY_HOUR_JST(デフォルト: 11)PUSH_NOTIFY_MINUTE_JST(デフォルト: 0)APP_ROOT_PATH(サブパス配信時のみ。例:/metal)APP_PUBLIC_PATH(Push通知クリック先のベース。デフォルト:/)VAPID_AUTO_GENERATE(デフォルト: true)VAPID_KEYS_DIR(デフォルト:/shared/vapid)VAPID_PUBLIC_KEY(手動指定する場合)VAPID_PRIVATE_KEY(手動指定する場合)VAPID_SUBJECT(デフォルト:mailto:admin@example.com。admin@example.comを指定した場合はmailto:を自動補完。不正形式はデフォルトへフォールバック)TRUST_CF_HEADERS(デフォルト: true)REQUIRE_CF_CONNECTING_IP(デフォルト: false)ALLOWED_HOSTS(カンマ区切り)WEB_HOST_PORT(デフォルト: 8001)STARTUP_TEST_MODE(デフォルト: false)STARTUP_TEST_REQUIRE_DOCKER(デフォルト: true)STARTUP_TEST_RUN_MIDNIGHT_JOB_ON_BOOT(デフォルト: false)STARTUP_TEST_FORCE_SNAPSHOT_REFRESH(デフォルト: true)STARTUP_TEST_RUN_PUSH_ON_BOOT(デフォルト: false)
起動テスト機能の注意:
STARTUP_TEST_MODE=trueかつ各実行フラグが有効なときのみ、コンテナ起動時にテスト処理を実行します。STARTUP_TEST_REQUIRE_DOCKER=trueの場合、コンテナ外プロセスではテスト処理を強制的に無効化します。- テスト起動処理はサーバー起動フック内のみで実行し、HTTP API は提供しません。 そのためブラウザの JS コンソールや外部リクエストからは実行できません。
docker-compose.yml には以下サービスを定義済みです。
postgres-secret-init(初回のみランダムパスワード生成)postgressycs-voldemort(Discord Bot)sycs-voldemort-web(Webトラッカー)
docker compose up -d --build起動時テストを有効化する例(必要なときだけ設定):
STARTUP_TEST_MODE=true \
STARTUP_TEST_RUN_MIDNIGHT_JOB_ON_BOOT=true \
STARTUP_TEST_RUN_PUSH_ON_BOOT=true \
docker compose up -d --build sycs-voldemort-web- 初回起動時、
postgres-secret-initがランダムな PostgreSQL パスワードを生成します。 - パスワードは Docker Volume
shared_secrets内の/shared/postgres_passwordに保存されます。 postgres/sycs-voldemort-webは毎回このファイルを読み込むため、再起動後も同じパスワードで動作します。
manifest.webmanifestとservice workerを実装済みです。- ブラウザで「Push通知を有効化」を押すと購読登録されます。
- 価格スナップショット取得(MetalPriceAPI)は JST 0:00 の日次実行です。
- 価格予測は毎時
FORECAST_REFRESH_MINUTE_JST分に再計算し、最新結果を API に反映します。 - 予測は USD/JPY・ニュース・AI判定を合算した外生シグナルを含む SARIMAX で算出します(履歴不足時は自動フォールバック)。
- フロントは予測APIを約5分間隔で自動再フェッチし、生成時刻が更新されると表示を自動反映します。
- サーバーは JST 毎日 11:00 に「前日差が最大の金属」を通知します。
- 通知は
notification_dispatchテーブルで同日重複送信を防止します。 VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEYが未設定でも、初回起動時に/shared/vapidへ自動生成して再利用します。