C# 将会话历史记录从MS bot保存到cosmos db

C# 将会话历史记录从MS bot保存到cosmos db,c#,.net,botframework,azure-cosmosdb,C#,.net,Botframework,Azure Cosmosdb,我正在开发的bot是一个用于替代潜在客户的联系表单的工具,这些潜在客户希望公司联系,因此用户输入必须保存在数据库中。我已成功地将Cosmos DB连接到我的机器人,该机器人在使用时收集状态数据。我有一个对话框堆栈,每个用户输入一个对话框(姓名、电子邮件和用户想要留下的消息) 我找不到任何关于如何为用C#编写的机器人保存对话历史记录的有用文档。有人能帮我吗?我还是Bot框架和C#的初学者 这是我的global.asax文件: public class WebApiApplication : Sy

我正在开发的bot是一个用于替代潜在客户的联系表单的工具,这些潜在客户希望公司联系,因此用户输入必须保存在数据库中。我已成功地将Cosmos DB连接到我的机器人,该机器人在使用时收集状态数据。我有一个对话框堆栈,每个用户输入一个对话框(姓名、电子邮件和用户想要留下的消息)

我找不到任何关于如何为用C#编写的机器人保存对话历史记录的有用文档。有人能帮我吗?我还是Bot框架和C#的初学者

这是我的global.asax文件:

 public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
        var uri = new Uri(ConfigurationManager.AppSettings["DocumentDbUrl"]);
        var key = ConfigurationManager.AppSettings["DocumentDbKey"];
        var store = new DocumentDbBotDataStore(uri, key);

        Conversation.UpdateContainer(
                    builder =>
                    {
                        builder.Register(c => store)
                            .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                            .AsSelf()
                            .SingleInstance();

                        builder.Register(c => new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
                            .As<IBotDataStore<BotData>>()
                            .AsSelf()
                            .InstancePerLifetimeScope();

                    });

    }
}
公共类WebAPI应用程序:System.Web.HttpApplication
{
受保护的无效应用程序\u Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var uri=新uri(ConfigurationManager.AppSettings[“DocumentDbUrl”]);
var key=ConfigurationManager.AppSettings[“DocumentDbKey”];
var store=newdocumentdbbotdatastore(uri,键);
Conversation.UpdateContainer(
生成器=>
{
builder.Register(c=>store)
.Keyed(AzureModule.Key_数据存储)
.AsSelf()
.SingleInstance();
Register(c=>newcachingbotdatastore(store,cachingbotdatastoreconsistentypolicy.ETagBasedConsistency))
.As()
.AsSelf()
.InstancePerLifetimeScope();
});
}
}
下面是收集用户名的my NameDialog:(其他对话框几乎与此相同)

[可序列化]
公共类名称对话框:IDialog
{
私人int尝试=3;
公共异步任务StartAsync(IDialogContext上下文)
{
等待上下文。PostAsync(“你叫什么名字?”);
context.Wait(this.MessageReceivedAsync);
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
var消息=等待结果;
如果((message.Text!=null)&&(message.Text.Trim().Length>0))
{
context.Done(message.Text);
}
其他的
{
--企图;
如果(尝试次数>0)
{
wait context.PostAsync(“我不明白,你能再试一次吗?”);
context.Wait(this.MessageReceivedAsync);
}
其他的
{
失败(新的ToomAnyatTestSexException(“这不是有效的输入”);
}
}
}
}

我提交了几条评论,要求澄清您所寻找的内容,但我想我还是提供一个包罗万象的答案为好

使用V4 如果您的bot是新的,只需使用BotBuilder/BotFramework的V4即可。它更简单,有更多的功能和更好的支持。无论如何,我会为这两个问题提供答案

在V4中保存自定义数据 参考文献:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);
对于指定用户Id的自定义存储:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);

在V4中保存完整的对话历史记录 参考资料:

只需阅读文档并查看此文档的示例。代码太多,无法复制/粘贴

在V3中保存自定义数据 参考文献:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);
我将从以下位置复制/粘贴代码:

public class WebChatController : Controller
{
    public ActionResult Index()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

        CloudTable table = tableClient.GetTableReference("BotStore");
        string userId = Guid.NewGuid().ToString();
        TableQuery<BotDataRow> query = new TableQuery<BotDataRow>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, userId));

        var dataRow = table.ExecuteQuery(query).FirstOrDefault();
        if(dataRow != null)
        {
            dataRow.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                UserName = "This user's name",
                Email = "whatever@email.com",
                GraphAccessToken = "token",
                TokenExpiryTime = DateTime.Now.AddHours(1)
            });
            dataRow.Timestamp = DateTimeOffset.UtcNow;
            table.Execute(TableOperation.Replace(dataRow));
        }
        else
        {
            var row = new BotDataRow(userId, "userData");
            row.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                UserName = "This user's name",
                Email = "whatever@email.com",
                GraphAccessToken = "token",
                TokenExpiryTime = DateTime.Now.AddHours(1)
            });
            row.Timestamp = DateTimeOffset.UtcNow;
            table.Execute(TableOperation.Insert(row));
        }

        var vm = new WebChatModel();
        vm.UserId = userId;
        return View(vm);
    }

    public class BotDataRow : TableEntity
    {
        public BotDataRow(string partitionKey, string rowKey)
        {
            this.PartitionKey = partitionKey;
            this.RowKey = rowKey;
        }

        public BotDataRow() { }

        public bool IsCompressed { get; set; }
        public string Data { get; set; }
    }
}
将以下内容添加到
Global.asax.cs

