You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:27:31