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

Выбор пиццы

На этом шаге создадим сценарий, в котором бот будет предлагать клиенту пиццу на выбор, а затем формировать заказ.

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

Создайте файл сценария pizza.sc в папке src.

require: pizza.csv
name = pizza
var = pizza

theme: /

state: ChoosePizza
a: Какую пиццу будем заказывать сегодня?
script:
for (var id = 1; id < Object.keys(pizza).length + 1; id++) {
var regions = pizza[id].value.region;
if (_.contains(regions, $client.city)) {
var button_name = pizza[id].value.title;
$reactions.buttons({text: button_name, transition: 'GetName'})
}
}

state: GetName
script:
$session.pizza_name = $request.query;
go!: /ChooseVariant

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

state: ChooseVariant
a: Выберите, пожалуйста, вариант:
script:
for (var id = 1; id < Object.keys(pizza).length + 1; id++) {
if ($session.pizza_name == pizza[id].value.title) {
var variations = pizza[id].value.variations;
for(var i = 0; i < variations.length; i++){
var button_name = variations[i].name + " за " + variations[i].price + " руб."
$reactions.inlineButtons({text: button_name, callback_data: variations[i].id })
}
}
}
a: Для возврата в меню выбора пиццы, нажмите "Меню"
buttons:
"Меню" -> /ChoosePizza

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

state: GetVariant
event: telegramCallbackQuery
script:
$session.pizza_id = parseInt($request.query);
go!: /ChooseQuantity

state: ChooseQuantity
a: Выберите, пожалуйста, количество:
buttons:
"1" -> ./GetQuantity
"2" -> ./GetQuantity
"3" -> ./GetQuantity

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

state: GetQuantity
script:
$session.quantity = parseInt($request.query);
$session.cart.push({name: $session.pizza_name, id: $session.pizza_id, quantity: $session.quantity});
a: Хотите ли выбрать что-нибудь еще, или перейдем к оформлению заказа?
buttons:
"Меню" -> /ChoosePizza
buttons:
"Оформить заказ" -> /Cart

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

Подключение модулей

В начале сценария под тегом require подключаем справочник pizza.csv. Здесь var = pizza указывает на то, что далее обращаться к справочнику можно по ключевому слову pizza.

require: pizza.csv
name = pizza
var = pizza

Теперь подключим сценарий pizza.sc к основному сценарию main.sc:

require: pizza.sc

Стейты

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

  • ChoosePizza — выбор пиццы из справочника.
  • GetName — сохранение выбранного клиентом варианта.
  • ChooseVariant — выбор вариантов приготовления пиццы.
  • GetVariant — сохранение параметров для выбранной пиццы.
  • ChooseQuantity — выбор количества пиццы для заказа.
  • GetQuantity — сохранение введенного количества пиццы.

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

ChoosePizza

На этом этапе клиент уже выбрал город, в котором он хочет заказать пиццу. Поэтому выведем из каталога список из пицц, доступных в этом городе.

state: ChoosePizza
a: Какую пиццу будем заказывать сегодня?
script:
for (var id = 1; id < Object.keys(pizza).length + 1; id++) {
var regions = pizza[id].value.region;
if (_.contains(regions, $client.city)) {
var button_name = pizza[id].value.title;
$reactions.buttons({text: button_name, transition: 'GetName'})
}
}

В скрипте стейта ChoosePizza обращаемся к справочнику pizza.csv и выбираем названия пицц, которые можно заказать в выбранном городе. Затем с помощью функции $reactions.buttons используем выбранные параметры в качестве названия кнопок и добавляем переход в стейт GetName.

GetName

Теперь сохраним выбор клиента. В скрипте стейта GetName сохраняем название выбранной пиццы в переменную $session.pizza_name. Мы сможем использовать её для получения доступа к информации о данной пицце и отображения ее названия в корзине. Затем осуществим переход в стейт ChooseVariant.

state: GetName
script:
$session.pizza_name = $request.query;
go!: /ChooseVariant

ChooseVariant

В скрипте стейта ChooseVariant, по аналогии со скриптом для выбора пиццы, создаем кнопки для выбора варианта приготовления. На этот раз воспользуемся функцией $reactions.inlineButtons. В отличие от $reactions.buttons такие кнопки отображаются внутри диалога в виде реплик бота.

state: ChooseVariant
a: Выберите, пожалуйста, вариант:
script:
for (var id = 1; id < Object.keys(pizza).length + 1; id++) {
if ($session.pizza_name == pizza[id].value.title) {
var variations = pizza[id].value.variations;
for(var i = 0; i < variations.length; i++){
var button_name = variations[i].name + " за " + variations[i].price + " руб."
$reactions.inlineButtons({text: button_name, callback_data: variations[i].id })
}
}
}
a: Для возврата в меню выбора пиццы, нажмите "Меню"
buttons:
"Меню" -> /ChoosePizza

GetVariant

В стейте GetVariant событие telegramCallbackQuery срабатывает по клику на инлайн-кнопку из стейта ChooseVariant. В скрипте сохраняем параметры пиццы в переменную $session.pizza_id. Мы сможем использовать её для получения доступа к информации о данной пицце и отображения ее в корзине. Затем осуществляем переход в стейт ChooseQuantity для выбора количества пицц.

state: GetVariant
event: telegramCallbackQuery
script:
$session.pizza_id = parseInt($request.query);
go!: /ChooseQuantity

ChooseQuantity

В стейте ChooseQuantity клиент выбирает количество пицц кликом на соответствующую кнопку и переходит в стейт GetQuantity.

state: ChooseQuantity
a: Выберите, пожалуйста, количество:
buttons:
"1" -> ./GetQuantity
"2" -> ./GetQuantity
"3" -> ./GetQuantity

GetQuantity

В скрипте стейта GetQuantity сохраняем количество выбранных пицц в переменную $session.quantity, а также добавляем выбранный вариант в корзину с помощью функции $session.cart.push.

Далее добавим две кнопки Меню и Оформить заказ. По ним будем решать, в какой стейт отправить клиента дальше: обратно в меню или к корзине для оформления заказа.

state: GetQuantity
script:
$session.quantity = parseInt($request.query);
$session.cart.push({name: $session.pizza_name, id: $session.pizza_id, quantity: $session.quantity});
a: Хотите ли выбрать что-нибудь еще, или перейдем к оформлению заказа?
buttons:
"Меню" -> /ChoosePizza
buttons:
"Оформить заказ" -> /Cart

ClickButtons

Добавим вложенный стейт ClickButtons в стейты ChoosePizza, ChooseVariant и ChooseQuantity. Он будет выполнять такую же функцию, как и в сценарии main.sc.

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

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

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

Telegram канал: выбор пиццы Telegram канал: выбор пиццы: количество Telegram канал

Далее перейдем к оформлению заказа.