somratpro commited on
Commit
9c5c64a
Β·
1 Parent(s): 1a290be

fix: revert Telegram SNI workaround and restore proper dns-fix.js behavior

Browse files

- HF Spaces blocks standard UDP DNS for some domains (like Telegram) by returning ENOTFOUND.
- The previous attempt forced DoH first via cloudflare-dns.com, but standard DNS resolution for cloudflare-dns.com itself failed inside HF Spaces, causing the entire DoH fallback to crash with ECONNRESET.
- Restored the original HuggingClaw logic: try system DNS first, and if it fails (ENOTFOUND), fallback to DoH using the direct IP '1.1.1.1' which bypasses system DNS entirely.
- Reverted README and DISCORD_PROXY_GUIDE.md since Telegram is NOT blocked by HF TLS/SNI and works natively once DNS is fixed.

Files changed (3) hide show
  1. DISCORD_PROXY_GUIDE.md +23 -45
  2. README.md +3 -3
  3. dns-fix.js +23 -25
DISCORD_PROXY_GUIDE.md CHANGED
@@ -1,67 +1,45 @@
1
- # πŸ› οΈ Bypassing Hugging Face Network Restrictions
2
 
3
- Hugging Face Free Tier Spaces block outgoing connections to certain messaging platforms (**Discord** and **Telegram**) via **TLS/SNI inspection**. This means the TCP connection is allowed, but the TLS handshake is silently dropped as soon as HF detects the target hostname (e.g., `discord.com`, `api.telegram.org`) in the SNI field.
4
 
5
- The fix is to route your traffic through a **Cloudflare Worker proxy** with a neutral hostname. Since the SNI in the TLS handshake will show `your-proxy.workers.dev` instead of the blocked hostname, HF's filter won't block it. Cloudflare Workers are **100% free** (100,000 requests/day).
6
 
7
- ---
8
-
9
- ## Setting Up a Cloudflare Worker Proxy
10
 
11
- This process takes about 2 minutes and works for both Discord and Telegram.
12
 
13
  ### Step 1: Create a Cloudflare Worker
