有没有任何方法可以使用SDK V4 Nodedjs在bot框架中捕获端到端的会话数据并将其保存到blob存储或cosmo



我想将对话数据存储到存储帐户或cosmos DB中。通过尝试https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-storage?view=azure-僵尸服务-4.0&tabs=javascript#使用blob存储

我能够将语句slog发送到blob存储中。但我想存储端到端的对话数据,其中包括用户的数据以及使用javascript的机器人程序响应。

我尝试使用保存用户状态和会话状态,但没有达到所需的输出。

我创建了一个自定义记录器(基于一个已经不存在的旧botduilder示例(,它使用TranscriptLoggerMiddleware实现了这一点。我选择了CosmosDB而不是Blob存储,因为我觉得将其存储(和检索(为JSON文档更容易。但是您可以调整这个概念以使用任何DB。以下是我所做的。

首先,创建您的自定义记录器代码。如前所述,我使用了CosmosDB,所以如果您使用不同的DB,您可能需要更改一些内容。活动的时间安排造成了并发问题,所以我没有解决这个问题,而是将transcript对象存储在本地,并每次覆盖数据库对象。也许不是最优雅的,但它很管用。此外,我发现我的等待功能是必需的。否则,你只能得到谈话的一方。有人告诉我,这种类型的等待功能不是最佳实践,但等待承诺或其他创建延迟的方法对我来说不起作用

customerLogger.js

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
const { CosmosDbStorage } = require('botbuilder-azure');
const path = require('path');
/**
* CustomLogger, takes in an activity and saves it for the duration of the conversation, writing to an emulator compatible transcript file in the transcriptsPath folder.
*/
class CustomLogger {
/**
* Log an activity to the log file.
* @param activity Activity being logged.
*/
// Set up Cosmos Storage
constructor(appInsightsClient) {
this.transcriptStorage = new CosmosDbStorage({
serviceEndpoint: process.env.COSMOS_SERVICE_ENDPOINT,
authKey: process.env.COSMOS_AUTH_KEY,
databaseId: process.env.DATABASE,
collectionId: 'bot-transcripts'
});
this.conversationLogger = {};
this.appInsightsClient = appInsightsClient;
this.msDelay = 250;
}

async logActivity(activity) {
if (!activity) {
throw new Error('Activity is required.');
}
// Log only if this is type message
if (activity.type === 'message') {
if (activity.attachments) {
var logTextDb = `${activity.from.name}: ${activity.attachments[0].content.text}`;
} else {
var logTextDb = `${activity.from.name}: ${activity.text}`;
}
if (activity.conversation) {
var id = activity.conversation.id;
if (id.indexOf('|') !== -1) {
id = activity.conversation.id.replace(/|.*/, '');
}
// Get today's date for datestamp
var currentDate = new Date();
var day = currentDate.getDate();
var month = currentDate.getMonth()+1;
var year = currentDate.getFullYear();
var datestamp = year + '-' + month + '-' + day;
var fileName = `${datestamp}_${id}`;
var timestamp = Math.floor(Date.now()/1);
// CosmosDB logging (JK)
if (!(fileName in this.conversationLogger)) {
this.conversationLogger[fileName] = {};
this.conversationLogger[fileName]['botName'] = process.env.BOTNAME;
}
this.conversationLogger[fileName][timestamp] = logTextDb;
let updateObj = {
[fileName]:{
...this.conversationLogger[fileName]
}
}
// Add delay to ensure messages logged sequentially
await this.wait(this.msDelay);
try {
let result = await this.transcriptStorage.write(updateObj);
} catch(err) {
this.appInsightsClient.trackTrace({message: `Logger ${err.name} - ${path.basename(__filename)}`,severity: 3,properties: {'botName': process.env.BOTNAME, 'error':err.message,'callStack':err.stack}});
}
}
}
}
async wait(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
}
exports.CustomLogger = CustomLogger;

现在,您需要将其附加到index.js文件中的botframework适配器上。相关代码包括:

index.js

const { TranscriptLoggerMiddleware } = require('botbuilder');
const { CustomLogger } = require('./helpers/CustomLogger');
//
//Your code to create your adapter, etc.
//
const transcriptLogger = new TranscriptLoggerMiddleware(new CustomLogger(appInsightsClient));
adapter.use(transcriptLogger);

我假设你已经找到了你的index.js文件,但如果你需要任何帮助来设置并让成绩单记录器使用它,请告诉我。

编辑:根据请求,以下是该对象在CosmosDB中的样子。通常我会显示"from name",但由于我测试机器人的方式,它通过了"undefined"。

{
"id": "2020-3-21_IfHK46rZV42KH5g3dIUgKu-j",
"realId": "2020-3-21_IfHK46rZV42KH5g3dIUgKu-j",
"document": {
"botName": "itInnovationBot",
"1584797671549": "Innovation Bot: Hi! I'm the IT Innovation Bot. I can answer questions about the innovation team and capture your innovation ideas. Let me know how I can help!",
"1584797692355": "undefined: Hello",
"1584797692623": "Innovation Bot: Hello.",
"1584797725223": "undefined: Tell me about my team",
"1584797725490": "Innovation Bot: The innovation team is responsible for investigating, incubating, and launching new technologies and applications. The innovation focus areas are:nn* Chatbotsnn* Augmented Reality/Virtual Realitynn* Blockchainnn* Robotic Process Automationnn* AI & Machine LearningnnLet me know if you want to learn more about any of these technologies!",
"1584797746279": "undefined: Thanks",
"1584797746531": "Innovation Bot: You're welcome."
},
"_rid": "OsYpALLrTn2TAwAAAAAAAA==",
"_self": "dbs/OsYpAA==/colls/OsYpALLrTn0=/docs/OsYpALLrTn2TAwAAAAAAAA==/",
"_etag": ""a4008d12-0000-0300-0000-5e7618330000"",
"_attachments": "attachments/",
"_ts": 1584797747
}

要读回对话(即使仍处于对话中间(,您只需在机器人程序中创建一个连接器,重新创建密钥,然后按如下方式读取文件(在这种情况下,id被传递到我的功能中,是对话id(:

const transcriptStorage = new CosmosDbStorage({
serviceEndpoint: process.env.COSMOS_SERVICE_ENDPOINT,
authKey: process.env.COSMOS_AUTH_KEY,
databaseId: process.env.DATABASE,
collectionId: 'bot-transcripts',
partitionKey: process.env.BOTNAME
});
// Get today's date for datestamp
var currentDate = new Date();
var day = currentDate.getDate();
var month = currentDate.getMonth()+1;
var year = currentDate.getFullYear();
var datestamp = year + '-' + month + '-' + day;
var filename = `${datestamp}_${id}`;
var transcript = await transcriptStorage.read([filename]);

最新更新