April 21, 2026 • Versión: 2026.2.26

[La API REST de Discord falla con proxy pese al éxito de WebSocket] - Discord REST API Fails with Proxy Despite WebSocket Success

La configuración `channels.discord.proxy` solo se aplica a las conexiones de puerta de enlace WebSocket, no a las llamadas salientes de la API REST. Esto causa fallos de recuperación al enviar mensajes en regiones restringidas.

🔍 Síntomas

Síntoma principal

El bot de Discord recibe mensajes correctamente pero falla al enviarlos, arrojando un error TypeError: fetch failed.

Manifestaciones técnicas

Patrón de salida del log: 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 (…)

Comandos de diagnóstico CLI

bash

Verificar estado de conexión de Discord

openclaw debug channels

Probar conectividad del proxy

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

Verificar si las llamadas REST omiten el 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)); "

Configuración que parece correcta pero falla

yaml channels: discord: enabled: true token: “Bot xxx…” proxy: “http://127.0.0.1:7890/” # WebSocket usa esto # No hay anulación de proxy REST disponible

🧠 Causa raíz

Problema arquitectónico: rutas de red duales

La implementación del canal Discord de OpenClaw utiliza dos rutas de red distintas:

Tipo de operaciónRuta de redSoporte de proxy
Conexión Gateway (WebSocket)Cliente WebSocket discord.io✅ Respeta channels.discord.proxy
Llamadas API REST (enviar mensaje, subir adjunto, etc.)RequestClient de carbon-request❌ Sin soporte de proxy

Análisis del flujo de código

El usuario envía un mensaje a Discord ↓ OpenClaw recibe a través de WebSocket (✓ proxy aplicado) ↓ El bot procesa y necesita responder ↓ Se llama a RequestClient.sendMessage() ↓ fetch() se ejecuta SIN agente de proxy ↓ TypeError: fetch failed (conexión rechazada/tiempo de espera agotado)

Archivo específico involucrado

La causa raíz reside en cómo se invoca carbon-request / RequestClient en el manejador del canal Discord:

javascript // En discord-channel.js (simplificado) async function sendReply(message) { const client = new RequestClient(); // Sin agente pasado return client.post({ url: https://discord.com/api/v10/channels/${channelId}/messages, body: { content: message } }); // Conexión directa, sin proxy }

La configuración channels.discord.proxy solo es consumida por la ruta de inicialización del WebSocket, nunca por el manejador de solicitudes REST.

Por qué funciona para recibir