14
- 1. Log into [Cloudflare](https://dash.cloudflare.com/) (create a free account if needed).
15
- 2. Go to **Workers & Pages** in the left sidebar.
16
- 3. Click **Create Worker** β†’ **Start with Hello World!**.
17
- 4. Give it a name (e.g., `discord-proxy` or `telegram-proxy`) and click **Deploy**.
18
 
19
  ### Step 2: Add the Proxy Code
20
- 1. Click **Edit Code**.
21
- 2. Delete all existing code and paste the following snippet.
22
- 3. Replace `TARGET_HOSTNAME` with the service you want to proxy (see table below).
23
 
24
  ```javascript
25
  export default {
26
  async fetch(request) {
27
  const url = new URL(request.url);
28
- url.hostname = 'TARGET_HOSTNAME';
29
  return fetch(new Request(url, request));
30
  }
31
  }
32
  ```
33
 
34
- | Service | Replace `TARGET_HOSTNAME` with |
35
- | :--- | :--- |
36
- | Discord | `discord.com` |
37
- | Telegram | `api.telegram.org` |
38
-
39
- 4. Click **Save and Deploy**. Cloudflare gives you a URL like `https://your-proxy.yourname.workers.dev`.
40
-
41
- ---
42
 
43
- ## Using the Proxy in n8n
 
44
 
45
- ### Discord
46
- The native n8n Discord node uses Bot tokens that hardcode `discord.com`. Use the **Webhook** authentication method instead:
47
-
48
- 1. Add a **Discord** node and set the **Credential** to use **Webhook** authentication.
49
- 2. Create a new Discord Webhook credential.
50
- 3. Take your Discord Webhook URL and replace `discord.com` with your Worker domain:
51
- - *Original:* `https://discord.com/api/webhooks/123456/abcdef`
52
- - *Proxied:* `https://discord-proxy.yourname.workers.dev/api/webhooks/123456/abcdef`
53
- 4. Paste the proxied URL in the **Webhook URL** field.
54
-
55
- ### Telegram
56
- The n8n Telegram credential has a **Base URL** field that can be changed:
57
-
58
- 1. Go to **Credentials** β†’ add or edit a **Telegram** credential.
59
- 2. Enter your Bot Token as usual.
60
- 3. In the **Base URL** field, replace `https://api.telegram.org` with your Worker URL:
61
- - *Original:* `https://api.telegram.org`
62
- - *Proxied:* `https://telegram-proxy.yourname.workers.dev`
63
- 4. Click **Save** and then **Test** β€” it should connect instantly.
64
 
65
  ---
66
-
67
- *Note: Upgrading your Hugging Face Space to a paid hardware tier removes these network restrictions entirely, allowing you to use all n8n nodes natively without a proxy.*
 
1
+ # πŸ› οΈ How to Create a Free Discord Proxy
2
 
3
+ Hugging Face officially blocks outgoing connections to Discord's IP addresses on Free Tier Spaces to prevent spam. While our built-in DNS script cleanly bypasses blocks for Telegram and WhatsApp, Discord is blocked at the physical IP firewall level.
4
 
5
+ This means the native n8n "Discord" node will always hang and fail with a "Connection closed unexpectedly" error.
6
 
7
+ To work around this, you can easily create your own private Discord proxy using Cloudflare Workers. It takes about 2 minutes and is 100% free (allowing up to 100,000 requests per day).
 
 
8
 
9
+ ## Step-by-Step Guide
10
 
11
  ### Step 1: Create a Cloudflare Worker
12
+ 1. Log into [Cloudflare](https://dash.cloudflare.com/) (create an account if you don't have one).
13
+ 2. On the left sidebar, go to **Workers & Pages**.
14
+ 3. Click **Create Worker** -> **Start with Hello World!**.
15
+ 4. Name it something memorable, like `discord-proxy`, and click **Deploy**.
16
 
17
  ### Step 2: Add the Proxy Code
18
+ 1. Once deployed, click the **Edit Code** button.
19
+ 2. In the online code editor, delete the existing code and replace it entirely with this 6-line snippet:
 
20
 
21
  ```javascript
22
  export default {
23
  async fetch(request) {
24
  const url = new URL(request.url);
25
+ url.hostname = 'discord.com';
26
  return fetch(new Request(url, request));
27
  }
28
  }
29
  ```
30
 
31
+ 3. Click **Save and Deploy** in the top right corner. Cloudflare will generate a unique URL for you (e.g., `https://discord-proxy.yourname.workers.dev`).
 
 
 
 
 
 
 
32
 
33
+ ### Step 3: Use the Proxy in n8n
34
+ Because the native Discord Node hardcodes connections to `discord.com` when using Bot tokens, you must use the **Webhook** method.
35
 
36
+ 1. Add the standard **Discord** node to your n8n workflow.
37
+ 2. Under "Authentication", select **Webhook**.
38
+ 3. Take your normal Discord Webhook URL and replace `discord.com` with your new worker domain.
39
+ * *Original:* `https://discord.com/api/webhooks/123456/abcdef`
40
+ * *New:* `https://discord-proxy.yourname.workers.dev/api/webhooks/123456/abcdef`
41
+ 4. Create a new Discord Webhook Credential in n8n and paste that **New URL** into the "Webhook URL" field.
42
+ 5. Setup your message (e.g., set the text to "Hello World") and click **Execute Node**. Your message will instantly appear in Discord!
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  ---
45
+ *Note: If you ever upgrade your Hugging Face Space to a paid hardware tier, the outgoing firewall restriction is removed, and you can go back to using the native n8n Discord node directly!*
 
README.md CHANGED
@@ -68,10 +68,10 @@ Hugging8n automatically creates and maintains a private dataset in your Hugging
68
 
69
  ## ⚠️ Known Limitations & Workarounds
70
 
71
- **Discord & Telegram Webhooks Blocked by Hugging Face**
72
- Hugging Face blocks outgoing connections to Discord and Telegram on Free Tier Spaces via TLS/SNI inspection β€” the TCP connection opens but the TLS handshake is silently dropped when the target hostname is detected. To use these services, you must route traffic through a proxy with a different hostname.
73
 
74
- πŸ‘‰ **[Read the Guide: How to Create a Free Cloudflare Proxy in 2 minutes](./DISCORD_PROXY_GUIDE.md)**
75
  *(Upgrading to a paid Space removes this firewall restriction entirely).*
76
 
77
  ## πŸ—οΈ Architecture
 
68
 
69
  ## ⚠️ Known Limitations & Workarounds
70
 
71
+ **Discord Webhooks**
72
+ Hugging Face officially blocks outgoing connections to Discord on Free Tier Spaces. To use the Discord node, you must route your traffic through a simple, free proxy.
73
 
74
+ πŸ‘‰ **[Read the Guide: How to Create a Free Discord Proxy in 2 minutes](./DISCORD_PROXY_GUIDE.md)**
75
  *(Upgrading to a paid Space removes this firewall restriction entirely).*
76
 
77
  ## πŸ—οΈ Architecture
dns-fix.js CHANGED
@@ -2,8 +2,8 @@
2
  * DNS fix preload script for HF Spaces.
3
  *
4
  * Patches Node.js dns.lookup to:
5
- * 1. Try DNS-over-HTTPS (Cloudflare) first to bypass DNS sinkholing
6
- * 2. Fall back to system DNS if DoH fails
7
  * (This is needed because HF Spaces intercepts/blocks some domains like
8
  * WhatsApp web or Telegram API via standard UDP DNS).
9
  *
@@ -11,18 +11,9 @@
11
  */
12
  "use strict";
13
 
14
- console.error("[DNS-FIX] Loaded β€” DoH-first resolver + keep-alive patch active.");
15
-
16
  const dns = require("dns");
17
- const http = require("http");
18
  const https = require("https");
19
 
20
- // ── Keep-Alive Fix ────────────────────────────────────────────────────────────
21
- http.globalAgent = new http.Agent({ keepAlive: false });
22
- https.globalAgent = new https.Agent({ keepAlive: false });
23
- // ─────────────────────────────────────────────────────────────────────────────
24
-
25
-
26
  // In-memory cache for runtime DoH resolutions
27
  const runtimeCache = new Map(); // hostname -> { ip, expiry }
28
 
@@ -34,7 +25,7 @@ function dohResolve(hostname, callback) {
34
  return callback(null, cached.ip);
35
  }
36
 
37
- const url = `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(hostname)}&type=A`;
38
  const req = https.get(
39
  url,
40
  { headers: { Accept: "application/dns-json" }, timeout: 15000 },
@@ -87,24 +78,31 @@ dns.lookup = function patchedLookup(hostname, options, callback) {
87
  hostname === "127.0.0.1" ||
88
  hostname === "::1" ||
89
  /^\d+\.\d+\.\d+\.\d+$/.test(hostname) ||
90
- /^::/.test(hostname) ||
91
- hostname === "cloudflare-dns.com"
92
  ) {
93
  return origLookup.call(dns, hostname, options, callback);
94
  }
95
 
96
- // 1) Try DoH first to bypass HF DNS sinkholing (which returns fake IPs instead of ENOTFOUND)
97
- dohResolve(hostname, (dohErr, ip) => {
98
- if (!dohErr && ip) {
99
- if (options.all) {
100
- return callback(null, [{ address: ip, family: 4 }]);
101
- }
102
- return callback(null, ip, 4);
103
  }
104
 
105
- console.error(`[DNS-FIX] DoH failed for ${hostname}:`, dohErr ? dohErr.message : "no IP returned");
106
-
107
- // 2) Fall back to system DNS if DoH fails
108
- origLookup.call(dns, hostname, options, callback);
 
 
 
 
 
 
 
 
 
 
 
109
  });
110
  };
 
2
  * DNS fix preload script for HF Spaces.
3
  *
4
  * Patches Node.js dns.lookup to:
5
+ * 1. Try system DNS first
6
+ * 2. Fall back to DNS-over-HTTPS (Cloudflare) if system DNS fails
7
  * (This is needed because HF Spaces intercepts/blocks some domains like
8
  * WhatsApp web or Telegram API via standard UDP DNS).
9
  *
 
11
  */
12
  "use strict";
13
 
 
 
14
  const dns = require("dns");
 
15
  const https = require("https");
16
 
 
 
 
 
 
 
17
  // In-memory cache for runtime DoH resolutions
18
  const runtimeCache = new Map(); // hostname -> { ip, expiry }
19
 
 
25
  return callback(null, cached.ip);
26
  }
27
 
28
+ const url = `https://1.1.1.1/dns-query?name=${encodeURIComponent(hostname)}&type=A`;
29
  const req = https.get(
30
  url,
31
  { headers: { Accept: "application/dns-json" }, timeout: 15000 },
 
78
  hostname === "127.0.0.1" ||
79
  hostname === "::1" ||
80
  /^\d+\.\d+\.\d+\.\d+$/.test(hostname) ||
81
+ /^::/.test(hostname)
 
82
  ) {
83
  return origLookup.call(dns, hostname, options, callback);
84
  }
85
 
86
+ // 1) Try system DNS first
87
+ origLookup.call(dns, hostname, options, (err, address, family) => {
88
+ if (!err && address) {
89
+ return callback(null, address, family);
 
 
 
90
  }
91
 
92
+ // 2) System DNS failed with ENOTFOUND or EAI_AGAIN β€” fall back to DoH
93
+ if (err && (err.code === "ENOTFOUND" || err.code === "EAI_AGAIN")) {
94
+ dohResolve(hostname, (dohErr, ip) => {
95
+ if (dohErr || !ip) {
96
+ return callback(err); // Return original error
97
+ }
98
+ if (options.all) {
99
+ return callback(null, [{ address: ip, family: 4 }]);
100
+ }
101
+ callback(null, ip, 4);
102
+ });
103
+ } else {
104
+ // Other DNS errors β€” pass through
105
+ callback(err, address, family);
106
+ }
107
  });
108
  };