Golang开发Telegram Bot遇Webhook连接被拒问题求助
配置信息
- 操作系统:Ubuntu
- 服务器:Apache2
- 虚拟主机:已成功绑定域名,监听8843端口,ufw已开放443、8843端口
- Webhook:设置为
"domain.app:8843/"+bot.Token,HandleFunc对应"/"+bot.Token,ListenAndServeTLS已成功加载证书文件
问题现象
启动二进制文件后,日志输出如下:
2023/01/07 01:50:15 Authorized on account ExampleAccount
2023/01/07 01:50:15 setWebhook resp:
{"ok":true,"result":true,"description":"Webhook is already set"}
2023/01/07 01:50:15 getWebhookInfo resp:
{"ok":true,"result":{"url":"https://domain.app:8443/MY_BOT_TOKEN","has_custom_certificate":false,"pending_update_count":0,"last_error_date":1673052633,"last_error_message":"Connection refused","max_connections":40,"ip_address":"x.x.x.x"}}
2023/01/07 01:50:15 Telegram callback failed: Connection refused
后续调用getWebhookInfo显示pending_update_count会随start命令增加,但回调仍提示连接被拒。
相关代码
func main() { // 创建Bot实例 bot, err := tgbotapi.NewBotAPI("PLACEHOLDER") if err != nil { log.Panic(err) } bot.Debug = true log.Printf("已授权账号: %s", bot.Self.UserName) // 设置Webhook _, err = bot.SetWebhook(tgbotapi.NewWebhook("https://domain.app:8443/" + bot.Token)) if err != nil { log.Panic(err) } info, err := bot.GetWebhookInfo() if err != nil { log.Fatal(err) } if info.LastErrorDate != 0 { log.Printf("Telegram回调失败: %s", info.LastErrorMessage) } // 启动Webhook服务器 http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { update := tgbotapi.Update{} err := json.NewDecoder(r.Body).Decode(&update) if err != nil { log.Println(err) return } // 检查是否为回调查询(按钮点击) if update.CallbackQuery != nil { callbackQuery := update.CallbackQuery data := callbackQuery.Data // 创建消息 msg := tgbotapi.NewMessage(callbackQuery.Message.Chat.ID, "") // 根据点击的按钮设置文本和键盘 switch data { case "get_information": msg.Text = "以下是支持的格式信息:" msg.ReplyMarkup = tgbotapi.NewRemoveKeyboard(true) case "start_file_conversion": msg.Text = "好的!点击链接下载文件: https://example.com/ks283dj" msg.ReplyMarkup = tgbotapi.NewRemoveKeyboard(true) } // 发送消息 bot.Send(msg) } }) log.Printf("即将监听 0.0.0.0:8443:8443") errServe := http.ListenAndServeTLS("0.0.0.0:8443", "fullchain.pem", "privkey.pem", nil) log.Fatal(errServe) }
排查要点
端口不一致问题
你提到虚拟主机监听8843端口,但代码中设置Webhook用的是8443,ListenAndServeTLS也绑定的是8443端口,而Telegram返回的Webhook URL也是8443。如果你的Apache虚拟主机是在8843提供服务,那么要么:- 修改代码,将Webhook URL和监听端口改为8843,确保和虚拟主机端口一致;
- 或者在Apache中配置反向代理,将8843端口的请求转发到Bot服务的8443端口。
端口可达性验证
从服务器外部测试https://domain.app:8443/你的BotToken是否能正常访问,返回预期响应。如果无法访问,检查:- 执行
ufw status确认8443端口确实在ufw开放列表中; - 云服务器的服务商防火墙(若使用云主机)是否开放了8443端口;
- 执行
netstat -tulpn | grep 8443确认Bot服务是否真的在监听8443端口。
- 执行
证书有效性
Telegram要求Webhook使用受信任CA颁发的证书(如Let's Encrypt),且证书文件包含完整链。确认fullchain.pem和privkey.pem路径正确,且Bot进程有读取权限。可执行openssl s_client -connect domain.app:8443验证证书是否有效。Apache配置冲突
确保Apache和Bot服务没有端口占用冲突,同时确认域名解析的IP指向正确,Telegram能正常解析到你的服务器IP。Webhook路径匹配
检查代码中HandleFunc的路径"/"+bot.Token和Webhook设置的路径是否完全一致,避免大小写、特殊字符等差异。
内容的提问来源于stack exchange,提问作者SelfLearnedNoob

