Как закрыть TextPrompt через определенное время, если пользователь не отвечает - PullRequest
0 голосов
/ 13 июня 2019

В 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 голосов
/ 13 июня 2019

Использование тайм-аута для завершения разговора не является хорошей практикой, поскольку при масштабировании сообщения могут перенаправляться на разные экземпляры бота, и тайм-аут не будет корректно отменен.Лучший подход - сохранить последний раз, когда пользователь отправил сообщение боту в userState, и проверить разницу во времени, когда пользователь в следующий раз отправит сообщение боту, прежде чем ответить.Посмотрите на фрагменты кода ниже.

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

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...