我正在本地 MongoDB 存储中维护机器人状态。当我尝试使用 directline-js 将对话移交给代理时,它显示错误 BotFrameworkAdapter.sendActivity(): Missing Conversation ID
。对话 ID 正在保存在 MongoDB 中
当我将中间层从Array更改为MongoDB时,出现了问题。我已经使用带有数组和默认内存存储的 directline-js 成功实现了相同的机器人与人类的交接。
BotFramework 中的内存存储
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder')
const memoryStorage = new MemoryStorage();
conversationState = new ConversationState(memoryStorage);
userState = new UserState(memoryStorage);
用于移交代理的中间层
case '#connect':
const user = await this.provider.connectToAgent(conversationReference);
if (user) {
await turnContext.sendActivity(`You are connected to
${ user.userReference.user.name }\n ${ JSON.stringify(user.messages) }`);
await this.adapter.continueConversation(user.userReference, async
(userContext) => {
await userContext.sendActivity('You are now connected to an agent!');
});
}
else {
await turnContext.sendActivity('There are no users in the Queue right now.');
}
使用 MongoDB 时,this.adapter.continueConversation
会引发错误。
使用数组时,它工作得很好。 MongoDB 和 Array 对象在结构上都很相似。
最佳答案
由于这适用于 MemoryStorage 而不是您的 MongoDB 实现,我猜测您的 MongoDB 实现有问题。本次回答将重点围绕这一点。如果不是这种情况,请提供您的 MongoDb 实现和/或您的存储库的链接,我可以解决这个问题。
<小时/>仅当您想使用自定义模型/类型/接口(interface)时才需要 Mongoose。对于实现 BotState
的存储,你只需要写一个自定义的 Storage适配器。
基本知识 are documented here 。虽然是为 C# 编写的,但您仍然可以将这些概念应用到 Node。
1。安装mongodb
npm i -S mongodb
2。创建一个 MongoDbStorage
类文件
MongoDbStorage.js
var MongoClient = require('mongodb').MongoClient;
module.exports = class MongoDbStorage {
constructor(connectionUrl, db, collection) {
this.url = connectionUrl;
this.db = db;
this.collection = collection;
this.mongoOptions = {
useNewUrlParser: true,
useUnifiedTopology: true
};
}
async read(keys) {
const client = await this.getClient();
try {
var col = await this.getCollection(client);
const data = {};
await Promise.all(keys.map(async (key) => {
const doc = await col.findOne({ _id: key });
data[key] = doc ? doc.document : null;
}));
return data;
} finally {
client.close();
}
}
async write(changes) {
const client = await this.getClient();
try {
var col = await this.getCollection(client);
await Promise.all(Object.keys(changes).map((key) => {
const changesCopy = { ...changes[key] };
const documentChange = {
_id: key,
document: changesCopy
};
const eTag = changes[key].eTag;
if (!eTag || eTag === '*') {
col.updateOne({ _id: key }, { $set: { ...documentChange } }, { upsert: true });
} else if (eTag.length > 0) {
col.replaceOne({ _id: eTag }, documentChange);
} else {
throw new Error('eTag empty');
}
}));
} finally {
client.close();
}
}
async delete(keys) {
const client = await this.getClient();
try {
var col = await this.getCollection(client);
await Promise.all(Object.keys(keys).map((key) => {
col.deleteOne({ _id: key });
}));
} finally {
client.close();
}
}
async getClient() {
const client = await MongoClient.connect(this.url, this.mongoOptions)
.catch(err => { throw err; });
if (!client) throw new Error('Unable to create MongoDB client');
return client;
}
async getCollection(client) {
return client.db(this.db).collection(this.collection);
}
};
注意:我只对此做了一些测试 - 足以让它与 the Multi-Turn-Prompt Sample 很好地配合工作。 。使用风险由您自行承担,并根据需要进行修改。
我基于这三种存储实现的组合:
3。在您的机器人中使用它
index.js
const MongoDbStorage = require('./MongoDbStorage');
const mongoDbStorage = new MongoDbStorage('mongodb://localhost:27017/', 'testDatabase', 'testCollection');
const conversationState = new ConversationState(mongoDbStorage);
const userState = new UserState(mongoDbStorage);
关于node.js - 如何使用 NodeJs 和 Mongoose 在 Bot Framework 中本地使用 MongoDB 和 directline-js 进行状态管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57639411/