Telegram: commands.nativeが起動時にsetMyCommandsを登録しない
OpenClaw 2026.4.14で正しい設定にもかかわらず、ネイティブTelegramボットコマンドがsetMyCommands経由で登録に失敗し、ボットインターフェースにコマンドメニューが表示されない状態になります。
🔍 症状
主な症状
Telegramボットはメッセージを受け取り、通常通りに処理しますが、ゲートウェイ起動時にネイティブコマンド登録が全く行われません。
診断出力パターン
ログエントリの欠落 bash
ログ内のsetMyCommandsを検索
grep -i “setMyCommands|setMyCommands|commands.native|BOT_COMMANDS” /var/log/openclaw/gateway.log
期待される出力: 以下のようなエントリが複数あるはず:
[INFO] TelegramProvider: Registering native commands via setMyCommands
[INFO] TelegramProvider: Successfully registered 8 bot commands
[DEBUG] bot.api.setMyCommands called with
実際の出力: マッチなし
オートコンプリートメニューが表示されない
Telegram DMでボットに対して/を入力しても、コマンドメニューが表示されません。スラッシュコマンドのオートコンプリート機能は、setMyCommandsが初期化時に呼び出されている必要があります。
設定は正しく見える json { “channels”: { “telegram”: { “enabled”: true, “token”: “123456789:ABCdefGHI…”, “commands”: { “native”: true, “nativeSkills”: true } } } }
CLI検証コマンド
bash
Telegram API経由でコマンドが登録されているか確認
curl -s “https://api.telegram.org/bot
正常登録後の期待される出力:
{
“ok”: true,
“result”: [
{“command”: “help”, “description”: “Show available commands”},
{“command”: “status”, “description”: “Check system status”},
…
]
}
実際の出力(バグありの場合):
{
“ok”: true,
“result”: []
}
サイレント失敗の特徴
ERRORまたはWARNレベルのログエントリがない- ゲートウェイの起動が正常に完了(終了コード0)
- Telegramボットは通常通りにメッセージに応答する
- スキルコマンドは手動で呼び出すと正常に実行される
- コマンドメニュー/オートコンプリートだけが欠落している
🧠 原因
アーキテクチャの背景
setMyCommands登録は、Telegramプロバイダーの初期化シーケンスで発生します。コードパスはdist/bot-BwMz6R6-.jsに存在しますが、1つ以上の早期リターン条件により決して到達しません。
主な原因
1. 設定スキーマの不一致
Telegramプロバイダーはcommands.nativeを文字列値としてチェックしますが、設定スキーマバリデーターが"true"を真偽値のtrueに、または"auto"予期しない列挙値に型強制 преобразуетします。条件チェックがサイレントに失敗します:
javascript // プロバイダー初期化時(動作から推測) if (config.commands?.native !== ‘auto’ && config.commands?.native !== true) { return early; // setMyCommands呼び出し前に終了 }
// 問題: config.commands.nativeが真偽値のtrue(文字列’true’ではなく) // またはパスがchannels.telegram.commands.native vsネスト構造の場合 // 比較が正しく評価されない
2. 非同期初期化の競合状態
Telegramプロバイダーがコマンドレジストリが設定される前に初期化する可能性があります:
Gateway Start │ ├── Load Channels Config │ │ │ └── TelegramProvider.init() │ │ │ └── bot.api.setMyCommands(retryCommands) │ │ │ └── retryCommands = [] ← コマンドはまだロードされていない │ └── Load Plugins/Skills │ └── コマンドレジストリの設定
プロバイダー初期化時にretryCommandsが評価される場合、スキルコマンドリストは空です。プラグインがプロバイダー初期化後にロードされるためです。
3. Promiseチェーンでのエラー握り潰し
setMyCommands呼び出しは、.catch()ハンドラーでログなしでエラーを握り潰すPromiseでラップされています:
javascript // 症状「エラーなし、警告なし」から推測 bot.api.setMyCommands(retryCommands) .then(() => logger.info(‘Commands registered’)) .catch(err => { // エラー在这里握り潰し - ログなし // void errまたは空のcatchブロック });
4. フィーチャーフラグの上書き
環境変数またはフィーチャーフラグがコマンド登録をグローバルに無効化している可能性があります:
bash
以下の環境変数により登録が阻止される
OPENCLAW_TELEGRAM_COMMANDS_ENABLED=false OPENCLAW_DISABLE_NATIVE_COMMANDS=1 TELEGRAM_SKIP_COMMAND_REGISTRATION=true
5. プロバイダー条件評価のバグ
Telegramプロバイダーに正しく評価されないガード条件がある可能性があります:
javascript // 考えられるコードパスの問題 class TelegramProvider { async start() { // バグ: 誤ったプロパティパスをチェック if (!this.config.channel?.commands?.native) { return this.startPolling(); // コマンド登録をスキップ }
// このコードに到達しない
await this.registerCommands();
}
}
// 正しいパスは以下の通り: if (!this.config.commands?.native) { … }
失敗シーケンス図
┌─────────────────────────────────────────────────────────────┐ │ Gateway Startup │ ├─────────────────────────────────────────────────────────────┤ │ 1. Config.load() → JSON + 環境変数をマージ │ │ └── channels.telegram.commands.native: true (真偽値) │ │ │ │ 2. PluginRegistry.load() │ │ └── スキルがロードされる、コマンドレジストリは空 │ │ │ │ 3. TelegramProvider.init() │ │ └── チェック: config.commands?.native !== ‘auto’ │ │ └── 真偽値true !== 文字列’auto’ → 早期終了 │ │ │ │ 4. setMyCommands()が呼び出されない │ │ └── retryCommands: [] │ │ │ │ 5. ゲートウェイ準備完了、ポーリングアクティブ │ │ └── コマンド未登録、エラーなし │ └─────────────────────────────────────────────────────────────┘
環境固有のトリガー
| プラットフォーム | トリガー | メカニズム |
|---|---|---|
| macOS LaunchAgent | 順序依存 | Plistがアルファベット順にサービスをロード |
| Docker | 設定ボリュームマウント | 環境変数オーバーライド適用前にJSONがパースされる |
| Linux systemd | タイミング | After=network.targetだがopenclaw-ready.serviceではない |
| Windows Service | レジストリの状態 | NSSMがサービス依存関係前に設定を読み込む |
🛠️ 解決手順
解決策1: 設定パスの修正
最も可能性の高い 문제는、不正確な設定パスまたは型不一致です。OpenClaw 2026.4.14は特定のスキーマ構造を期待します。
ステップ1: 設定スキーマを確認
bash
実際にロードされた設定を確認
cat ~/.openclaw/openclaw.json | jq ‘.channels.telegram.commands’
ステップ2: 正しい設定を適用
openclaw.jsonを編集します:
json // 修正前(不正確 - パスまたは型が間違っている可能性) { “channels”: { “telegram”: { “commands”: { “native”: true } } } }
// 修正後(正しいスキーマ) { “channels”: { “telegram”: { “commands”: { “native”: “auto” } } } }
注意: 真偽値trueの代わりに文字列"auto"を使用してください。コードは真偽値trueではなく、文字列リテラル'auto'およびtrue(文字列)と比較します。
ステップ3: ゲートウェイを再起動
bash
macOS LaunchAgent
launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist launchctl load ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Linux systemd
sudo systemctl restart openclaw-gateway
Docker
docker restart openclaw-gateway
直接(開発時)
pkill -f openclaw-gateway && openclaw gateway start
解決策2: 手動コマンド登録(即時の対応)
起動の問題を調査しながら即座にreliefを得る方法:
ステップ1: 必要なコマンドを識別
bash
OpenClawから登録された全コマンドをリスト
grep -r “BOT_COMMANDS|registerCommand|command.*description”
~/.openclaw/node_modules/openclaw/dist/ 2>/dev/null
| head -30
ステップ2: Telegram API経由で登録
bash
をボットトークンに置き換え
curl -X POST “https://api.telegram.org/bot
-H “Content-Type: application/json”
-d ‘{
“commands”: [
{“command”: “help”, “description”: “Show available commands and usage”},
{“command”: “status”, “description”: “Display system status and health”},
{“command”: “new”, “description”: “Start a new conversation thread”},
{“command”: “reset”, “description”: “Reset conversation context”},
{“command”: “model”, “description”: “Show or change the active AI model”},
{“command”: “skills”, “description”: “List available skill plugins”}
],
“scope”: {“type”: “default”}
}’
ステップ3: 登録を確認
bash
curl -s “https://api.telegram.org/bot
期待される出力: json { “ok”: true, “result”: [ {“command”: “help”, “description”: “Show available commands and usage”}, {“command”: “status”, “description”: “Display system status and health”} ] }
解決策3: 環境変数オーバーライド
設定パスは正しいがプロバイダーがまだ登録をスキップする場合:
ステップ1: デバッグ環境変数を設定
bash
シェルプロファイルまたはLaunchAgent plistのEnvironmentVariablesに追加
export OPENCLAW_TELEGRAM_COMMANDS_DEBUG=1 export DEBUG=openclaw:telegram:commands
ステップ2: ランタイムキャッシュをクリア
bash rm -rf ~/.openclaw/cache/* rm -rf ~/.openclaw/runtime/state.json
ステップ3: 詳細ログで再起動
bash
デバッグ出力付きで実行
openclaw gateway start –log-level debug 2>&1 | grep -i “command|setMy”
解決策4: コードレベルのホットフィックス
ランタイムコードを変更するアクセスがある場合:
ステップ1: プロバイダーファイルを Locate
bash
Telegramプロバイダーを検索
find ~/.openclaw/node_modules -name “provider-telegram*.js” -o
-name “TelegramProvider.js” 2>/dev/null
ステップ2: 条件チェックを修正
早期リターン条件を 찾아修正します:
javascript // 修正前(バグあり) if (config.commands?.native !== ‘auto’ && config.commands?.native !== true) { return early; }
// 修正後(修正済み) if (config.commands?.native === false || config.commands?.native === ‘false’) { return early; }
ステップ3: Catchブロックにエラーログを追加
javascript
setMyCommands呼び出し 찾아ログを追加
try {
await bot.api.setMyCommands(retryCommands);
logger.info(TelegramProvider: Registered ${retryCommands.length} native commands);
} catch (err) {
logger.error(‘TelegramProvider: Failed to register commands’, { error: err.message });
// 握り潰さない - 伝播させる
}
解決策5: プロバイダー起動順序の修正
プラグインロードとの競合状態が問題の場合:
ステップ1: 起動依存関係を追加
LaunchAgent用(ai.openclaw.gateway.plist):
xml
systemd用(openclaw-gateway.service):
ini
[Unit]
After=network.target
After=time-sync.target
Wants=time-sync.target
[Service] ExecStartPre=/bin/sleep 3 Restart=on-failure RestartSec=5
🧪 検証
即時の検証ステップ
ステップ1: コマンド登録のゲートウェイログを確認
bash
コマンド登録フィルター付きでログを監視
tail -f /var/log/openclaw/gateway.log 2>/dev/null | grep -E “setMyCommands|commands.*registered|native.*command”
または最近の起動の場合
grep -E “setMyCommands|commands.*registered|native.*command”
/var/log/openclaw/gateway.log | tail -20
期待される出力:
[TIMESTAMP] INFO TelegramProvider: Initializing native command registration [TIMESTAMP] INFO TelegramProvider: Built-in commands loaded: help, status, new, reset, model [TIMESTAMP] INFO TelegramProvider: Skill commands loaded: 4 commands [TIMESTAMP] INFO TelegramProvider: Calling setMyCommands with 8 commands [TIMESTAMP] INFO TelegramProvider: Successfully registered 8 bot commands via setMyCommands
実際の出力(バグが残っている場合):
一致するエントリが見つかりません
ステップ2: Telegram APIで確認
bash
ボットトークンに置き換え
TELEGRAM_TOKEN=“123456789:ABCdefGHI…”
curl -s “https://api.telegram.org/bot${TELEGRAM_TOKEN}/getMyCommands" | jq .
期待される出力: json { “ok”: true, “result”: [ { “command”: “help”, “description”: “Show available commands” }, { “command”: “status”, “description”: “Display system status” } ] }
実際の出力(未修正): json { “ok”: true, “result”: [] }
ステップ3: Telegramでコマンドメニューをテスト
- TelegramボットとのDMを開く
/と入力 — オートコンプリート付きのコマンドメニューが表示されるはず- 各コマンドを試す:
/help、/status、/new、/reset
期待される出力: /入力時に即座にコマンドメニューが表示される
実際の出力(未修正の場合): メニューが表示されない; コマンドは手動で入力する必要がある
自動検証スクリプト
bash #!/bin/bash
verify-telegram-commands.sh
TELEGRAM_TOKEN="${OPENCLAW_TELEGRAM_TOKEN:-}”
if [ -z “$TELEGRAM_TOKEN” ]; then echo “ERROR: OPENCLAW_TELEGRAM_TOKEN not set” exit 1 fi
echo “=== Telegram Bot Commands Verification ===” echo ""
登録済みコマンドを確認
RESPONSE=$(curl -s “https://api.telegram.org/bot${TELEGRAM_TOKEN}/getMyCommands") COUNT=$(echo “$RESPONSE” | jq ‘.result | length’)
echo “Registered commands: $COUNT” echo “$RESPONSE” | jq -r ‘.result[] | " /” + .command + " - " + .description’
if [ “$COUNT” -gt 0 ]; then echo "" echo “✓ SUCCESS: Commands are registered” exit 0 else echo "" echo “✗ FAILURE: No commands registered” exit 1 fi
検証を実行: bash chmod +x verify-telegram-commands.sh ./verify-telegram-commands.sh
期待される出力:
=== Telegram Bot Commands Verification ===
Registered commands: 6 /help - Show available commands /status - Display system status /new - Start a new conversation /reset - Reset conversation context /model - Show or change AI model /skills - List skill plugins
✓ SUCCESS: Commands are registered
ログ分析チェックリスト
修正を適用した後、起動時に以下のログエントリが存在することを確認:
| ログエントリ | ステータス | 意味 |
|---|---|---|
TelegramProvider: Initializing native command registration | ✓ 必須 | プロバイダーがネイティブコマンド有効を検出 |
TelegramProvider: Built-in commands loaded | ✓ 必須 | コアコマンドが列挙された |
TelegramProvider: Skill commands loaded: N commands | ✓ nativeSkills有効な場合 | プラグインコマンドがロードされた |
TelegramProvider: Calling setMyCommands with N commands | ✓ 必須 | API呼び出しが開始された |
TelegramProvider: Successfully registered N bot commands | ✓ 必須 | API呼び出しが成功した |
⚠️ よくある落とし穴
設定の落とし穴
1. 型強制の不一致
json // 誤り - 文字列ではなく真偽値 “native”: true
// 正しい - 文字列値 “native”: “auto”
プロバイダーコードは文字列リテラルと比較する可能性が高いです。真偽値trueはJavaScriptで文字列"true"と決して等しくなりません。
2. ネストパスのエラー
json // 誤り - ネストが間違っている “telegram”: { “plugin”: { “commands”: { “native”: true } } }
// 正しい - 期待されるパス “telegram”: { “commands”: { “native”: “auto” } }
3. 環境変数オーバーライドが無視される
bash
シェルで設定したがLaunchAgentに渡されていない
export OPENCLAW_TELEGRAM_COMMANDS_ENABLED=true # LaunchAgentに無視される
正しい方法: plistのEnvironmentVariablesに追加
プラットフォーム固有のトラップ
macOS LaunchAgent
| 落とし穴 | 症状 | 解決策 |
|---|---|---|
| launchdによる設定キャッシュ | 変更が有効にならない | launchctl unload/loadサイクルを実行 |
| ユーザーvsシステムplist | アクセス権限エラー | ~/Library/LaunchAgents/ vs /Library/LaunchAgents/を確認 |
| 古いPIDで再起動できない | 「すでに実行中」 | launchctl remove ai.openclaw.gateway && launchctl load |
Dockerコンテナー
| 落とし穴 | 症状 | 解決策 |
|---|---|---|
| ボリュームマウント順序 | 設定が見つからない | アプリケーションボリュームより先に設定ボリュームをマウント |
| ENV変数のタイミング | オーバーライドが適用されない | docker-compose.override.ymlを使用 |
| ネットワーク分離 | API呼び出しが失敗 | コンテナーがapi.telegram.orgに到達可能であることを確認 |
Linux Systemd
| 落とし穴 | 症状 | 解決策 |
|---|---|---|
| サービスが早すぎる起動 | 競合状態 | ExecStartPre=/bin/sleep 5を追加 |
| ジャーナルの切り詰め | ログが欠落 | journalctl -u openclaw-gateway -n 1000 |
| SELinux/AppArmor | ネットワークがブロック | setsebool -P nis_enabled 1 |
ランタイムの落とし穴
1. トークンの不一致
openclaw.jsonで使用されるボットトークンが環境変数のトークンと異なる場合、getMyCommandsとsetMyCommandsは異なるボットを参照します。
bash
トークンの一貫性を確認
jq ‘.channels.telegram.token’ ~/.openclaw/openclaw.json echo $OPENCLAW_TELEGRAM_TOKEN
2. BotFatherコマンドスコープ
Telegramボットは異なるスコープでコマンドを登録できます:
default- 全チャットcommands_in_private- プライベートチャットの فقطchat_idを持つチャットごとのスコープ
コマンドが以前BotFather介してスコープ付きで設定されていた場合、setMyCommandsはそれらを上書きしない可能性があります。
bash
全コマンドスコープをクリア
curl -X POST “https://api.telegram.org/bot
-H “Content-Type: application/json”
-d ‘{“scope”: {“type”: “all_private_chats”}}’
curl -X POST “https://api.telegram.org/bot
-H “Content-Type: application/json”
-d ‘{}’ # デフォルトスコープも削除
3. レート制限
TelegramはsetMyCommandsを毎秒約1回のレート制限します。デバッグ中にゲートウェイが急速に再起動すると、APIが呼び出しを拒否する可能性があります。
bash
レート制限エラーを確認
grep -i “Too Many Requests|retry_after” /var/log/openclaw/gateway.log
4. ボットモードの制限
certain modes (例:_inline-only、制限付き)のボットのモードではsetMyCommandsを使用できません。
開発の落とし穴
ホットリロードがプロバイダーを 놓す
一部のホットリロード実装ではプラグインを再初期化してもTelegramプロバイダーは再初期化しません。コマンドは再登録されません。
bash
設定の再ロードではなく、完全な再起動が必要
pkill -f openclaw openclaw gateway start
デバッグロギングがエラーを黙らせる
高いlogLevel設定(debug、trace)は、エラーをフィルタリングされるレベルでログ出力することがあります。
bash
Telegram関連のログを明示的に有効化
openclaw gateway start –log-level debug –log-filter “telegram,commands,provider”
🔗 関連するエラー
直接的に関連するエラー
| エラーコード | 説明 | 関連性 |
|---|---|---|
BOT_COMMANDS_TOO_MUCH | 100コマンドを超えた場合のTelegram APIエラー | スキル登録時にコマンドが多すぎる場合setMyCommandsが失敗 |
TELEGRAM_API_ERROR_400 | Telegram APIへの不正なリクエスト | setMyCommandsへの不正なコマンドペイロード |
TELEGRAM_API_ERROR_401 | 未認証 | 無効なボットトークンによりsetMyCommands不可 |
TELEGRAM_API_ERROR_429 | リクエスト过多 | setMyCommands呼び出しのレート制限 |
歴史的に関連する問題
| 問題 | 説明 | 可能性 |
|---|---|---|
lossless-clawコンテキストエンジンエラー | 再起動時のLCMエラー(issueで記載) | 二次的な問題、独立して解決済み |
| プラグイン初期化のタイミング | スキルがプロバイダー初期化後にロード | v2026.xで見られた競合状態パターン |
| バージョン間の設定スキーマ変更 | breakingな設定フォーマットの変更 | マイルストーンリリースで一般的 |
| プロバイダーライサイクル変更 | v2026.4でのTelegramプロバイダーリファクター | コードパスのバグの直接的な原因 |
他のチャネルの類似症状
| チャネル | 関連する症状 | 識別点 |
|---|---|---|
| Discord | スラッシュコマンドが登録されない | 異なるAPI(/applicationsエンドポイント)を使用 |
| Slack | App homeコマンドが欠落 | apps.connections.installフローを使用 |
| Matrix | コマンドプレフィックスが表示されない | ルーム状態イベント代わりにを使用 |
外部参照
- Telegram Bot API: setMyCommands —
https://core.telegram.org/bots/api#setmycommands - Telegram Bot API: getMyCommands —
https://core.telegram.org/bots/api#getmycommands - grammY Commands Plugin —
https://grammy.dev/plugins/commands - OpenClaw Config Schema —
~/.openclaw/node_modules/openclaw/schema/config.json
関連するログパターン
类似的な問題の診断時にゲートウェイログでこれらのパターンを検索:
bash
Telegram関連の全ログ
grep -E “TelegramProvider|Telegram.*provider|telegram” /var/log/openclaw/gateway.log
コマンド登録試行
grep -E “setMyCommands|register.*command|command.*registration” /var/log/openclaw/gateway.log
APIエラー
grep -E “api.*error|api.*fail|telegram.*error” /var/log/openclaw/gateway.log
設定ロード
grep -E “config.*load|channels.*init|provider.*start” /var/log/openclaw/gateway.log