如何在Dialogflow中使用C# Webhook实现订阅用户广播消息
实现Dialogflow Webhook的广播消息功能(C#)
你已经搞定了用户订阅(保存PSID)的部分,接下来要实现广播消息其实核心是调用Facebook Messenger Send API(毕竟你用到的PSID是Facebook用户标识,说明你的Dialogflow对接了Messenger渠道),下面一步步给你讲怎么在C# Webhook里落地:
1. 准备必要的凭证
首先得从Facebook开发者后台拿到你的Page Access Token,这个令牌是调用Messenger API的关键,要确保它拥有pages_messaging权限。
2. 从数据库取出所有订阅用户的PSID
你已经用WebhookReceiverModelDataContext保存了用户PSID,现在只需要查询上下文里的订阅列表就行,假设你的实体类是SubscribedUser,包含Psid字段:
// 从数据库拉取所有订阅用户的PSID var subscribedUsers = ctx.SubscribedUsers.Select(u => u.Psid).ToList();
3. 封装调用Messenger API的方法
写一个通用方法用来给单个用户发送消息,后续广播时直接循环调用即可:
private async Task SendMessageToUser(string pageAccessToken, string psid, string messageText) { // 建议复用HttpClient,这里为示例简洁直接创建 var client = new HttpClient(); var requestUrl = $"https://graph.facebook.com/v18.0/me/messages?access_token={pageAccessToken}"; // 构造Messenger API要求的请求体 var payload = new { recipient = new { id = psid }, message = new { text = messageText } }; var jsonPayload = JsonConvert.SerializeObject(payload); var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"); var response = await client.PostAsync(requestUrl, content); if (!response.IsSuccessStatusCode) { // 这里建议加日志记录,方便排查发送失败的情况 var errorContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($"给用户 {psid} 发送消息失败: {errorContent}"); } }
提示:记得安装
Newtonsoft.JsonNuGet包来处理JSON序列化;生产环境里HttpClient最好全局复用,不要每次请求都实例化。
4. 在Webhook里触发广播逻辑
比如你可以新增一个broadcast.send意图,当管理员触发这个意图时(比如发送指令“发送广播”),执行广播逻辑。把这段逻辑加到你现有的Post方法里:
public async Task<ApiAiResponse> Post([FromBody]JObject jsonRequest) { using (WebhookReceiverModelDataContext ctx = new WebhookReceiverModelDataContext()) { ApiAiRequest request = jsonRequest.ToObject<ApiAiRequest>(); var response = new ApiAiResponse(); switch (request.Result.Action) { case "subscribe.about": // 你已有的保存PSID逻辑 var psid = request.OriginalRequest.Data["sender"]["id"].ToString(); ctx.SubscribedUsers.InsertOnSubmit(new SubscribedUser { Psid = psid }); ctx.SubmitChanges(); response.Speech = "订阅成功!"; break; case "broadcast.send": // 广播消息逻辑 string pageAccessToken = "你的Facebook Page Access Token"; string broadcastContent = "这是一条给所有订阅用户的广播消息!"; var subscribedUsers = ctx.SubscribedUsers.Select(u => u.Psid).ToList(); foreach (var userPsid in subscribedUsers) { await SendMessageToUser(pageAccessToken, userPsid, broadcastContent); } response.Speech = "广播消息已发起发送!"; break; // 其他意图的处理逻辑... } return response; } }
几个注意点
- API版本:示例里用的是v18.0,记得根据Facebook的最新API版本调整,避免版本过期导致请求失败。
- 限流问题:如果订阅用户数量多,不要一次性同步发送,建议用异步队列或者批量请求处理,避免触发Facebook的API调用频率限制。
- 失效PSID处理:如果用户取消订阅,对应的PSID会失效,API返回错误时可以考虑从数据库移除这些无效的PSID。
- 凭证安全:不要把Page Access Token硬编码在代码里,最好放在配置文件(比如appsettings.json)中,避免泄露。
内容的提问来源于stack exchange,提问作者user7575848
相关产品推荐
相关产品推荐