El manejo de tramas WebSocket pasa correctamente el agente de proxy: javascript const ws = new WebSocket(url, { agent: new HttpsProxyAgent(proxyUrl) // ✅ Proxy aplicado });

Por qué falla para enviar

La llamada REST crea una conexión directa: javascript // carbon-request interno (simplificado) function request(options) { return fetch(options.url, { // Sin configuración de agente para proxy }); }

🛠️ Solución paso a paso

Opción 1: Invalidación de variables de entorno (Alternativa - Inmediata)

Establece variables de entorno de proxy globales antes de iniciar 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/”

Luego inicia OpenClaw

openclaw start

Antes vs Después:

ConfiguraciónAntesDespués
channels.discord.proxySolo WebSocketSolo WebSocket
Variables de entornoNo establecidasTodo el tráfico con proxy

Opción 2: Corrección a nivel de código (Permanente - Requiere parche)

Crea un módulo wrapper que aplique proxy a todas las solicitudes HTTP:

Paso 1: Instalar dependencia requerida bash npm install https-proxy-agent –save

Paso 2: Crear wrapper de RequestClient consciente de proxy javascript // Archivo: ~/.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, // Forzar HTTPS para API de Discord protocol: ‘https:’ }); }

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

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

module.exports = { ProxyRequestClient };

Paso 3: Aplicar parche al canal Discord para usar el wrapper javascript // En discord-channel.js, modificar inicialización: // Encontrar: const client = new RequestClient(); // Reemplazar con: const proxyUrl = config.get(‘channels.discord.proxy’) || process.env.HTTPS_PROXY; const client = proxyUrl ? new ProxyRequestClient(proxyUrl) : new RequestClient();

Opción 3: Reemplazar carbon-request con cliente consciente de proxy

Paso 1: Instalar node-fetch con soporte de agente bash npm install node-fetch@2 https-proxy-agent@5 –save

Paso 2: Reemplazar uso de RequestClient en canal Discord javascript // Reemplazar todas las importaciones de RequestClient con: const fetch = require(’node-fetch’); const { HttpsProxyAgent } = require(‘https-proxy-agent’);

// En función 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(); }

🧪 Verificación

Prueba 1: Verificar proxy WebSocket (Debería funcionar)

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

Salida esperada: log [INFO] Discord gateway connecting via proxy: http://127.0.0.1:7890/ [INFO] Discord gateway connected (WebSocket)

Prueba 2: Verificar proxy REST (La corrección real)

javascript // Guardar como test-discord-rest.js const { HttpsProxyAgent } = require(‘https-proxy-agent’);

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

// Probar sin proxy (debería fallar en región restringida) try { await fetch(‘https://discord.com/api/v10/gateway'); console.log(’✗ Conexión directa réussie (inesperado)’); } catch (e) { console.log(’✓ Conexión directa bloqueada como esperado:’, e.message); }

// Probar con proxy (debería funcionar) try { const response = await fetch(‘https://discord.com/api/v10/gateway', { agent: new HttpsProxyAgent(proxyUrl) }); console.log(’✓ Conexión por proxy réussie, estado:’, response.status); } catch (e) { console.log(’✗ Conexión por proxy falló:’, e.message); } }

testProxyRequest();

Ejecutar con: bash node test-discord-rest.js

Prueba 3: Envío de mensaje Discord de extremo a extremo

bash

Iniciar OpenClaw con proxy

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

En otra terminal, enviar mensaje de prueba vía Discord

Enviar “!test” a tu bot

Verificar logs

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

Patrón de éxito esperado: log [INFO] Discord gateway connected via proxy [INFO] Received: !test [INFO] Sending reply via REST (proxied) [INFO] Reply sent successfully (200 OK)

Prueba 4: Verificar que no haya error fetch failed

bash

Después de la corrección, esto no debería aparecer

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

Esperado: Sin coincidencias (resultado vacío)

⚠️ Errores comunes

Error común 1: Mezclar protocolos de proxy HTTP/HTTPS

La API de Discord requiere HTTPS. Asegúrate de que tu configuración de proxy use HTTPS:

❌ Incorrecto✅ Correcto
http://127.0.0.1:7890/ para gatewayUsar para ambos (node maneja el upgrade)
Proxy SOCKS sin configuración de agenteInstalar socks-proxy-agent explícitamente

javascript // Para proxies SOCKS: const { SocksProxyAgent } = require(‘socks-proxy-agent’); const agent = new SocksProxyAgent(‘socks://127.0.0.1:1080’);

Error común 2: Alcance de variables de entorno

Las variables de entorno establecidas después del inicio del proceso no se aplican. Siempre establece antes de lanzar:

bash

✗ Incorrecto - vars no heredadas

openclaw start && export HTTP_PROXY="…"

✓ Correcto - vars establecidas antes del fork

HTTP_PROXY="…" openclaw start

Error común 3: Compatibilidad de versión de Node.js

https-proxy-agent@5+ requiere Node.js 18+. Para versiones anteriores:

bash node –version

Si < 18, usar: npm install https-proxy-agent@4

Error común 4: Autenticación de proxy no manejada

Si tu proxy requiere nombre de usuario y contraseña:

javascript const proxyUrl = ‘http://user:[email protected]:7890/’; // o const proxyUrl = ‘http://’ + encodeURIComponent(‘user’) + ‘:’ + encodeURIComponent(‘pass’) + ‘@127.0.0.1:7890/’;

Error común 5: Errores de certificado TLS

En algunas configuraciones de proxy, puede que necesites deshabilitar la verificación SSL para pruebas:

javascript process.env.NODE_TLS_REJECT_UNAUTHORIZED = ‘0’;

⚠️ Advertencia: Solo usar esto para depuración. Nunca en producción.

Error común 6: Aislamiento de proxy de contenedor Docker

Si ejecutas OpenClaw en Docker, el proxy debe ser accesible desde dentro del contenedor:

bash

✗ El contenedor no puede alcanzar el loopback del host

HTTP_PROXY=“http://127.0.0.1:7890”

✓ Usar red del host o docker.for.mac.localhost

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

Para Docker, añade --network=host o configura network_mode: host en docker-compose.

🔗 Errores relacionados

Patrones de errores lógicamente conectados

ErrorDescripciónRelacionado con
TypeError: fetch failedFallo de conexión de llamada RESTEste problema
ECONNREFUSEDServidor proxy no ejecutándoseDisponibilidad de red/proxy
ETIMEDOUTTiempo de conexión agotado a DiscordRed/firewall bloqueando
ENOTFOUNDNo puede resolver DNS de DiscordFiltrado DNS en regiones restringidas
Failed to connect to Discord gatewayFallo de inicialización WebSocketProxy no aplicado a cliente WS
Disconnected with code 1006Cierre anormal de WebSocketInestabilidad de red/proxy cayendo
Request timeoutSolicitud REST colgadaProxy lento/inestable

Contexto histórico

  • Issue #1423: Soporte de proxy WebSocket agregado para Discord gateway
  • Issue #1891: Descargas de medios/adjuntos omiten proxy
  • Issue #2156: Cliente carbon-request carece de API de inyección de agente

Patrones similares en otros canales

CanalTiene problema de proxy RESTAlternativa
Discord✅ Sí (este problema)Vars de entorno / parche de código
Slack⚠️ ParcialUsa node-fetch con agente
Teams❌ DesconocidoRequiere pruebas
Mattermost❌ DesconocidoRequiere pruebas

Evidencia y fuentes

Esta guía de solución de problemas fue sintetizada automáticamente por la tubería de inteligencia de FixClaw a partir de las discusiones de la comunidad.