如何储存和存放使用directLine通道在Azure表存储中检索Bot数据?

问题描述:

我正在将Microsoft Bot FrameworkdirectLine通道一起使用.我的机器人是公司客户门户网站的一部分,从那里我可以获取一些用户信息,并使用stateClient将该信息存储在BotState中,如下所示

I'm using Microsoft Bot Framework with directLine channel. My Bot is a part of company's customer portal from where I fetch some user information and store it in BotState using stateClient as shown below

 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频道,我正在使用javascript中的secret连接我的机器人,如下所示:

As its a directLine channel, I'm connecting my bot using secret in javascript as shown below:

  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中的用户信息数据,如下所示:

I'm accessing user information data in Node js Bot captured in MVC site as shown below:

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的从管理上述代码的状态数据,然后使用session中可用的userData访问我的Node.JS Bot中的数据.

I referred Microsoft's Save state data from Manage state data for above code and then I used userData available in the session to access this data in my Node.JS Bot.

不建议使用StateClient,我引用了,将stateclient替换为Azure Table storage.但是,我无法理解如何将以上数据存储在Table Storage中.

As the StateClient is Deprecated, I referred this to replace stateclient with Azure Table storage. However, I'm not able to understand how can I store the above data in the Table Storage.

任何人都可以建议我参考以解决该问题的任何文章吗?

我的机器人在NodeJs中,而我在C# MVC application中使用directLine通道.

My Bot is in NodeJs and the I'm using directLine channel in a C# MVC application.

一个选项是将 Microsoft Azure存储客户端库用于.NET,如此处答案中所述:如何在Azure(Tablelogger)中检索保存的会话数据遵循与

One option is to use the Microsoft Azure Storage Client Library for .NET, as explained in the answer here: How to retrieve Saved Conversation Data in Azure (Tablelogger) Just make sure to follow the exact same PartitionKey strategy as is followed by the TableBotDataStore class, and serialize the data field correctly.

- 我对此进行了测试,实际上它确实按预期工作.

-- I tested this out, and it does in fact work as expected.

 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; }
    }
}

在节点漫游器中:

'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;
    }
]);