Перейти к содержанию

События диалогов

Виды обрабатываемых событий

onInputDialogBegin

Данный обработчик вызывается перед началом работы элемента ввода данных, с которым связана переменная (с указанным кодом или вообще любая). Если в сценарии бота есть несколько элементов ввода, связанных с указанной переменной, этот обработчик будет вызываться для каждого из них.

С помощью этого обработчика можно настраивать работу элемента, устанавливая различные свойства в объекте context.output.result:

  • context.output.result.promptText — строка, которая будет отправлена пользователю в качестве запроса ввода.
  • context.output.result.suggestedActions — массив строк или объектов CardAction, которые будут показаны пользователю в виде кнопок.
  • context.output.result.unrecognizedPromptText — строка, которая будет отправлена пользователю в случае нераспознанного ввода.

onInputDialogBegin

TypeScript
1
2
3
4
5
6
function onInputDialogBegin(
  variableCode: OptionalParameter<VariableCodeType>,
  callback: (
    botEvent: InputDialogBeginEvent
  ) => Promise<void>
): void
  • variableCode — код переменной, с которой связан элемент ввода (см. VariableCodeType). При указании null, undefined, "*" или пустой строки обработчик вызывается для любой переменной (см. OptionalParameter).
  • callback — функция, которая будет вызвана в начале работы элемента ввода.
  • botEvent — объект события, который можно использовать в теле функции (см. InputDialogBeginEvent).

Пример

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

TypeScript
onInputDialogBegin('store_name', async () => {
  if (context.input.variables.store_name) {
    // Если переменная с названием магазина уже записана (например, если был один подходящий вариант),
    // можно ничего не делать, т. к. если у свойства «Спрашивать» элемента ввода текста выбран вариант
    // «Только если значение не заполнено», то текущий элемент ввода будет полностью пропущен
    return;
  }

  const fuseArray = context.input.variables.fuse_results as any[];

  // Если есть несколько подходящих вариантов, но не больше пяти,
  if (fuseArray && fuseArray.length > 1 && fuseArray.length <= 5) {
    // то пользователю сразу предлагается выбор из подходящих вариантов
    context.output.result.promptText = 'Мы нашли несколько магазинов с похожим названием. Выберите один из них.';
    context.output.result.suggestedActions = fuseArray.map(result => result.item);
  }

  // Если подходящих вариантов нет или слишком много, элемент ввода работает как обычно.
});

onInputDialogBeforeInterruption

Данный обработчик вызывается непосредственно после выполнения пользователем ввода. В теле функции можно переопределить возможность прерывания работы элемента. Обработчик вызывается только для элементов ввода, с которыми связана переменная с указанным кодом.

С помощью этого обработчика можно настраивать работу элемента, устанавливая свойство в объекте context.output.result:

  • context.output.result.allowInterruptions — поле, в которое можно записать логическое значение (true/false), которое определит, можно ли прерывать работу текущего элемента ввода. Например, можно запретить прерывать работу элемента ввода распознаванием интента в прерывающем сценарии, если ввод пользователя полностью совпал с одним из заранее известных вариантов ответов.

onInputDialogBeforeInterruption

TypeScript
1
2
3
4
5
6
function onInputDialogBeforeInterruption(
  variableCode: OptionalParameter<VariableCodeType>,
  callback: (
    botEvent: InputDialogBeforeInterruptionEvent
  ) => Promise<void>
): void
  • variableCode — код переменной, с которой связан элемент ввода (см. VariableCodeType). При указании null, undefined, "*" или пустой строки обработчик вызывается для любой переменной (см. OptionalParameter).
  • callback — функция, которая будет вызвана после выполнения ввода пользователем.
  • botEvent — объект события, который можно использовать в теле функции (см. InputDialogBeforeInterruptionEvent).

onInputDialogValueRecognized

Данный обработчик вызывается после успешного распознавания ввода пользователя. В теле функции можно переопределить результат распознавания и переопределить текст, который будет отправлен в ответ. Обработчик вызывается только для элементов ввода, с которыми связана переменная с указанным кодом.

С помощью этого обработчика можно проводить дополнительную обработку распознанного значения, устанавливая различные свойства в объекте context.output.result:

  • context.output.result.recognized — логическое значение (true/false), которое переопределяет, было ли распознано введенное пользователем значение.
  • context.output.result.outputValue — переопределенное распознанное значение, которое будет записано в переменную, связанную с элементом ввода.

Например, введенное пользователем значение можно сравнивать с заранее известным списком допустимых значений и записывать результат в связанную переменную только в том случае, если значение найдено в списке.

onInputDialogValueRecognized

TypeScript
1
2
3
4
5
6
function onInputDialogValueRecognized(
  variableCode: OptionalParameter<VariableCodeType>,
  callback: (
    botEvent: InputDialogValueRecognizedEvent
  ) => Promise<void>
): void
  • variableCode — код переменной, с которой связан элемент ввода (см. VariableCodeType). При указании null, undefined, "*" или пустой строки обработчик вызывается для любой переменной (см. OptionalParameter).
  • callback — функция, которая будет вызвана после успешного распознавания ввода пользователя.
  • botEvent — объект события, который можно использовать в теле функции (см. InputDialogValueRecognizedEvent).

Пример

В этом примере при каждом вводе пользователем названия магазина происходит нечеткий поиск по списку всех магазинов, после чего поведение элемента ввода меняется в зависимости от результатов поиска.

TypeScript
onInputDialogValueRecognized('store_name', async (botEvent) => {
  if (context.input.variables.store_name) {
    return;
  }

  const searchOptions = {
      method: 'GET',
      url: baseUrl + storesEndpointRoute,
  };
  const storesResponse = await axios.request(searchOptions);

  const store = storesResponse.data.find(s => s.toLowerCase() == botEvent.userInputText.toLowerCase());

  if (store) {
    // Если найдено полное совпадение, записываем найденный элемент в результат
    context.output.result.recognized = true;
    context.output.result.outputValue = store;
    return;
  }

  const fuse = new Fuse(storesResponse.data, fuseOptions);

  const searchResults = fuse.search(botEvent.userInputText);
  console.log(searchResults);

  if (!searchResults.length) {
    context.output.result.recognized = false;
    context.output.result.unrecognizedPromptText = 'Мы не нашли ничего похожего. Уточните название.';
    context.output.result.suggestedActions = null;
    return;
  }

  if (searchResults.length == 1) {
    context.output.result.recognized = true;
    context.output.result.outputValue = searchResults[0].item;
    return;
  }

  if (searchResults.length > 1 && searchResults.length <= 5) {
    context.output.result.recognized = false;
    context.output.result.unrecognizedPromptText = 'Мы нашли несколько магазинов с похожим названием. Выберите один из них.';
    context.output.result.suggestedActions = searchResults.map(result => result.item);
    return;
  }

  if (searchResults.length > 5) {
    context.output.result.recognized = false;
    context.output.result.unrecognizedPromptText = 'Мы нашли слишком много магазинов с похожим названием. Уточните название.';
    context.output.result.suggestedActions = null;
    return;
  }
});