[Discord REST-API schlägt bei Proxy trotz WebSocket-Erfolg fehl] - Discord REST API Fails with Proxy Despite WebSocket Success
Die `channels.discord.proxy`-Konfiguration gilt nur für WebSocket-Gateway-Verbindungen, nicht für ausgehende REST-API-Aufrufe. Dies führt zu Fetch-Fehlern beim Senden von Nachrichten in eingeschränkten Regionen.
🔍 Symptome
Hauptsymptom
Discord-Bot empfängt Nachrichten erfolgreich, kann sie aber nicht senden und wirft einen TypeError: fetch failed-Fehler.
Technische Manifestationen
Logausgabe-Muster: 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-Diagnosebefehle
bash
Verify Discord connection status
openclaw debug channels
Test proxy connectivity
curl -x http://127.0.0.1:7890/ https://discord.com/api/v10/gateway
Check if REST calls bypass proxy
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)); "
Konfiguration, die korrekt erscheint, aber fehlschlägt
yaml channels: discord: enabled: true token: “Bot xxx…” proxy: “http://127.0.0.1:7890/” # WebSocket uses this # No REST proxy override available
🧠 Ursache
Architektonisches Problem: Duale Netzwerkpfade
Die Discord-Kanalimplementierung von OpenClaw verwendet zwei unterschiedliche Netzwerkpfade:
| Operationstyp | Netzwerkpfad | Proxy-Unterstützung |
|---|---|---|
| Gateway-Verbindung (WebSocket) | discord.io WebSocket-Client | ✅ Respektiert channels.discord.proxy |
| REST-API-Aufrufe (Nachricht senden, Anhang hochladen usw.) | carbon-request RequestClient | ❌ Keine Proxy-Unterstützung |
Codefluss-Analyse
User sends message to Discord ↓ OpenClaw receives via WebSocket (✓ proxied) ↓ Bot processes and needs to reply ↓ RequestClient.sendMessage() called ↓ fetch() executes WITHOUT proxy agent ↓ TypeError: fetch failed (connection refused/timeout)
Spezifische Dateibeteiligung
Die Grundursache liegt darin, wie carbon-request / RequestClient im Discord-Kanal-Handler aufgerufen wird:
javascript
// In discord-channel.js (simplified)
async function sendReply(message) {
const client = new RequestClient(); // No agent passed
return client.post({
url: https://discord.com/api/v10/channels/${channelId}/messages,
body: { content: message }
}); // Direct connection, no proxy
}
Die Einstellung channels.discord.proxy wird nur vom WebSocket-Initialisierungspfad verwendet, niemals vom REST-Request-Handler.
Warum es für den Empfang funktioniert
Die WebSocket-Frame-Verarbeitung übergibt den Proxy-Agent korrekt: javascript const ws = new WebSocket(url, { agent: new HttpsProxyAgent(proxyUrl) // ✅ Proxy applied });
Warum es für das Senden fehlschlägt
Der REST-Aufruf erstellt eine direkte Verbindung: javascript // carbon-request internal (simplified) function request(options) { return fetch(options.url, { // No agent configuration for proxy }); }
🛠️ Schritt-für-Schritt-Lösung
Option 1: Umgebungsvariablen-Override (Workaround - Sofort)
Setzen Sie globale Proxy-Umgebungsvariablen vor dem Start von 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/”
Then start OpenClaw
openclaw start
Vorher vs. Nachher:
| Einstellung | Vorher | Nachher |
|---|---|---|
channels.discord.proxy | Nur WebSocket | Nur WebSocket |
| Umgebungsvariablen | Nicht gesetzt | Gesamter Datenverkehr über Proxy |
Option 2: Code-Level-Fix (Permanent - Erfordert Patching)
Erstellen Sie ein Wrapper-Modul, das Proxy auf alle HTTP-Anfragen anwendet:
Schritt 1: Erforderliche Abhängigkeit installieren bash npm install https-proxy-agent –save
Schritt 2: Proxy-fähigen RequestClient-Wrapper erstellen javascript // File: ~/.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, // Force HTTPS for Discord API protocol: ‘https:’ }); }
get(options) { return super.get({ …options, agent: this.agent }); }
post(options) { return super.post({ …options, agent: this.agent }); } }
module.exports = { ProxyRequestClient };
Schritt 3: Discord-Kanal patchen, um Wrapper zu verwenden javascript // In discord-channel.js, modify initialization: // Find: const client = new RequestClient(); // Replace with: const proxyUrl = config.get(‘channels.discord.proxy’) || process.env.HTTPS_PROXY; const client = proxyUrl ? new ProxyRequestClient(proxyUrl) : new RequestClient();
Option 3: carbon-request durch proxy-fähigen Client ersetzen
Schritt 1: node-fetch mit Agent-Unterstützung installieren bash npm install node-fetch@2 https-proxy-agent@5 –save
Schritt 2: RequestClient-Verwendung im Discord-Kanal ersetzen javascript // Replace all RequestClient imports with: const fetch = require(’node-fetch’); const { HttpsProxyAgent } = require(‘https-proxy-agent’);
// In sendMessage function: 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(); }
🧪 Verifizierung
Test 1: WebSocket-Proxy überprüfen (Sollte bereits funktionieren)
bash openclaw debug –channel discord –verbose 2>&1 | grep -i proxy
Erwartete Ausgabe: log [INFO] Discord gateway connecting via proxy: http://127.0.0.1:7890/ [INFO] Discord gateway connected (WebSocket)
Test 2: REST-Proxy überprüfen (Die eigentliche Lösung)
javascript // Save as test-discord-rest.js const { HttpsProxyAgent } = require(‘https-proxy-agent’);
async function testProxyRequest() { const proxyUrl = ‘http://127.0.0.1:7890’;
// Test without proxy (should fail in restricted region) 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); }
// Test with proxy (should succeed) 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();
Ausführen mit: bash node test-discord-rest.js
Test 3: Discord-Nachricht von Ende zu Ende senden
bash
Start OpenClaw with proxy
HTTP_PROXY=“http://127.0.0.1:7890” HTTPS_PROXY=“http://127.0.0.1:7890” openclaw start
In another terminal, send test message via Discord
Send “!test” to your bot
Check logs
tail -f ~/.openclaw/logs/openclaw.log | grep -E “(discord|message|proxy|error)”
Erwartetes Erfolgsmuster: log [INFO] Discord gateway connected via proxy [INFO] Received: !test [INFO] Sending reply via REST (proxied) [INFO] Reply sent successfully (200 OK)
Test 4: Überprüfen, dass kein „fetch failed"-Fehler auftritt
bash
After fix, this should not appear
grep -r “fetch failed” ~/.openclaw/logs/
Erwartet: Keine Treffer (leeres Ergebnis)
⚠️ Häufige Fehler
Fallstrick 1: Mischung von HTTP/HTTPS-Proxy-Protokollen
Discord-API erfordert HTTPS. Stellen Sie sicher, dass Ihre Proxy-Konfiguration HTTPS verwendet:
| ❌ Falsch | ✅ Richtig |
|---|---|
http://127.0.0.1:7890/ für Gateway | Für beides verwenden (Node übernimmt Upgrade) |
| SOCKS-Proxy ohne Agent-Konfiguration | socks-proxy-agent explizit installieren |
javascript // For SOCKS proxies: const { SocksProxyAgent } = require(‘socks-proxy-agent’); const agent = new SocksProxyAgent(‘socks://127.0.0.1:1080’);
Fallstrick 2: Umgebungsvariablen-Gültigkeitsbereich
Umgebungsvariablen, die nach dem Prozessstart gesetzt werden, gelten nicht. Immer vor dem Start setzen:
bash
✗ Wrong - vars not inherited
openclaw start && export HTTP_PROXY="…"
✓ Correct - vars set before fork
HTTP_PROXY="…" openclaw start
Fallstrick 3: Node.js-Versionskompatibilität
https-proxy-agent@5+ erfordert Node.js 18+. Für ältere Versionen:
bash node –version
If < 18, use: npm install https-proxy-agent@4
Fallstrick 4: Proxy-Authentifizierung wird nicht behandelt
Wenn Ihr Proxy Benutzername/Passwort erfordert:
javascript const proxyUrl = ‘http://user:pass@127.0.0.1:7890/’; // or const proxyUrl = ‘http://’ + encodeURIComponent(‘user’) + ‘:’ + encodeURIComponent(‘pass’) + ‘@127.0.0.1:7890/’;
Fallstrick 5: TLS-Zertifikatsfehler
In einigen Proxy-Konfigurationen müssen Sie möglicherweise die SSL-Überprüfung zum Testen deaktivieren:
javascript process.env.NODE_TLS_REJECT_UNAUTHORIZED = ‘0’;
⚠️ Warnung: Nur für das Debugging verwenden. Niemals in der Produktion.
Fallstrick 6: Docker-Container-Proxy-Isolation
Wenn OpenClaw in Docker läuft, muss der Proxy innerhalb des Containers erreichbar sein:
bash
✗ Container can’t reach host loopback
HTTP_PROXY=“http://127.0.0.1:7890”
✓ Use host network or docker.for.mac.localhost
HTTP_PROXY=“http://host.docker.internal:7890”
Für Docker --network=host hinzufügen oder network_mode: host in docker-compose konfigurieren.
🔗 Zugehörige Fehler
Logisch verbundene Fehlermuster
| Fehler | Beschreibung | Zugehörig zu |
|---|---|---|
TypeError: fetch failed | REST-Aufruf-Verbindungsfehler | Dieses Problem |
ECONNREFUSED | Proxy-Server läuft nicht | Netzwerk/Proxy-Verfügbarkeit |
ETIMEDOUT | Verbindungs-Timeout zu Discord | Netzwerk/Firewall blockiert |
ENOTFOUND | Discord-DNS kann nicht aufgelöst werden | DNS-Filterung in eingeschränkten Regionen |
Failed to connect to Discord gateway | WebSocket-Init-Fehler | Proxy nicht auf WS-Client angewendet |
Disconnected with code 1006 | WebSocket abnormales Schließen | Netzwerkinstabilität/Proxy trennt |
Request timeout | REST-Anfrage hängt | Proxy langsam/instabil |
Historischer Kontext
- Issue #1423: WebSocket-Proxy-Unterstützung für Discord-Gateway hinzugefügt
- Issue #1891: Medien-/Anhang-Downloads umgehen Proxy
- Issue #2156: carbon-request-Client fehlt Agent-Injektions-API
Ähnliche Muster in anderen Kanälen
| Kanal | Hat REST-Proxy-Problem | Workaround |
|---|---|---|
| Discord | ✅ Ja (dieses Problem) | Env-Variablen / Code-Patch |
| Slack | ⚠️ Teilweise | Verwendet node-fetch mit Agent |
| Teams | ❌ Unbekannt | Erfordert Testen |
| Mattermost | ❌ Unbekannt | Erfordert Testen |