基于Google Apps Script的Telegram Bot无消息响应问题求助
问题概述
我用Google Apps Script开发的Telegram Bot无法正常工作,耗时5小时调试无果。具体表现为Bot完全不发送消息,但如果把sendMessage方法里的聊天ID硬编码成我的ID,直接点击执行按钮调用就能正常发送。
我怀疑问题出在doPost()方法上,已经尝试过重新设置Webhook(先delete再set)、简化代码只保留doPost和带固定ID的sendMessage(依然无效),查过文档和资料还是定位不了问题。
原代码
var apiToken = "token"; var appUrl = "https://script.google.com/macros/s/link/exec"; var apiUrl = "https://api.telegram.org/bot"+apiToken; var commands = { "/start": commandStart, }; function setWebhook(){ var url = apiUrl + "/setWebhook?url="+appUrl; var res = UrlFetchApp.fetch(url); Logger.log(res); } function deleteWebhook(){ var res = UrlFetchApp.fetch(apiUrl+"/deleteWebhook"); Logger.log(res); } function doPost(e){ var webhookData = JSON.parse(e.postData.contents); var from = webhookData.message.from.id; var text = webhookData.message.text; if (text.charAt(0) == "/") { commands[text](from); } else { sendMessage("You said: "+text, from); } } function doGet(e){ return ContentService.createTextOutput("Method GET not allowed"); } function sendMessage(txt, receiver) { var encoded = encodeURIComponent(txt); var url = apiUrl+"/sendMessage?parse_mode=HTML&chat_id="+receiver+"&text="+encoded; var response = UrlFetchApp.fetch(url); Logger.log(response); } function commandStart(receiver){ sendText("Hello, skinbag", receiver); }
可正常运行的sendMessage修改版
function sendMessage() { var encoded = encodeURIComponent("SomeMessage"); var url = apiUrl+"/sendMessage?parse_mode=HTML&chat_id="+MyId+"&text="+encoded; var response = UrlFetchApp.fetch(url); Logger.log(response); }
问题定位与修复
1. 函数调用拼写错误
最明显的问题是commandStart函数里调用了不存在的sendText,正确的函数名是sendMessage。这个错误会导致执行/start命令时直接报错,中断后续逻辑。
2. 缺少错误处理
doPost方法没有任何错误捕获逻辑,一旦Telegram的Webhook数据格式异常(比如没有message字段)、e.postData为空,就会直接抛出错误,导致Bot无响应。建议添加try-catch块捕获错误,同时记录日志:
function doPost(e){ try { if (!e || !e.postData) { Logger.log("Invalid request data"); return ContentService.createTextOutput("Invalid request"); } var webhookData = JSON.parse(e.postData.contents); // 处理可能的callback_query情况(如果Bot支持按钮) var message = webhookData.message || webhookData.callback_query?.message; if (!message) { Logger.log("No message found in webhook data"); return ContentService.createTextOutput("No message data"); } var from = message.from.id; var text = message.text || webhookData.callback_query?.data; if (!text) { Logger.log("No text content found"); return ContentService.createTextOutput("No text data"); } if (text.charAt(0) == "/") { if (commands[text]) { commands[text](from); } else { sendMessage("Unknown command", from); } } else { sendMessage("You said: "+text, from); } return ContentService.createTextOutput("OK"); } catch (error) { Logger.log("Error in doPost: " + error.toString()); return ContentService.createTextOutput("Error: " + error.toString()); } }
3. UrlFetchApp添加错误捕获
sendMessage里的UrlFetchApp.fetch默认会在HTTP错误时抛出异常,建议添加muteHttpExceptions: true参数,这样可以获取错误响应内容,方便调试:
function sendMessage(txt, receiver) { try { var encoded = encodeURIComponent(txt); var url = apiUrl+"/sendMessage?parse_mode=HTML&chat_id="+receiver+"&text="+encoded; // 原代码里的&是HTML转义,在JavaScript里直接用&即可 var options = { muteHttpExceptions: true }; var response = UrlFetchApp.fetch(url, options); Logger.log("Send message response: " + response.getContentText()); return response; } catch (error) { Logger.log("Error sending message: " + error.toString()); } }
4. 部署权限检查
确保Google Apps Script项目部署时,权限设置为任何人,甚至匿名,否则Telegram的Webhook请求会被拒绝。部署步骤:
- 点击右上角“部署”→“新部署”
- 类型选择“Web应用”
- 执行权限选“我”
- 谁可以访问选“任何人,甚至匿名”
- 点击部署,复制新的appUrl到代码里,重新设置Webhook
5. 验证Webhook状态
调用https://api.telegram.org/bot<your_token>/getWebhookInfo检查Webhook的状态,查看是否有错误日志,确认URL是否正确、是否有未处理的更新。
内容的提问来源于stack exchange,提问作者kubo man

