Bot Framework:如何使用中间件编辑机器人 outgoing 消息
在Bot Framework中拦截并修改机器人发送的所有消息
嗨,这个需求我之前刚好实现过!你说得没错,常规的IMiddleware的OnTurnAsync确实只在收到用户消息或对话更新时触发,但Bot Framework其实提供了专门的方式来拦截和修改机器人发出的所有消息(包括提示、SendActivityAsync发送的内容),下面给你两种靠谱的实现方案:
方案一:使用ActivityMiddleware(推荐,Bot Framework v4+)
ActivityMiddleware是框架专门为处理** outgoing 活动**(也就是机器人发出去的消息)设计的中间件类型,它能直接拦截所有机器人要发送的活动,非常适合你的场景。
步骤1:创建自定义的ActivityMiddleware
using Microsoft.Bot.Builder; using Microsoft.Bot.Schema; using System.Threading; using System.Threading.Tasks; public class UpperCaseOutgoingMiddleware : ActivityMiddleware { protected override async Task OnSendActivityAsync(ActivityHandlerDelegate next, ITurnContext turnContext, Activity activity, CancellationToken cancellationToken) { // 只处理消息类型的活动,避免修改对话更新、事件等其他类型 if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { // 将消息转换为大写 activity.Text = activity.Text.ToUpper(); } // 继续执行后续的中间件或发送流程 await next(cancellationToken); } }
步骤2:注册中间件
在你的Bot服务配置代码(比如Startup.cs或者Program.cs的依赖注入部分)中,把这个中间件添加到Bot的中间件管道里:
services.AddBot<YourBotClass>(options => { // 其他Bot配置(比如适配器、AppId/AppPassword等)... options.Middleware.Add(new UpperCaseOutgoingMiddleware()); });
方案二:拦截ITurnContext的SendActivityAsync方法
如果你需要更灵活的控制(比如同时处理 incoming 和 outgoing 消息),也可以在常规的IMiddleware中,通过包装TurnContext的SendActivityAsync方法来实现拦截:
实现自定义IMiddleware
using Microsoft.Bot.Builder; using Microsoft.Bot.Schema; using System.Threading; using System.Threading.Tasks; public class UpperCaseMiddleware : IMiddleware { public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { // 保存原始的SendActivityAsync方法引用 var originalSendActivity = turnContext.SendActivityAsync; // 替换为我们自定义的逻辑 turnContext.SendActivityAsync = async (Activity activity, CancellationToken ct) => { if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { activity.Text = activity.Text.ToUpper(); } // 调用原始方法发送修改后的消息 return await originalSendActivity(activity, ct); }; // 继续处理当前Turn的其他逻辑(比如用户消息的处理) await next(cancellationToken); } }
注册中间件
同样在Bot配置中添加这个中间件即可,和方案一的注册方式一致。
注意事项
- 这两种方案都能捕获到所有机器人发出的消息,包括:直接调用
SendActivityAsync发送的消息、WaterfallDialog中的各种提示(TextPrompt、ChoicePrompt等)、甚至是自适应卡片这类富消息(如果需要修改卡片内容,只需要调整activity.Attachments的逻辑即可)。 - 如果你的Bot使用了多轮对话(比如Dialog系统),不用担心,中间件会自动作用于所有Dialog中发出的消息,不需要额外配置。
内容的提问来源于stack exchange,提问作者Kuba K
相关产品推荐
相关产品推荐

