What is the proper way to use discord.js with proxy server?

I want to run my Discord bot using a different IP address for both HTTP (REST API) and WebSocket (WSS) connections — so that all outbound traffic from the bot is routed through a specific proxy. So far I have such simple configuration:
import "dotenv/config";
import { setGlobalDispatcher, ProxyAgent } from "undici";
import { Client, GatewayIntentBits } from "discord.js";

setGlobalDispatcher(new ProxyAgent(process.env.PROXY_URL!));

const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});

client.once("ready", () => {
console.log(`Logged in as ${client.user?.tag}`);
});

client.login(process.env.DISCORD_TOKEN);
import "dotenv/config";
import { setGlobalDispatcher, ProxyAgent } from "undici";
import { Client, GatewayIntentBits } from "discord.js";

setGlobalDispatcher(new ProxyAgent(process.env.PROXY_URL!));

const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});

client.once("ready", () => {
console.log(`Logged in as ${client.user?.tag}`);
});

client.login(process.env.DISCORD_TOKEN);
But it gives me timeout error (or doesn't output anything):
i113861615:cards doctor8296$ npx ts-node src/bot.ts
/Users/doctor8296/cards/node_modules/ws/lib/websocket.js:873
abortHandshake(websocket, req, 'Opening handshake has timed out');
^
Error: Opening handshake has timed out
at ClientRequest.<anonymous> (/Users/doctor8296/cards/node_modules/ws/lib/websocket.js:873:7)
at ClientRequest.emit (node:events:518:28)
at ClientRequest.emit (node:domain:489:12)
at TLSSocket.emitRequestTimeout (node:_http_client:851:9)
at Object.onceWrapper (node:events:632:28)
at TLSSocket.emit (node:events:518:28)
at TLSSocket.emit (node:domain:489:12)
at TLSSocket.Socket._onTimeout (node:net:595:8)
at listOnTimeout (node:internal/timers:594:17)
at processTimers (node:internal/timers:529:7)
i113861615:cards doctor8296$ npx ts-node src/bot.ts
/Users/doctor8296/cards/node_modules/ws/lib/websocket.js:873
abortHandshake(websocket, req, 'Opening handshake has timed out');
^
Error: Opening handshake has timed out
at ClientRequest.<anonymous> (/Users/doctor8296/cards/node_modules/ws/lib/websocket.js:873:7)
at ClientRequest.emit (node:events:518:28)
at ClientRequest.emit (node:domain:489:12)
at TLSSocket.emitRequestTimeout (node:_http_client:851:9)
at Object.onceWrapper (node:events:632:28)
at TLSSocket.emit (node:events:518:28)
at TLSSocket.emit (node:domain:489:12)
at TLSSocket.Socket._onTimeout (node:net:595:8)
at listOnTimeout (node:internal/timers:594:17)
at processTimers (node:internal/timers:529:7)
node version: v22.11.0 discord.js: ^14.18.0, My proxy has http(s) type. It is indeed working. I have successfully requested main discord page through my proxy with https.
5 Replies
d.js toolkit
d.js toolkit3w ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
doctor8296
doctor8296OP3w ago
Hi! I'm not very experienced yet, but I suspect the bot needs to use WebSocket to function fully. In that case - yes. I need to proxify webscoket connection as well.
doctor8296
doctor8296OP3w ago
As far as I know, if HTTPS is supported, then WSS should be supported as well (depends on proxy provider, but most of the times works that way). I even wrote a small code snippet to verify that WebSocket works correctly with my proxy:
import WebSocket from "ws";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("...");
const ws = new WebSocket("wss://gateway.discord.gg/?v=10&encoding=json", { agent });
ws.on("open", () => {
console.log("Success.");
ws.close();
});
ws.on("error", (err) => {
console.error("Failed:", err.message);
});
import WebSocket from "ws";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("...");
const ws = new WebSocket("wss://gateway.discord.gg/?v=10&encoding=json", { agent });
ws.on("open", () => {
console.log("Success.");
ws.close();
});
ws.on("error", (err) => {
console.error("Failed:", err.message);
});
Success was the result.
No description
.Bunnys
.Bunnys3w ago
the WSS connection may not be routed correctly through the proxy using undici bec undici handles HTTP traffic not WebSockets i think, the handshake timeout error indicates that the websocket connection to discord is being blocked but also consider these: - timeouts - prooxy config => make sure that ur proxy supports websocket tunneling, most HTTPS proxies do but there could be cases where some configs / restrictions prevent websocket connections Correct me if I'm wrong
skyhan
skyhan3w ago
I use proxychains for this. just run the bot with this: proxychains4 -q -f /path/to/proxychains4/config.conf node index.js. all requests coming out of this process including websocket will automatically use the configured proxy server sample from one of my proxychain configurations:
strict_chain
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
http proxy_ip_here proxy_port_here
strict_chain
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
http proxy_ip_here proxy_port_here

Did you find this page helpful?