PLUTON\igor.kreyda commited on
Commit
e9ebe66
·
1 Parent(s): 1f9b2b7

fix: implement DNS-over-HTTPS (DoH) to bypass local resolver issues

Browse files
Files changed (1) hide show
  1. app/bot/bot.js +57 -18
app/bot/bot.js CHANGED
@@ -4,6 +4,48 @@
4
  */
5
 
6
  const { Telegraf, Markup } = require('telegraf');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  // This function will be called from index.js
9
  function setupBot(token, webAppUrl) {
@@ -11,28 +53,31 @@ function setupBot(token, webAppUrl) {
11
  throw new Error('BOT_TOKEN is missing!');
12
  }
13
 
14
- // --- CUSTOM DNS RESOLUTION FIX ---
15
- // Hugging Face Spaces often fails to resolve api.telegram.org via system DNS.
16
- // We will manually resolve it using Google DNS (8.8.8.8) and force Telegraf to use the IP.
17
-
18
- const https = require('https');
19
- const dns = require('dns');
20
-
21
  const botOptions = {};
22
 
23
  // Only apply this fix in production (on Hugging Face)
24
  if (process.env.NODE_ENV === 'production') {
25
- console.log('[Bot] Production mode: Forcing custom DNS resolution for Telegram.');
26
 
27
  const agent = new https.Agent({
28
  keepAlive: true,
29
  family: 4,
30
- lookup: (hostname, options, callback) => {
 
31
  if (hostname === 'api.telegram.org') {
32
- // console.log(`[Bot] Resolving ${hostname} to fixed IP.`);
33
- return callback(null, '149.154.167.220', 4);
 
 
 
 
 
 
 
34
  }
35
- dns.lookup(hostname, options, callback);
 
 
36
  }
37
  });
38
 
@@ -43,9 +88,6 @@ function setupBot(token, webAppUrl) {
43
  const bot = new Telegraf(token, botOptions);
44
 
45
  // Initial setup for the menu button
46
- // Note: setChatMenuButton might need to be called on specific user interaction or globally once logic is decided.
47
- // For now, let's put it in the start command to ensure it updates for the user.
48
-
49
  bot.start(async (ctx) => {
50
  const welcomeMessage = `
51
  Привет! Я AI Post Generator Bot. 🤖
@@ -55,8 +97,6 @@ function setupBot(token, webAppUrl) {
55
  `;
56
 
57
  try {
58
- // Set the persistent Menu Button (bottom left of chat input)
59
- // This button opens the Web App directly.
60
  await ctx.setChatMenuButton({
61
  type: 'web_app',
62
  text: 'Настройки',
@@ -67,7 +107,6 @@ function setupBot(token, webAppUrl) {
67
  console.error('Failed to set menu button:', e);
68
  }
69
 
70
- // Send a message with an inline button as well
71
  await ctx.reply(welcomeMessage, Markup.inlineKeyboard([
72
  Markup.button.webApp('Открыть настройки ⚙️', `${webAppUrl}/app/index.html`)
73
  ]));
 
4
  */
5
 
6
  const { Telegraf, Markup } = require('telegraf');
7
+ const https = require('https');
8
+
9
+ // Helper function: Resolve IP via Google DNS-over-HTTPS
10
+ // This bypasses local system DNS (UDP:53) which is often blocked on free hosting.
11
+ async function resolveDoH(hostname) {
12
+ return new Promise((resolve, reject) => {
13
+ const options = {
14
+ hostname: 'dns.google',
15
+ port: 443,
16
+ path: `/resolve?name=${hostname}&type=A`,
17
+ method: 'GET',
18
+ headers: { 'Accept': 'application/dns-json' }
19
+ };
20
+
21
+ const req = https.request(options, (res) => {
22
+ let data = '';
23
+ res.on('data', (chunk) => { data += chunk; });
24
+ res.on('end', () => {
25
+ try {
26
+ const json = JSON.parse(data);
27
+ // Check if Answer exists and has data
28
+ if (json.Answer && json.Answer.length > 0) {
29
+ // Return the first IP address found
30
+ console.log(`[DNS-over-HTTPS] Resolved ${hostname} to ${json.Answer[0].data}`);
31
+ resolve(json.Answer[0].data);
32
+ } else {
33
+ reject(new Error('No DNS Answer found'));
34
+ }
35
+ } catch (e) {
36
+ reject(e);
37
+ }
38
+ });
39
+ });
40
+
41
+ req.on('error', (e) => {
42
+ console.error('[DNS-over-HTTPS] Request failed:', e);
43
+ reject(e);
44
+ });
45
+ req.end();
46
+ });
47
+ }
48
+
49
 
50
  // This function will be called from index.js
51
  function setupBot(token, webAppUrl) {
 
53
  throw new Error('BOT_TOKEN is missing!');
54
  }
55
 
 
 
 
 
 
 
 
56
  const botOptions = {};
57
 
58
  // Only apply this fix in production (on Hugging Face)
59
  if (process.env.NODE_ENV === 'production') {
60
+ console.log('[Bot] Production mode: Configuring DNS-over-HTTPS agent.');
61
 
62
  const agent = new https.Agent({
63
  keepAlive: true,
64
  family: 4,
65
+ lookup: async (hostname, options, callback) => {
66
+ // Only intercept api.telegram.org
67
  if (hostname === 'api.telegram.org') {
68
+ try {
69
+ const ip = await resolveDoH('api.telegram.org');
70
+ return callback(null, ip, 4);
71
+ } catch (err) {
72
+ console.error('[Bot] DoH failed, falling back to system DNS:', err);
73
+ // Fallback to system DNS if DoH fails (unlikely if outbound HTTPS works)
74
+ const dns = require('dns');
75
+ return dns.lookup(hostname, options, callback);
76
+ }
77
  }
78
+ // Default behavior for other domains
79
+ const dns = require('dns');
80
+ return dns.lookup(hostname, options, callback);
81
  }
82
  });
83
 
 
88
  const bot = new Telegraf(token, botOptions);
89
 
90
  // Initial setup for the menu button
 
 
 
91
  bot.start(async (ctx) => {
92
  const welcomeMessage = `
93
  Привет! Я AI Post Generator Bot. 🤖
 
97
  `;
98
 
99
  try {
 
 
100
  await ctx.setChatMenuButton({
101
  type: 'web_app',
102
  text: 'Настройки',
 
107
  console.error('Failed to set menu button:', e);
108
  }
109
 
 
110
  await ctx.reply(welcomeMessage, Markup.inlineKeyboard([
111
  Markup.button.webApp('Открыть настройки ⚙️', `${webAppUrl}/app/index.html`)
112
  ]));