Node.js 如何在我的bot中实现某种会话?

Node.js 如何在我的bot中实现某种会话?,node.js,botframework,Node.js,Botframework,我正在使用Microsoft Bot Framework SDK 4节点JS,将部署在Skype上。我想在我的bot中实现某种会话。例如,如果用户在“x”时间内没有与机器人进行交互,则对话将结束 目前,我使用“onMessage”函数在用户每次向bot发送消息时更新一个变量,并将该时间与用户上次交互的时间进行比较。如果超过时间限制,则对话结束 但问题是,这种方法不适用于超过1个用户。因此,如果有两个人与bot交互,那么每当这些用户中的任何一个与bot交互时,计时器变量都会更新 但是,我想为每个用

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

目前,我使用“onMessage”函数在用户每次向bot发送消息时更新一个变量,并将该时间与用户上次交互的时间进行比较。如果超过时间限制,则对话结束

但问题是,这种方法不适用于超过1个用户。因此,如果有两个人与bot交互,那么每当这些用户中的任何一个与bot交互时,计时器变量都会更新

但是,我想为每个用户创建这个计时器变量的新实例,并在特定用户与bot交互时更新它


我如何才能做到这一点?

您需要根据下面引用的部分使用状态管理:

机器人本质上是无状态的。一旦部署了bot,它可能不会 在同一流程中或在同一台机器上从一圈运行到另一圈 下一个但是,您的bot可能需要跟踪 对话,以便它能够管理自己的行为并记住答案 回答前面的问题。Bot的状态和存储功能 frameworksdk允许您向bot添加状态。机器人使用状态 用于管理和保持状态的管理和存储对象。国家 manager提供了一个抽象层,允许您访问状态 使用属性访问器的属性,独立于 底层存储

这主要基于使用两个对象,即
UserState
ConversationState
MemoryStorage
来模拟存储

在定义类和创建对象之后,下面的示例演示了它们的用法:

// 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;
然后,您可以在运行时轻松地使用访问器来读取和写入状态信息


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

要进一步了解Ali的答案

使用超时结束对话不是一种好的做法,因为当您向外扩展时,消息可能会路由到bot的不同实例,并且超时不会被正确取消。一个更好的方法是保存用户上次在userState中向bot发送消息的时间,并在下次用户在响应之前向bot发送消息时检查时间差。请看下面的代码片段

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();
    }
  }
const TIMEOUT=5000;
//提示
异步promptForName(步骤){
this.profileAccessor.set(step.context,{lastMessage:new Date()});
return wait step.prompt(NAME_prompt,“您叫什么名字?”);
}
异步captureName(步骤){
const profile=wait this.profileAccessor.get(step.context);
if(new Date().getTime()-new Date(profile.lastMessage).getTime()