c# - 如何使用 directLine channel 在 Azure 表存储中存储和检索机器人数据?

标签 c# node.js botframework azure-table-storage direct-line-botframework

我正在将 Microsoft Bot FrameworkdirectLine channel 结合使用。我的机器人是公司客户门户的一部分,我从那里获取一些用户信息并使用 stateClient 将其存储在 BotState 中,如下所示

 public ActionResult Index()
        {
            var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            GetTokenViaBootStrap().Wait();

            var botCred = new MicrosoftAppCredentials(
              ConfigurationManager.AppSettings["MicrosoftAppId"],
              ConfigurationManager.AppSettings["MicrosoftAppPassword"]);
            var stateClient = new StateClient(botCred);
            BotState botState = new BotState(stateClient);
            BotData botData = new BotData(eTag: "*");
            botData.SetProperty<string>("UserName", result.UserInfo.GivenName + " " + result.UserInfo.FamilyName);
            botData.SetProperty<string>("Email", result.UserInfo.DisplayableId);
            botData.SetProperty<string>("GraphAccessToken", UserAccessToken);
            botData.SetProperty<string>("TokenExpiryTime", result.ExpiresOn.ToString());

            stateClient.BotState.SetUserDataAsync("directline", userId, botData).Wait();

            var UserData = new UserInformationModel
            {
                UserId = userId,
                UserName = result.UserInfo.GivenName + " " + result.UserInfo.FamilyName
            };
            return View(UserData);
        }

由于它是一个 directLine channel ,我使用 JavaScript 中的 secret 连接我的机器人,如下所示:

  BotChat.App({
        bot: { id: 'my_bot_id', name: 'my_bot_id' },
        resize: 'detect',
        sendTyping: true,    // defaults to false. set to true to send 'typing' activities to bot (and other users) when user is typing
        user: { id: UserData.UserId},
        directLine: {
            secret: "my_bot_secret"
        }
    }, document.getElementById('my_bot_id'));

我正在访问 MVC 站点中捕获的 Node js Bot 中的用户信息数据,如下所示:

function sessionUserCapture(session) {

    switch (session.message.address.channelId) {
        case 'skypeforbusiness':
            // some code
            break;
        case 'directline':
               userName= session.userData.UserName;
               userEmail= session.userData.Email;
               //some code
            break;
        case 'slack':
        // some code
    }
}

我引用了 Microsoft 的 Save state data from Manage state data对于上面的代码,然后我使用 session 中可用的 userData 在我的 Node.JS Bot 中访问此数据。

由于 StateClient 已弃用,我引用了 thisstateclient 替换为 Azure 表存储。但是,我无法理解如何将上述数据存储在表存储中。

有人可以推荐任何我可以引用的文章来解决这个问题吗?

我的机器人位于 NodeJs 中,并且我正在 C# MVC 应用程序 中使用 directLine channel 。

最佳答案

一种选择是使用 .NET 的 Microsoft Azure 存储客户端库,如此处答案中所述:How to retrieve Saved Conversation Data in Azure (Tablelogger)只需确保遵循与 TableBotDataStore 完全相同的 PartitionKey 策略即可。类,并正确序列化数据字段。

-- 编辑: 我对此进行了测试,它确实按预期工作。

 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 = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="addac5ccd9c8dbc8dfedc8c0ccc4c183cec2c0" rel="noreferrer noopener nofollow">[email protected]</a>",
                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 = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aed9c6cfdacbd8cbdceecbc3cfc7c280cdc1c3" rel="noreferrer noopener nofollow">[email protected]</a>",
                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; }
    }
}

在 Node 机器人中:

'use strict';

const builder = require('botbuilder');
const restify = require('restify');
var azure = require('botbuilder-azure');

var tableName = 'BotStore';
var azureTableClient = new azure.AzureTableClient(tableName,'accountname','accountkey');
var tableStorage = new azure.AzureBotStorage({ gzipData: false }, azureTableClient);


const connector = new builder.ChatConnector({
    appId: process.env.MicrosoftAppId,
    appPassword: process.env.MicrosoftAppPassword
    });

const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3979, () => {
    console.log(`${server.name} listening to ${server.url}`);
});

server.post('/api/messages', connector.listen());

var bot = new builder.UniversalBot(connector)
    .set('storage', tableStorage);;

bot.dialog('/',
[
    function (session){
        var data = session.userData;
    }
]);

enter image description here

关于c# - 如何使用 directLine channel 在 Azure 表存储中存储和检索机器人数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48327229/

相关文章:

c# - 从其他 Windows 应用程序捕获事件

c# - DataGrid 的行在应用程序运行时显示为最小化

javascript - 寻找一种通过 Nodejs 在 HTML 中运行 Javascript 函数的方法

node.js - node.js 中的 addListener(event, listener) 和 on(event, listener) 方法有什么区别?

c# - 读取文本文件并以内存有效的方式搜索字符串(并在找到时中止)

c# - 如何在 Automapper 6 映射期间忽略所有源成员的空值?

node.js - 如何正确处理 docker 中的 .env 文件

c# - 通过 API Microsoft Bot Framework 返回货币汇率

c# - BotFramework 在表单流中访问用户数据

node.js - 使用 Google Vision Api 在 Azure 中托管的机器人 - gRPC 问题