如果最终用户未回复,如何在一定时间后关闭TextPrompt

时间:2019-06-13 10:48:43

标签: javascript node.js typescript botframework

在Microsoft chatbot SDK v4中,我想知道如何以编程方式关闭“任何类型的提示,TextPrompt,ConfirmPrompt ...等”提示,如果用户未回复,则在一段时间后结束对话框。

我已经尝试过使用settimeout和sc.endDialog,但是它不起作用并给了我

private promptForNameStep = async (step: WaterfallStepContext<UserProfile>) => {

setTimeout(async () => {
   console.log('I am here!');
   await step.endDialog();
}, 5000);

        const userProfile = await this.userProfileAccessor.get(step.context);

        if (userProfile.name === undefined) {
            // prompt for name, if missing
            return await step.prompt(NAME_PROMPT, i18n.__('salutation.your_name'));
        }
        return await step.next();
    }
(node:21084) UnhandledPromiseRejectionWarning: TypeError: Cannot perform 'get' on a proxy that has been revoked
    at UserState.load (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-core/src/botState.ts:84:48)
    at BotStatePropertyAccessor.get (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-core/src/botStatePropertyAccessor.ts:97:43)
    at SkillDialog.getStateFromAccessor (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/src/dialogs/skill/skillDialog.ts:164:68)
    at SkillDialog.executeStep (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/src/dialogs/skill/skillDialog.ts:91:47)
    at Array.stepsMethods.push (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/src/dialogs/skill/skillDialog.ts:149:29)
    at WaterfallDialog.onStep (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-dialogs/src/waterfallDialog.ts:198:44)
    at WaterfallDialog.runStep (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-dialogs/src/waterfallDialog.ts:225:31)
    at WaterfallDialog.resumeDialog (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-dialogs/src/waterfallDialog.ts:166:27)
    at WaterfallStepContext.endDialog (/Users/macbook/Workspace/bot/chatbot/templates/Enterprise-Template/src/typescript/enterprise-bot/node_modules/botbuilder-dialogs/src/dialogContext.ts:269:33)
    at <anonymous>
(node:21084) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:21084) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我希望对话框关闭,但出现上述错误。

1 个答案:

答案 0 :(得分:0)

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

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

希望这会有所帮助!