public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<DebugActivityLogger>().AsImplementedInterfaces().InstancePerDependency();
            builder.Update(Conversation.Container);

            GlobalConfiguration.Configure(WebApiConfig.Register);
        }
    }
公共类WebAPI应用程序:System.Web.HttpApplication
{
受保护的无效应用程序\u Start()
{
var builder=new ContainerBuilder();
builder.RegisterType();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}

我提交了几条评论,要求澄清您所寻找的内容,但我想我还是提供一个包罗万象的答案为好

使用V4 如果您的bot是新的,只需使用BotBuilder/BotFramework的V4即可。它更简单,有更多的功能和更好的支持。无论如何,我会为这两个问题提供答案

在V4中保存自定义数据 参考文献:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);
对于指定用户Id的自定义存储:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);

在V4中保存完整的对话历史记录 参考资料:

只需阅读文档并查看此文档的示例。代码太多,无法复制/粘贴

在V3中保存自定义数据 参考文献:

// Create Cosmos Storage
private static readonly CosmosDbStorage _myStorage = new CosmosDbStorage(new CosmosDbStorageOptions
{
   AuthKey = CosmosDBKey,
   CollectionId = CosmosDBCollectionName,
   CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
   DatabaseId = CosmosDBDatabaseName,
});

// Write
var userData = new { Name = "xyz", Email = "xyz@email.com", Message = "my message" };
var changes = Dictionary<string, object>();
{
    changes.Add("UserId", userData);
};
await _myStorage.WriteAsync(changes, cancellationToken);

// Read
var userDataFromStorage = await _myStorage.read(["UserId"]);
我将从以下位置复制/粘贴代码:

public class WebChatController : Controller
{
    public ActionResult Index()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

        CloudTable table = tableClient.GetTableReference("BotStore");
        string userId = Guid.NewGuid().ToString();
        TableQuery<BotDataRow> query = new TableQuery<BotDataRow>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, userId));

        var dataRow = table.ExecuteQuery(query).FirstOrDefault();
        if(dataRow != null)
        {
            dataRow.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                UserName = "This user's name",
                Email = "whatever@email.com",
                GraphAccessToken = "token",
                TokenExpiryTime = DateTime.Now.AddHours(1)
            });
            dataRow.Timestamp = DateTimeOffset.UtcNow;
            table.Execute(TableOperation.Replace(dataRow));
        }
        else
        {
            var row = new BotDataRow(userId, "userData");
            row.Data = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                UserName = "This user's name",
                Email = "whatever@email.com",
                GraphAccessToken = "token",
                TokenExpiryTime = DateTime.Now.AddHours(1)
            });
            row.Timestamp = DateTimeOffset.UtcNow;
            table.Execute(TableOperation.Insert(row));
        }

        var vm = new WebChatModel();
        vm.UserId = userId;
        return View(vm);
    }

    public class BotDataRow : TableEntity
    {
        public BotDataRow(string partitionKey, string rowKey)
        {
            this.PartitionKey = partitionKey;
            this.RowKey = rowKey;
        }

        public BotDataRow() { }

        public bool IsCompressed { get; set; }
        public string Data { get; set; }
    }
}
将以下内容添加到
Global.asax.cs

public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<DebugActivityLogger>().AsImplementedInterfaces().InstancePerDependency();
            builder.Update(Conversation.Container);

            GlobalConfiguration.Configure(WebApiConfig.Register);
        }
    }
公共类WebAPI应用程序:System.Web.HttpApplication
{
受保护的无效应用程序\u Start()
{
var builder=new ContainerBuilder();
builder.RegisterType();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}

为了澄清,您是想保存整个对话历史记录,还是只保存用户数据(姓名、电子邮件、消息)?另外,是否有理由在V3而不是SDK的V4中构建机器人?为了澄清,您是想保存整个对话历史记录,还是只保存用户数据(姓名、电子邮件、消息)?另外,您在SDK的V3而不是V4中构建bot有什么原因吗?用于存储完整对话的链接“对话历史示例”不起作用。您可以发布更新的链接吗?@RohanRao我们不再提供更新的示例,而是您的链接“对话历史示例”,用于存储ful