April 21, 2026 • バージョン: 2026.2.26

[プロキシ使用時のDiscord REST API失敗] - Discord REST API Fails with Proxy Despite WebSocket Success

`channels.discord.proxy`設定はWebSocketゲートウェイ接続のみに適用され、アウトバウンドREST API呼び出しには適用されません。これにより、制限された地域でメッセージを送信する際のフェッチエラーが発生します。

🔍 症状

主な症状

Discordボットのメッセージ受信は成功するが、送信に失敗し、TypeError: fetch failedエラーが発生する。

技術的な症状

ログ出力パターン: log [2026-02-26 10:23:45] INFO: Discord gateway connected via proxy ws://127.0.0.1:7890/ [2026-02-26 10:23:52] INFO: Received message from user123 [2026-02-26 10:23:52] ERROR: discord final reply failed: TypeError: fetch failed [2026-02-26 10:23:52] ERROR: at fetch (node:internal/deps:node_fetch:index.js:…) at async RequestClient.request (…)

CLI診断コマンド

bash

Discord接続状態を確認

openclaw debug channels

プロキシ接続性をテスト

curl -x http://127.0.0.1:7890/ https://discord.com/api/v10/gateway

REST呼び出しがプロキシをバイパスするか確認

node -e " const fetch = require(’node-fetch’); fetch(‘https://discord.com/api/v10/gateway', { agent: new (require(‘http-proxy-agent’))(‘http://127.0.0.1:7890’) }).then(r => console.log(‘Proxy works:’, r.status)).catch(e => console.error(‘Failed:’, e.message)); "

正しく見えるが失敗する設定

yaml channels: discord: enabled: true token: “Bot xxx…” proxy: “http://127.0.0.1:7890/” # WebSocketはこれを使用 # RESTプロキしのオーバーライドは利用不可

🧠 原因

アーキテクチャ上の問題:二重ネットワークパス

OpenClawのDiscordチャンネル実装は、2つの異なるネットワークパスを使用します:

操作タイプネットワークパスプロキシサポート
Gateway接続(WebSocket)discord.io WebSocketクライアントchannels.discord.proxyを尊重
REST API呼び出し(メッセージ送信、添付ファイルアップロード等)carbon-request RequestClient❌ プロキシサポートなし

コードフロー分析

ユーザーがDiscordにメッセージを送信 ↓ OpenClawがWebSocket経由で受信(✓ プロキシ経由) ↓ ボットが処理して返信が必要 ↓ RequestClient.sendMessage()呼び出し ↓ fetch()がプロキシエージェントなしで実行 ↓ TypeError: fetch failed(接続拒否/タイムアウト)

関連するファイル

根本原因は、carbon-request / RequestClientがDiscordチャンネルハンドラーでどのように呼び出されるかにあります:

javascript // discord-channel.js内(簡略化) async function sendReply(message) { const client = new RequestClient(); // agentが渡されていない return client.post({ url: https://discord.com/api/v10/channels/${channelId}/messages, body: { content: message } }); // 直接接続、プロキシなし }

channels.discord.proxy設定は、WebSocket初期化コードパスでのみ使用され、RESTリクエストハンドラーでは使用されません。

受信が機能する理由

