已设置Webhook的Telegram Bot无响应问题求助
核心问题分析
你的Bot无响应的根源是代码存在多个关键错误,导致Webhook无法正常处理Telegram的请求:
1. 未处理Telegram Webhook的验证请求
Telegram设置Webhook时会发送GET请求,携带hub.challenge参数,你的代码只处理了POST请求,直接返回错误响应,导致Webhook实际未成功激活。
2. 错误解析Telegram的请求结构
Telegram推送的消息JSON里,text字段并非直接在根节点,而是嵌套在message.text(或edited_message.text)中,你直接const { text } = await request.json()会得到undefined,所有命令判断逻辑都无法触发。
3. Cloudflare Worker环境下Cheerio引入错误
Worker是ES模块环境,不能用require('cheerio'),必须用ES模块导入,且需确保使用兼容Worker的Cheerio版本。
4. 无错误捕获机制
所有异步操作(网络请求、页面解析)都没有错误捕获,Worker会静默失败,你看不到任何报错信息。
5. 未校验Telegram API的发送结果
sendMessageToChatId函数发送消息后未检查响应状态,即使令牌、Chat ID错误也无法察觉。
修复后的完整代码
import * as cheerio from 'cheerio'; addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const { pathname, searchParams } = new URL(request.url); // 处理Telegram Webhook验证请求 if (request.method === 'GET') { const challenge = searchParams.get('hub.challenge'); if (challenge) { return new Response(challenge, { status: 200 }); } return new Response('Hello! This is a Telegram bot.', { status: 200 }); } // 处理POST消息请求 if (request.method !== 'POST') { return new Response('Method Not Allowed', { status: 405 }); } try { const update = await request.json(); // 提取消息文本,兼容普通消息和编辑后的消息 const text = update.message?.text || update.edited_message?.text; if (!text) { return new Response('No text found in request', { status: 200 }); } if (text.startsWith('/start')) { return new Response('Welcome to the bot! Use the /help command to see available options.'); } else if (text.startsWith('/help')) { return new Response('Available commands:\n/scrape - 抓取指定网站的最新视频并发送到聊天\n/example - 抓取指定网站的最新文章并发送到聊天'); } else if (text.startsWith('/scrape')) { const videoUrl = await scrapeVideoUrl('你的目标网站URL'); if (!videoUrl) { throw new Error('Failed to scrape video URL'); } const message = `最新视频链接:${videoUrl}`; await sendMessageToChatId(message); return new Response('OK'); } else if (text.startsWith('/example')) { const post = await scrapePost('你的目标网站URL'); if (!post?.title) { throw new Error('Failed to scrape post'); } const message = `最新文章:${post.title}\n链接:${post.url}`; await sendMessageToChatId(message); return new Response('OK'); } else { return new Response('无效命令,使用/help查看可用命令'); } } catch (error) { // 打印错误到Worker日志,方便排查 console.error('Error handling request:', error); return new Response('Internal Server Error', { status: 500 }); } } async function scrapeVideoUrl(url) { try { const response = await fetch(url, { // 添加User-Agent,避免被目标网站拦截 headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } }); if (!response.ok) { throw new Error(`Failed to fetch ${url}: ${response.status}`); } const html = await response.text(); const $ = cheerio.load(html); const videoUrl = $('div.media > a').attr('href'); // 处理相对URL return videoUrl ? new URL(videoUrl, url).href : null; } catch (error) { console.error('Error scraping video URL:', error); throw error; } } async function scrapePost(url) { try { const response = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } }); if (!response.ok) { throw new Error(`Failed to fetch ${url}: ${response.status}`); } const html = await response.text(); const $ = cheerio.load(html); return { title: $('div.content h1').text().trim(), url: url }; } catch (error) { console.error('Error scraping post:', error); throw error; } } async function sendMessageToChatId(message) { const telegramApiUrl = "https://api.telegram.org/bot你的Bot令牌/sendMessage"; const chatId = "你的聊天ID"; try { const response = await fetch(telegramApiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chat_id: chatId, text: message }) }); const result = await response.json(); if (!result.ok) { throw new Error(`Telegram API error: ${result.description}`); } } catch (error) { console.error('Error sending message:', error); throw error; } }
额外配置步骤
在Cloudflare Worker中添加Cheerio依赖:
- 进入Worker的"Settings" -> "Variables" -> "Environment Variables",点击"Add variable"
- 选择"Add binding" -> "Module",输入名称
cheerio,选择对应的Cheerio模块(版本选1.0.0-rc.12及以上)
重新设置Webhook:
用浏览器访问以下链接(替换你的Bot令牌和Worker域名):https://api.telegram.org/bot你的Bot令牌/setWebhook?url=https://你的Worker域名.workers.dev确认返回
{"ok":true,"result":true,"description":"Webhook was set"}即为成功。查看Worker日志:
在Cloudflare Worker的"Logs"页面查看实时日志,若有错误会在这里显示,方便进一步排查。
内容的提问来源于stack exchange,提问作者user21239393

