From 247811330a2d9ea9066ecbd5a5bbfd4a1feb2f4d Mon Sep 17 00:00:00 2001 From: Jeroen Claassens Date: Tue, 13 May 2025 16:50:35 +0200 Subject: [PATCH 1/2] feat: add page about setting up with a proxy --- .../additional-info/proxy/14/rest-proxy.js | 10 ++ .../proxy/14/ws-proxy-loader.js | 15 +++ .../proxy/14/ws-proxy-setup.js | 28 +++++ guide/.vuepress/sidebar.ts | 1 + guide/additional-info/proxy.md | 111 ++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 code-samples/additional-info/proxy/14/rest-proxy.js create mode 100644 code-samples/additional-info/proxy/14/ws-proxy-loader.js create mode 100644 code-samples/additional-info/proxy/14/ws-proxy-setup.js create mode 100644 guide/additional-info/proxy.md diff --git a/code-samples/additional-info/proxy/14/rest-proxy.js b/code-samples/additional-info/proxy/14/rest-proxy.js new file mode 100644 index 000000000..3bb9847a7 --- /dev/null +++ b/code-samples/additional-info/proxy/14/rest-proxy.js @@ -0,0 +1,10 @@ +const { ProxyAgent } = require('undici'); +const { Client } = require('discord.js'); + +// eslint-disable-next-line no-unused-vars +const myClient = new Client({ + // other client options + rest: { + agent: new ProxyAgent('http://my-proxy-server:port'), + }, +}); diff --git a/code-samples/additional-info/proxy/14/ws-proxy-loader.js b/code-samples/additional-info/proxy/14/ws-proxy-loader.js new file mode 100644 index 000000000..eaa0c86b8 --- /dev/null +++ b/code-samples/additional-info/proxy/14/ws-proxy-loader.js @@ -0,0 +1,15 @@ +const { Client } = require('discord.js'); +const { NodeGlobalProxy } = require('./NodeGlobalProxy'); + +const proxy = new NodeGlobalProxy({ + http: 'http://my-proxy-server:port', + https: 'http://my-proxy-server:port', +}); + +proxy.start(); + +const client = new Client({ + // client options, including the proxy agent as described above +}); + +client.login('your-token-goes-here'); diff --git a/code-samples/additional-info/proxy/14/ws-proxy-setup.js b/code-samples/additional-info/proxy/14/ws-proxy-setup.js new file mode 100644 index 000000000..7490d46c9 --- /dev/null +++ b/code-samples/additional-info/proxy/14/ws-proxy-setup.js @@ -0,0 +1,28 @@ +const { bootstrap } = require('global-agent'); + +bootstrap(); + +class NodeGlobalProxy { + config = { + http: '', + https: '', + }; + + constructor(config) { + this.config = config; + } + + start() { + global.GLOBAL_AGENT.HTTP_PROXY = this.config.http; + global.GLOBAL_AGENT.HTTPS_PROXY = this.config.https; + } + + stop() { + global.GLOBAL_AGENT.HTTP_PROXY = null; + global.GLOBAL_AGENT.HTTPS_PROXY = null; + } +} + +module.exports = { + NodeGlobalProxy, +}; diff --git a/guide/.vuepress/sidebar.ts b/guide/.vuepress/sidebar.ts index f90da926b..96347dbe2 100644 --- a/guide/.vuepress/sidebar.ts +++ b/guide/.vuepress/sidebar.ts @@ -150,6 +150,7 @@ export default { '/additional-info/collections.md', '/additional-info/async-await.md', '/additional-info/rest-api.md', + '/additional-info/proxy.md', '/additional-info/changes-in-v13.md', '/additional-info/changes-in-v14.md', ], diff --git a/guide/additional-info/proxy.md b/guide/additional-info/proxy.md new file mode 100644 index 000000000..aea7a56c6 --- /dev/null +++ b/guide/additional-info/proxy.md @@ -0,0 +1,111 @@ +# Using a proxy with Discord.js + +It may be necessary to use a proxy when using Discord.js, for example when you are deploying your bot on a server that has a web filtering firewall that only allows outside traffic through the proxy. This guide will show you how to set up a proxy with Discord.js. + +A proxy for Discord.js requires 2 separate setups, one for REST and one for WebSocket. + +## Prerequisites + +In order to set up a proxy for Discord.js, you will need to install the following packages: + +:::: code-group +::: code-group-item npm + +```sh:no-line-numbers +npm install undici global-agent +``` + +::: +::: code-group-item yarn + +```sh:no-line-numbers +yarn add undici global-agent +``` + +::: +::: code-group-item pnpm + +```sh:no-line-numbers +pnpm add undici global-agent +``` + +::: +::: code-group-item bun + +```sh:no-line-numbers +bun add undici global-agent +``` + +::: +:::: + +## Setting up the proxy for REST calls + +To set up a proxy for REST calls, you should provide a custom `ProxyAgent` to the `Client` constructor. The `ProxyAgent` must be imported from the `undici` package, which is the package that `@discordjs/rest` uses to make HTTP requests. + +```js +const { ProxyAgent } = require('undici'); +const { Client } = require('discord.js'); + +const myClient = new Client({ + // other client options + rest: { + agent: new ProxyAgent('http://my-proxy-server:port'), + }, +}); +``` + +For further information on the `undici` `ProxyAgent`, please refer to the [undici documentation](https://undici.nodejs.org/#/docs/api/ProxyAgent.md). + +## Setting up the proxy for WebSocket + +To set up a proxy for WebSocket, you can use the `global-agent` package. You will need to provide some custom configuration to activate it: + +```js +const { bootstrap } = require('global-agent'); + +bootstrap(); + +class NodeGlobalProxy { + config = { + http: '', + https: '', + }; + + constructor(config) { + this.config = config; + } + + start() { + global.GLOBAL_AGENT.HTTP_PROXY = this.config.http; + global.GLOBAL_AGENT.HTTPS_PROXY = this.config.https; + } + + stop() { + global.GLOBAL_AGENT.HTTP_PROXY = null; + global.GLOBAL_AGENT.HTTPS_PROXY = null; + } +} + +module.exports = { + NodeGlobalProxy, +}; +``` + +Now in the file where you create your client, you can import the `NodeGlobalProxy` class and start it with the proxy URL: + +```js +const { Client } = require('discord.js'); +const { NodeGlobalProxy } = require('./NodeGlobalProxy'); + +const proxy = new NodeGlobalProxy({ + http: 'http://my-proxy-server:port', + https: 'http://my-proxy-server:port', +}); +proxy.start(); +const client = new Client({ + // client options, including the proxy agent as described above +}); + +client.login('your-token-goes-here'); +``` From d60f028ba52de516831fc404ed45781b2c9ea9e4 Mon Sep 17 00:00:00 2001 From: Jeroen Claassens Date: Tue, 13 May 2025 17:06:22 +0200 Subject: [PATCH 2/2] fix: properly implement ResultingCode and add vuepress styling --- .../additional-info/proxy/14/index.js | 43 +++++++++++++++++++ .../additional-info/proxy/14/rest-proxy.js | 10 ----- .../proxy/14/ws-proxy-loader.js | 15 ------- .../proxy/14/ws-proxy-setup.js | 28 ------------ guide/additional-info/proxy.md | 14 ++++-- 5 files changed, 54 insertions(+), 56 deletions(-) create mode 100644 code-samples/additional-info/proxy/14/index.js delete mode 100644 code-samples/additional-info/proxy/14/rest-proxy.js delete mode 100644 code-samples/additional-info/proxy/14/ws-proxy-loader.js delete mode 100644 code-samples/additional-info/proxy/14/ws-proxy-setup.js diff --git a/code-samples/additional-info/proxy/14/index.js b/code-samples/additional-info/proxy/14/index.js new file mode 100644 index 000000000..89338325d --- /dev/null +++ b/code-samples/additional-info/proxy/14/index.js @@ -0,0 +1,43 @@ +const { ProxyAgent } = require('undici'); +const { Client } = require('discord.js'); +const { bootstrap } = require('global-agent'); + +bootstrap(); + +class NodeGlobalProxy { + config = { + http: '', + https: '', + }; + + constructor(config) { + this.config = config; + } + + start() { + global.GLOBAL_AGENT.HTTP_PROXY = this.config.http; + global.GLOBAL_AGENT.HTTPS_PROXY = this.config.https; + } + + stop() { + global.GLOBAL_AGENT.HTTP_PROXY = null; + global.GLOBAL_AGENT.HTTPS_PROXY = null; + } +} + +const proxy = new NodeGlobalProxy({ + http: 'http://my-proxy-server:port', + https: 'http://my-proxy-server:port', +}); + +proxy.start(); + +// eslint-disable-next-line no-unused-vars +const client = new Client({ + // other client options + rest: { + agent: new ProxyAgent('http://my-proxy-server:port'), + }, +}); + +client.login('your-token-goes-here'); diff --git a/code-samples/additional-info/proxy/14/rest-proxy.js b/code-samples/additional-info/proxy/14/rest-proxy.js deleted file mode 100644 index 3bb9847a7..000000000 --- a/code-samples/additional-info/proxy/14/rest-proxy.js +++ /dev/null @@ -1,10 +0,0 @@ -const { ProxyAgent } = require('undici'); -const { Client } = require('discord.js'); - -// eslint-disable-next-line no-unused-vars -const myClient = new Client({ - // other client options - rest: { - agent: new ProxyAgent('http://my-proxy-server:port'), - }, -}); diff --git a/code-samples/additional-info/proxy/14/ws-proxy-loader.js b/code-samples/additional-info/proxy/14/ws-proxy-loader.js deleted file mode 100644 index eaa0c86b8..000000000 --- a/code-samples/additional-info/proxy/14/ws-proxy-loader.js +++ /dev/null @@ -1,15 +0,0 @@ -const { Client } = require('discord.js'); -const { NodeGlobalProxy } = require('./NodeGlobalProxy'); - -const proxy = new NodeGlobalProxy({ - http: 'http://my-proxy-server:port', - https: 'http://my-proxy-server:port', -}); - -proxy.start(); - -const client = new Client({ - // client options, including the proxy agent as described above -}); - -client.login('your-token-goes-here'); diff --git a/code-samples/additional-info/proxy/14/ws-proxy-setup.js b/code-samples/additional-info/proxy/14/ws-proxy-setup.js deleted file mode 100644 index 7490d46c9..000000000 --- a/code-samples/additional-info/proxy/14/ws-proxy-setup.js +++ /dev/null @@ -1,28 +0,0 @@ -const { bootstrap } = require('global-agent'); - -bootstrap(); - -class NodeGlobalProxy { - config = { - http: '', - https: '', - }; - - constructor(config) { - this.config = config; - } - - start() { - global.GLOBAL_AGENT.HTTP_PROXY = this.config.http; - global.GLOBAL_AGENT.HTTPS_PROXY = this.config.https; - } - - stop() { - global.GLOBAL_AGENT.HTTP_PROXY = null; - global.GLOBAL_AGENT.HTTPS_PROXY = null; - } -} - -module.exports = { - NodeGlobalProxy, -}; diff --git a/guide/additional-info/proxy.md b/guide/additional-info/proxy.md index aea7a56c6..2677bc542 100644 --- a/guide/additional-info/proxy.md +++ b/guide/additional-info/proxy.md @@ -43,7 +43,7 @@ bun add undici global-agent To set up a proxy for REST calls, you should provide a custom `ProxyAgent` to the `Client` constructor. The `ProxyAgent` must be imported from the `undici` package, which is the package that `@discordjs/rest` uses to make HTTP requests. -```js +```js {6-8} const { ProxyAgent } = require('undici'); const { Client } = require('discord.js'); @@ -55,13 +55,15 @@ const myClient = new Client({ }); ``` +:::tip For further information on the `undici` `ProxyAgent`, please refer to the [undici documentation](https://undici.nodejs.org/#/docs/api/ProxyAgent.md). +::: ## Setting up the proxy for WebSocket To set up a proxy for WebSocket, you can use the `global-agent` package. You will need to provide some custom configuration to activate it: -```js +```js {1-24} const { bootstrap } = require('global-agent'); bootstrap(); @@ -94,7 +96,7 @@ module.exports = { Now in the file where you create your client, you can import the `NodeGlobalProxy` class and start it with the proxy URL: -```js +```js {2,4-7,9} const { Client } = require('discord.js'); const { NodeGlobalProxy } = require('./NodeGlobalProxy'); @@ -102,10 +104,16 @@ const proxy = new NodeGlobalProxy({ http: 'http://my-proxy-server:port', https: 'http://my-proxy-server:port', }); + proxy.start(); + const client = new Client({ // client options, including the proxy agent as described above }); client.login('your-token-goes-here'); ``` + +## Resulting code + +