WebSocketフレーム処理は正しくプロキシエージェントを渡します: javascript const ws = new WebSocket(url, { agent: new HttpsProxyAgent(proxyUrl) // ✅ プロキシが適用される });

送信が失敗する理由

REST呼び出しは直接接続を作成します: javascript // carbon-request内部(簡略化) function request(options) { return fetch(options.url, { // プロキシ用のagent設定がない }); }

🛠️ 解決手順

オプション1:環境変数のオーバーライド(回避策 - 即時対応)

OpenClawを起動する前にグローバルプロキシ環境変数を設定します:

bash

Linux/macOS

export HTTP_PROXY=“http://127.0.0.1:7890/” export HTTPS_PROXY=“http://127.0.0.1:7890/” export http_proxy=“http://127.0.0.1:7890/” export https_proxy=“http://127.0.0.1:7890/”

次にOpenClawを起動

openclaw start

変更前と変更後:

設定変更前変更後
channels.discord.proxyWebSocketのみWebSocketのみ
環境変数未設定全トラフィックがプロキシ経由

オプション2:コードレベルの修正(恒久対応 - パッチ適用が必要)

すべてのHTTPリクエストにプロキシを適用するラッパーモジュールを作成します:

ステップ1: 必要な依存関係をインストール bash npm install https-proxy-agent –save

ステップ2: プロキシ対応のRequestClientラッパーを作成 javascript // ファイル: ~/.openclaw/plugins/proxy-request-wrapper.js

const { RequestClient } = require(‘carbon-request’); const { HttpsProxyAgent } = require(‘https-proxy-agent’);

class ProxyRequestClient extends RequestClient { constructor(proxyUrl) { super(); this.proxyUrl = proxyUrl; this.agent = new HttpsProxyAgent(proxyUrl); }

request(options) { return super.request({ …options, agent: this.agent, // Discord API用にHTTPSを強制 protocol: ‘https:’ }); }

get(options) { return super.get({ …options, agent: this.agent }); }

post(options) { return super.post({ …options, agent: this.agent }); } }

module.exports = { ProxyRequestClient };

ステップ3: Discordチャンネルを修正してラッパーを使用 javascript // discord-channel.jsで、初期化を修正: // 検索: const client = new RequestClient(); // 置換: const proxyUrl = config.get(‘channels.discord.proxy’) || process.env.HTTPS_PROXY; const client = proxyUrl ? new ProxyRequestClient(proxyUrl) : new RequestClient();

オプション3:carbon-requestをプロキシ対応クライアントに置き換える

ステップ1: agentサポート付きでnode-fetchをインストール bash npm install node-fetch@2 https-proxy-agent@5 –save

ステップ2: DiscordチャンネルのRequestClient使用箇所を置き換え javascript // すべてのRequestClientインポートを以下で置き換え: const fetch = require(’node-fetch’); const { HttpsProxyAgent } = require(‘https-proxy-agent’);

// sendMessage関数内: async function sendMessage(channelId, content) { const proxyUrl = process.env.HTTPS_PROXY || config.channels?.discord?.proxy;

const options = { method: ‘POST’, headers: { ‘Authorization’: Bot ${config.channels.discord.token}, ‘Content-Type’: ‘application/json’ }, body: JSON.stringify({ content }) };

if (proxyUrl) { options.agent = new HttpsProxyAgent(proxyUrl); }

const response = await fetch( https://discord.com/api/v10/channels/${channelId}/messages, options );

return response.json(); }

🧪 検証

テスト1:WebSocketプロキシの確認(すでに機能しているはず)

bash openclaw debug –channel discord –verbose 2>&1 | grep -i proxy

期待される出力: log [INFO] Discord gateway connecting via proxy: http://127.0.0.1:7890/ [INFO] Discord gateway connected (WebSocket)

テスト2:RESTプロキシの確認(実際の修正確認)

javascript // test-discord-rest.jsとして保存 const { HttpsProxyAgent } = require(‘https-proxy-agent’);

async function testProxyRequest() { const proxyUrl = ‘http://127.0.0.1:7890’;

// プロキシなしテスト(制限された地域では失敗するはず) try { await fetch(‘https://discord.com/api/v10/gateway'); console.log(’✗ Direct connection succeeded (unexpected)’); } catch (e) { console.log(’✓ Direct connection blocked as expected:’, e.message); }

// プロキシありテスト(成功するはず) try { const response = await fetch(‘https://discord.com/api/v10/gateway', { agent: new HttpsProxyAgent(proxyUrl) }); console.log(’✓ Proxy connection succeeded, status:’, response.status); } catch (e) { console.log(’✗ Proxy connection failed:’, e.message); } }

testProxyRequest();

実行: bash node test-discord-rest.js

テスト3:エンドツーエンドのDiscordメッセージ送信テスト

bash

プロキシ付きでOpenClawを起動

HTTP_PROXY=“http://127.0.0.1:7890” HTTPS_PROXY=“http://127.0.0.1:7890” openclaw start

別のターミナルで、Discord経由でテストメッセージを送信

ボットに"!test"を送信

ログを確認

tail -f ~/.openclaw/logs/openclaw.log | grep -E “(discord|message|proxy|error)”

成功パターンの例: log [INFO] Discord gateway connected via proxy [INFO] Received: !test [INFO] Sending reply via REST (proxied) [INFO] Reply sent successfully (200 OK)

テスト4:fetch failedエラーがないことを確認

bash

修正後、これは表示されないはず

grep -r “fetch failed” ~/.openclaw/logs/

期待結果: 一致なし(空の結果)

⚠️ よくある落とし穴

落とし穴1:HTTP/HTTPSプロキシプロトコルの混用

Discord APIはHTTPSが必要です。プロキシ設定でHTTPSを使用していることを確認してください:

❌ 間違い✅ 正しい
gateway用 http://127.0.0.1:7890/両方中使用(nodeがアップグレードを処理)
agent設定なしのSOCKSプロキシsocks-proxy-agentを明示的にインストール

javascript // SOCKSプロキシの場合: const { SocksProxyAgent } = require(‘socks-proxy-agent’); const agent = new SocksProxyAgent(‘socks://127.0.0.1:1080’);

落とし穴2:環境変数のスコープ

プロセスの起動後に設定された環境変数は適用されません。起動前に常に設定してください:

bash

✗ 間違い - 変数が継承されない

openclaw start && export HTTP_PROXY="…"

✓ 正しい - fork前に変数を設定

HTTP_PROXY="…" openclaw start

落とし穴3:Node.jsバージョンの互換性

https-proxy-agent@5+はNode.js 18+が必要です。古いバージョンの場合:

bash node –version

18未満の場合は: npm install https-proxy-agent@4

落とし穴4:プロキシ認証の処理

プロキシにユーザー名/パスワードが必要な場合:

javascript const proxyUrl = ‘http://user:pass@127.0.0.1:7890/’; // または const proxyUrl = ‘http://’ + encodeURIComponent(‘user’) + ‘:’ + encodeURIComponent(‘pass’) + ‘@127.0.0.1:7890/’;

落とし穴5:TLS証明書エラー

一部のプロキシ設定では、テスト用にSSL検証を無効にする必要がある場合があります:

javascript process.env.NODE_TLS_REJECT_UNAUTHORIZED = ‘0’;

⚠️ 警告: これはデバッグ専用にのみ使用してください。本番環境では使用しないでください。

落とし穴6:Dockerコンテナの プロキシ隔離

DockerでOpenClawを実行している場合、プロキシはコンテナ内からアクセス可能でなければなりません:

bash

✗ コンテナがホストのループバックに到達できない

HTTP_PROXY=“http://127.0.0.1:7890”

✓ ホストネットワークまたはdocker.for.mac.localhostを使用

HTTP_PROXY=“http://host.docker.internal:7890

Dockerの場合、--network=hostを追加するか、docker-composeでnetwork_mode: hostを設定します。

🔗 関連するエラー

論理的に関連するエラーパターン

エラー説明関連性
TypeError: fetch failedREST呼び出しの接続失敗この問題
ECONNREFUSEDプロキシサーバーが起動していないネットワーク/プロキシ可用性
ETIMEDOUTDiscordへの接続タイムアウトネットワーク/ファイアウォールがブロック
ENOTFOUNDDiscord DNS解決不可制限された地域でのDNSフィルタリング
Failed to connect to Discord gatewayWebSocket初期化失敗WSクライアントにプロキシが適用されない
Disconnected with code 1006WebSocket異常終了ネットワーク不安定/プロキシ切断
Request timeoutRESTリクエストがハングプロキシ遅い/不安定

歴史的背景

  • Issue #1423: Discord gatewayのWebSocketプロキシサポートが追加
  • Issue #1891: メディア/添付ファイルのダウンロードがプロキシをバイパス
  • Issue #2156: carbon-requestクライアントにagent注入APIがない

他のチャンネルでの類似パターン

チャンネルRESTプロキシ問題あり回避策
Discord✅ はい(この問題)環境変数 / コードパッチ
Slack⚠️ 一部agent付きでnode-fetchを使用
Teams❌ 不明テストが必要
Mattermost❌ 不明テストが必要

エビデンスとソース

このトラブルシューティングガイドは、FixClaw Intelligence パイプラインによってコミュニティの議論から自動的に合成されました。