如何在漫游器中实现某种会话?

时间:2019-07-03 13:17:56

标签: node.js botframework

我正在使用Microsoft Bot Framework SDK 4节点JS,并将其部署在Skype上。我想在我的机器人中实施某种会话。例如,如果用户未在“ x”时间内与机器人进行互动,则对话将结束。

当前,我每次用户向机器人发送消息时都使用“ onMessage”功能更新变量,并将该时间与用户上一次交互的时间进行比较。如果超过时间限制,则对话结束。

但是问题是,此方法不适用于1个以上的用户。因此,如果有2个人与该机器人进行交互,则每次这些用户中的任何一个与该机器人进行交互时,timer变量都会更新。

但是,我想为每个用户创建此计时器变量的新实例,并在该特定用户与机器人进行交互时对其进行更新。

我该怎么做?

2 个答案:

答案 0 :(得分:0)

为此,您需要根据下面documentation中引用的部分使用状态管理:

  

机器人本质上是无状态的。部署您的漫游器后,可能不会   从一转到同一进程或在同一台机器上运行   下一个。但是,您的漫游器可能需要跟踪   对话,以便它可以管理其行为并记住答案   以前的问题。 Bot的状态和存储功能   Framework SDK允许您向机器人添加状态。机器人使用状态   管理和存储对象以管理和保持状态。状态   管理器提供了一个抽象层,可让您访问状态   使用属性访问器的属性,与类型无关   基础存储。

这主要是基于使用UserStateConversationStateMemoryStorage这两个对象来模拟存储。

下面是example,说明了在定义类和创建对象之后它们的用法:

// The accessor names for the conversation data and user profile state property accessors.
const CONVERSATION_DATA_PROPERTY = 'conversationData';
const USER_PROFILE_PROPERTY = 'userProfile';

class StateManagementBot extends ActivityHandler {
    constructor(conversationState, userState) {
        super();
        // Create the state property accessors for the conversation data and user profile.
        this.conversationData = conversationState.createProperty(CONVERSATION_DATA_PROPERTY);
        this.userProfile = userState.createProperty(USER_PROFILE_PROPERTY);

        // The state management objects for the conversation and user state.
        this.conversationState = conversationState;
        this.userState = userState;

然后,您可以在运行时轻松地使用访问器来读取和写入状态信息。

您也可以查看文档中提到的sample,以更好地理解。

答案 1 :(得分:0)

稍微扩展一下Ali的答案...

使用超时来结束对话不是一个好习惯,因为向外扩展时,消息可能会路由到该漫游器的不同实例,并且超时不会正确取消。更好的方法是将用户上次向机器人发送消息给机器人的时间保存下来,并在用户下一次向机器人发送消息给机器人响应之前检查时间差。看看下面的代码片段。

const TIMEOUT = 5000;



  // Prompts
  async promptForName(step) {
    this.profileAccessor.set(step.context, { lastMessage: new Date() });    
    return await step.prompt(NAME_PROMPT, "What is your name?");
  }

  async captureName(step) {
    const profile = await this.profileAccessor.get(step.context);
    if (new Date().getTime() - new Date(profile.lastMessage).getTime() < TIMEOUT) {
      profile.name = step.result;
      profile.lastMessage = new Date();
      this.profileAccessor.set(step.context, profile);

      await this.userState.saveChanges(step.context);

      return await step.next();
    } else {
      await step.context.sendActivity("Sorry, you took too long to respond");
      return await step.endDialog();
    }
  }