Есть ли способ отправить объект TimeOut от шага к другому в диалоге? - botBuilder v4 - Node.js - PullRequest
0 голосов
/ 21 июня 2019

В одном из шагов диалога моего бота я запускаю некоторые операции в функции setTimeout(). Цель состоит в том, чтобы очистить TimeOut на другом этапе в некоторых условиях.

async saveAdults(step) {
    if (step.result) {
      step.values.adults = step.result;
      const convId = step.context.activity.conversation.id;
      const format = "dddd DD MMMM YYYY";

      // Send partial notification in case of a delay of 5 minutes
      const data = {
        checkIn: step.values.checkIn,
        nights: step.values.nights,
        adults: "",
        children: ""
      };
      const timer = await sendPartialNotification(convId, data);
      // step.values.timer = timer;
      this.notificationProp.set(step.context, timer);
      await this.conversationState.saveChanges(step.context);
    }
    return await step.next();
  }
exports.sendPartialNotification = async (convId, data) => {
  const interval = 300000;
  const timer = setTimeout(() => {
    notify(convId, this.id, data, true);
  }, interval);
  return timer;
};
async notifyClient(step) {
  const timer = this.notificationProp.get(step.context);
  clearTimeout(timer);
  // …
}

Попытка сохранить объект TimeOut в step.values.timer или в состоянии диалога выдает эту ошибку, которая указывает, что невозможно проанализировать объект Timeout ...

TypeError: Converting circular structure to JSON

В качестве решения этой проблемы я думал о сохранении timer в Redis ..

Есть ли идеи? Спасибо.

1 Ответ

1 голос
/ 22 июня 2019

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

  1. Инициируйте таймер на шаге вперед.
async setTimer(step) {
  if (step.result) {
    const convId = step.context.activity.conversation.id;

    const data = {
      value1: someValue1,
      value2: someValue2
    };

    const timer = await sendPartialNotification(convId, data);

    this.notificationProp = { step: step.context, timer: timer };
    await this.conversationState.saveChanges(step.context);
  }
  return await step.next();
}
  1. На промежуточном этапе спросите клиента, не хотели бы он отменить таймер. У меня установлен таймер на 10 секунд.
    • Если пользователь отменяет, таймер очищается.
    • Если клиент отказывается или не отвечает до истечения 10 секунд, таймер не изменяется и работает.
async askClient(step) {
  const timer = this.notificationProp.timer;

  if (timer._idleTimeout > 0) {
    const message = MessageFactory.text(
      'Cancel the timer?',
      null,
      'expectingInput'
    );
    return await step.prompt('confirmPrompt', message);
  }
}
  1. Наконец, вывод результатов и уведомление клиента.
async notifyClient(step) {
  const stepResult = step.result;
  step.value = { timer: this.notificationProp.timer };

  if (stepResult === true) {
    console.log('TIMER PRE-CLEAR ', step.value.timer);

    const timer = step.value.timer;
    await clearTimeout(timer);

    console.log('TIMER POST-CLEAR', timer);
    step.context.sendActivity('Cancelling timer');
  } else {
    step.context.sendActivity('Timer not cancelled');
  }

  return await step.next();
}

Таймер не отменен и работает:

enter image description here

Таймер отменен:

enter image description here

Надежда на помощь!

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