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

实现IBotToUser翻译后Bot消息无法写入Table Storage问题

解决Bot消息翻译与活动记录无法共存的问题

嘿,我明白你的问题了——当你注册了自定义的翻译拦截类后,Bot发送的消息就没法存到Table Storage的Activities表了,但禁用翻译又能正常记录。这其实是因为你的DI注册直接替换了Bot Framework默认的IBotToUser实现,而默认实现恰恰包含了把消息写入活动表的逻辑。

问题根源

Bot Framework自带的BotToUser类(默认的IBotToUser实现)内部会处理活动记录到Table Storage的逻辑。但你现在的DI注册用自己的InterceptBotToUserTranslator完全替换了这个默认实现,导致记录活动的代码根本没机会运行。

解决方案:用装饰器模式包装原始实现

正确的做法是用装饰器模式,让你的翻译类"包裹"住原始的IBotToUser实现,这样既能执行翻译逻辑,又不会丢失原本的活动记录功能。

第一步:修改DI注册代码

把你原来的DI注册改成这样:

// 先注册Bot Framework默认的IBotToUser实现
Builder.RegisterType<BotToUser>().As<IBotToUser>().InstancePerLifetimeScope();

// 注册你的拦截类(如果确实需要保留的话)
Builder.RegisterType<InterceptBotToUser>().AsSelf().InstancePerLifetimeScope();

// 关键:用装饰器模式注册翻译类,让它注入原始的IBotToUser
Builder.RegisterDecorator<InterceptBotToUserTranslator, IBotToUser>()
       .InstancePerLifetimeScope();

第二步:优化翻译类(可选)

其实你的InterceptBotToUser类看起来和默认的BotToUser功能重复了,你可以简化代码,直接让翻译类依赖原始的IBotToUser,这样不需要额外的InterceptBotToUser:

public class InterceptBotToUserTranslator : IBotToUser
{
    private readonly IBotToUser _innerBotToUser;
    // 如果有翻译服务,这里可以注入
    // private readonly IMyTranslationService _translationService;

    public InterceptBotToUserTranslator(IBotToUser innerBotToUser/*, IMyTranslationService translationService*/)
    {
        SetField.NotNull(out _innerBotToUser, nameof(innerBotToUser), innerBotToUser);
        // SetField.NotNull(out _translationService, nameof(translationService), translationService);
    }

    public IMessageActivity MakeMessage()
    {
        // 直接调用原始实现的方法
        return _innerBotToUser.MakeMessage();
    }

    public async Task PostAsync(IMessageActivity message, CancellationToken cancellationToken = default)
    {
        // 在这里执行翻译逻辑
        // message.Text = await _translationService.TranslateTextAsync(message.Text, "目标语言代码");
        
        // 调用原始的PostAsync,这样默认的活动记录逻辑会被触发
        await _innerBotToUser.PostAsync(message, cancellationToken);
    }
}

为什么这样能解决问题?

用RegisterDecorator注册后,当请求IBotToUser实例时,Autofac(假设你用的是Autofac)会先创建原始的BotToUser实例,再把它注入到你的InterceptBotToUserTranslator中。这样你的翻译逻辑执行完后,会调用原始实例的PostAsync方法,而原始方法里就包含了把消息写入Table Storage的逻辑。

验证效果

修改完之后,再测试一下:

  • Bot发送的消息应该正常翻译并推送给用户
  • 同时,这条消息会被自动记录到Table Storage的Activities表中

内容的提问来源于stack exchange,提问作者GeekzSG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:26:09