使用Pub/Sub时Hangouts Chat Bot交互按钮异常问题排查
解决Hangouts Chat机器人卡片按钮点击后重复收到消息的问题
看起来你已经走通了大部分流程,就差卡片交互的最后一步了——这种重复收到CARD_CLICKED消息的情况,本质是Hangouts Chat没有收到符合要求的响应,所以默认重试三次。我来给你拆解几个关键排查点和解决方案:
1. 确保返回正确的HTTP响应状态和格式
Hangouts Chat对卡片点击的响应有严格要求:
- 必须返回 200 OK 的状态码,任何4xx/5xx都会触发重试
- 响应内容类型必须是
application/json - 要返回符合Chat API规范的JSON结构,哪怕只是确认处理完成,也要明确告诉Chat“我收到了”
比如在C#里,如果你不需要更新卡片,至少要返回这样的响应:
return Ok(new { actionResponse = new { type = "NONE" } });
如果需要更新原卡片,就返回包含更新后卡片结构的响应,示例代码我放在下面了。
2. 检查JSON序列化的正确性
Chat的API对字段大小写是敏感的,比如actionResponse不能写成actionresponse,type也不能写错。建议用强类型模型来序列化,避免手写字符串出错。
这里给你一个完整的C#处理示例(以ASP.NET Core为例):
[HttpPost] public IActionResult HandleChatEvent([FromBody] ChatEvent incomingEvent) { if (incomingEvent.Type == "CARD_CLICKED") { var buttonAction = incomingEvent.Common?.ActionMethodName; // 根据按钮的方法名处理业务逻辑 switch (buttonAction) { case "confirm_order": // 执行确认订单的逻辑 var updatedCard = BuildConfirmedOrderCard(); // 返回更新卡片的响应 return Ok(new { actionResponse = new { type = "UPDATE_MESSAGE" }, card = updatedCard }); case "cancel_order": // 执行取消订单的逻辑 return Ok(new { actionResponse = new { type = "UPDATE_MESSAGE" }, message = new { text = "订单已取消" } }); default: // 未知操作,返回提示 return Ok(new { actionResponse = new { type = "NONE" }, message = new { text = $"无法识别操作: {buttonAction}" } }); } } // 处理其他类型的消息 return Ok(new { text = "消息已收到" }); } // 辅助方法:构建更新后的卡片 private object BuildConfirmedOrderCard() { return new { header = new { title = "订单已确认", subtitle = $"处理时间: {DateTime.Now:yyyy-MM-dd HH:mm}", imageUrl = "https://your-domain.com/confirm-icon.png", imageStyle = "IMAGE" }, sections = new[] { new { widgets = new[] { new { textParagraph = new { text = "你的订单已成功确认,将尽快发货。" } } } } } }; } // 定义对应的模型类(简化版) public class ChatEvent { public string Type { get; set; } public ChatEventCommon Common { get; set; } } public class ChatEventCommon { public string ActionMethodName { get; set; } }
3. 排查网络延迟和防火墙限制
因为你的机器人托管在防火墙内,要确认:
- Pub/Sub的推送请求能在30秒内得到响应(Chat的超时阈值大概是30秒,超时会触发重试)
- 防火墙允许Google Pub/Sub的IP范围访问你的服务(虽然其他功能正常,但卡片交互的响应路径可能有特殊配置,还是要确认下)
- 你的服务处理
CARD_CLICKED事件时有没有耗时操作(比如数据库查询、外部API调用),尽量异步处理或者优化性能
4. 日志排查
在处理CARD_CLICKED事件的前后,详细记录:
- 收到的完整事件内容
- 返回的响应内容和状态码
- 处理事件的耗时
通过日志你能快速定位是响应格式错了,还是处理超时了,或者是其他问题。
按照上面的步骤排查,应该就能解决重复收到消息的问题了。
内容的提问来源于stack exchange,提问作者TheMcCann
相关产品推荐
相关产品推荐

