Перейти к основному содержимому

Выбор города

На этом шаге мы создадим конфигурационный файл бота, а также напишем основной сценарий бота. В нем бот будет предлагать клиенту выбрать город доставки с помощью двух кнопок Санкт-Петербург и Москва.

Конфигурационный файл

Создайте конфигурационный файл бота chatbot.yaml:

# Название проекта
name: pizza-bot

# Точка входа
entryPoint:
- main.sc

# Параметры NLU:
botEngine: v2 # Версия диалогового движка
language: ru # Язык бота

nlp:
intentNoMatchThresholds:
phrases: 0.2
patterns: 0.2

Создание сценария

Создайте файл main.sc в папке src. В нем будет основной сценарий работы бота:

theme: /

state: Start
q!: $regex</start>
script:
$context.session = {};
$context.client = {};
$context.temp = {};
$context.response = {};
a: Привет! Я электронный помощник. Помогу вам заказать пиццу.
go!: /ChooseCity

state: ChooseCity || modal = true
a: Выберите свой город.
buttons:
"Санкт-Петербург" -> ./RememberCity
"Москва" -> ./RememberCity

state: RememberCity
script:
$client.city = $request.query;
$session.cart = [];
go!: /ChoosePizza

state: ClickButtons
q: *
a: Нажмите, пожалуйста, кнопку.
go!: ..

state: CatchAll || noContext=true
event!: noMatch
a: Я вас не понимаю.

Основной сценарий бота состоит из следующих стейтов:

  • Start — начало работы. Бот приветствует пользователя и предлагает выбрать город для доставки.
  • ChooseCity — выбор города из двух предложенных вариантов.
  • RememberCity — «запоминание» выбранного города.
  • ClickButtons — подсказывает пользователю, что бот воспринимает только нажатие кнопок.
  • CatchAll — реагирует на любой непредусмотренный сценарием ответ пользователя.

Структура сценария

Start

В стейте Start запускается сценарий. Бот посылает приветственное сообщение и предлагает помочь заказать пиццу.

state: Start
q!: $regex</start>
script:
$context.session = {};
$context.client = {};
$context.temp = {};
$context.response = {};
a: Привет! Я электронный помощник. Помогу вам заказать пиццу.
go!: /ChooseCity

Обнуляем переменные в скрипте для начала нового диалога, так как бот должен «забыть» ответы клиента из предыдущего диалога. Предыдущие ответы хранятся в переменных объекта $context.

С помощью тега go! осуществляется переход в стейт ChooseCity.

ChooseCity

state: ChooseCity || modal = true
a: Выберите свой город.
buttons:
"Санкт-Петербург" -> ./RememberCity
"Москва" -> ./RememberCity

Клиент должен выбрать один из городов с помощью кнопок Санкт-Петербург и Москва. Они задаются с помощью тега buttons.

Вложенные данные тега buttons должны соответствовать шаблону: <json-node> -> <string>. В левой части — строка или объект, определяющие текст или тело кнопки. В правой части — строка, определяющая путь перехода при нажатии кнопки. В нашем сценарии переход по нажатию осуществляется в стейт RememberCity.

Флаг modal = true используется для того, чтобы бот не мог перейти в следующее состояние, пока пользователь не выберет город.

RememberCity

state: RememberCity
script:
$client.city = $request.query;
$session.cart = [];
go!: /ChoosePizza

Выбор клиента будет обработан с помощью $request.query и записан в переменную $client.city. Бот будет предлагать последующие варианты ответов в зависимости от выбранного города.

С помощью тега go! осуществляется переход в стейт ChoosePizza, работа которого будет описана в следующих шагах.

ClickButtons

state: ClickButtons
q: *
a: Нажмите, пожалуйста, кнопку.
go!: ..

Стейт ClickButtons реагирует на любой текстовый ввод клиента и выводит ответ Нажмите, пожалуйста, кнопку. Оно необходимо, так как modal=true не дает текстовому вводу попасть в глобальный CatchAll. Затем осуществляем переход в состояние на уровень выше go!: .., так как нам важно, чтобы клиент выбрал город.

CatchAll

state: CatchAll || noContext=true
event!: noMatch
a: Я вас не понимаю.

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

Воспользуемся флагом noContext = true, чтобы контекст не изменился при попадании в стейт CatchAll.

Тестирование

Подключим канал в Telegram и протестируем результат работы сценария. Результат запуска:

Telegram канал Telegram канал

Далее перейдем к работе со справочником.