如何使用 ITranscriptLogger 和 TranscriptLoggerMiddleware 在 cosmos DB 中存储聊天记录

Lan*_*nna 5 c# sdk botframework azure-cosmosdb

我想使用 ITranscriptLogger 和 TranscriptMiddelWare 将整个聊天历史记录存储在 cosmos DB 中,但我很难做到这一点。我已阅读这篇 MS 文章,但我想将其存储在 Cosmos DB 而不是 Blob 存储中。另外,我正在尝试在 Startup.cs 中而不是在 Bot.cs 中实例化转录日志,并且我尝试根据此答案来实现它,但没有任何运气。也就是说,不会存储脚本,并且我的 Azure cosmos DB 中没有容器。我感谢任何帮助和反馈。

代码

我已经创建了 TranscriptStore 类,并按照引用的 SO 答案中的说明创建并添加了中间件:

CosmosTranscriptStore.cs

public class CosmosTranscriptStore : ITranscriptLogger
    {
        private CosmosDbStorage _storage;

        public CosmosTranscriptStore(CosmosDbStorageOptions config)
        {
            _storage = new CosmosDbStorage(config);
        }
        public async Task LogActivityAsync(IActivity activity)
        {
            // activity only contains Text if this is a message
            var isMessage = activity.AsMessageActivity() != null ? true : false;
            if (isMessage)
            {
                // Customize this to save whatever data you want
                var data = new
                {
                    From = activity.From,
                    To = activity.Recipient,
                    Text = activity.AsMessageActivity().Text,
                };
                var document = new Dictionary<string, object>();
                // activity.Id is being used as the Cosmos Document Id
                document.Add(activity.Id, data);
                await _storage.WriteAsync(document, new CancellationToken());
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

启动.cs

 public class Startup
    {

        private const string CosmosServiceEndpoint = "MyCosmosServiceEndpoint";
        private const string CosmosDBKey = "MyCosmosDBKey";
        private const string CosmosDBDatabaseName = "MyCosmosDBDatabaseName";
        private const string CosmosDBCollectionName = "Transcript-storage";
      
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;    
        }
        
        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            var config = new CosmosDbStorageOptions
            {
                AuthKey = CosmosDBKey,
                CollectionId = CosmosDBCollectionName,
                CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
                DatabaseId = CosmosDBDatabaseName,
            };

            var transcriptMiddleware = new TranscriptLoggerMiddleware(new CosmosTranscriptStore(config));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // Create the Bot Framework Adapter.
            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
            
            // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
            services.AddSingleton<MainDialog>();
            services.AddTransient<IBot, WelcomeBot<MainDialog>>();

            services.AddBot<WelcomeBot<MainDialog>>(options =>
            {
                var middleware = options.Middleware;
                middleware.Add(transcriptMiddleware);
            });

        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseMvc();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Lan*_*nna 4

我设法通过将转录本存储中间件添加到适配器来解决这个问题,在提出这个问题之前我可能应该从一开始就这样做,但我对机器人框架和这种类型的编程都很陌生。这就是我解决它的方法:

启动.cs

public void ConfigureServices(IServiceCollection services)
        {
            ...
            
            var config = new CosmosDbStorageOptions
            {
                AuthKey = CosmosDBKey,
                CollectionId = CosmosDBAntoherCollectionName,
                CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
                DatabaseId = CosmosDBDatabaseName,
            };

            var transcriptMiddleware = new TranscriptLoggerMiddleware(new CosmosTranscriptStore(config));

            services.AddSingleton(transcriptMiddleware);
            
            ...

        }
Run Code Online (Sandbox Code Playgroud)

AdapterWithErrorHandler.cs

public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
    {
        public AdapterWithErrorHandler(TranscriptLoggerMiddleware transcriptMiddlewareStore, IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger, ConversationState conversationState = null)
            : base(configuration, logger)
        {
            Use(transcriptMiddlewareStore);
            
            OnTurnError = async (turnContext, exception) =>
            {
               ...
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

此外,如果想要将整个聊天记录存储在一个文档/项目中,我强烈建议通过对话 ID 而不是活动 ID 将数据存储在 CosmosTranscriptStore 类中。原因是每个活动都有自己的 ID,从而在 Cosmos DB 中为每个活动创建一个新项目。

 public class CosmosTranscriptStore : ITranscriptLogger
    {
      ...

        public async Task LogActivityAsync(IActivity activity)
        {
            ...

                document.Add(activity.Conversation.Id, data);
                await chatStorage.WriteAsync(document, new CancellationToken());
            
        }
    }
Run Code Online (Sandbox Code Playgroud)