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

Оформление заказа

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

Функции для работы с корзиной

Создайте файл function.js в папке src.

function deleteFromCart(name){
var $session = $jsapi.context().session;
for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
if(current_position.name === name){
$session.cart.splice(i, 1);
}
}
log('!!!!!! CART: ' + JSON.stringify($session.cart));
}

function getTotalSum(){
var totalSum = 0;
var $session = $jsapi.context().session;

for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
for(var id = 1; id < Object.keys(pizza).length + 1; id++){
if (current_position.name === pizza[id].value.title){
var variation = _.find(pizza[id].value.variations, function(variation){
return variation.id === current_position.id;
});
totalSum += variation.price * current_position.quantity;
}
}
}
log("!!!!!!!!!!!! totalSum = " + totalSum);
return totalSum;
}

function editText(messageId, text) {
var $response = $jsapi.context().response;
var reply = {
type: "raw",
body: {
text: text,
message_id: messageId,
reply_markup: {
"resize_keyboard": false,
}
},
method: "editMessageText"
};

$response.replies = $response.replies || [];
$response.replies.push(reply);
}

Здесь:

  • function deleteFromCart(name) — удаление товара из корзины;
  • function getTotalSum() — подсчет общей суммы заказа;
  • function editText(messageId, text) — редактирование предыдущих сообщений.

deleteFromCart()

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

function deleteFromCart(name){
var $session = $jsapi.context().session;
for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
if(current_position.name === name){
$session.cart.splice(i, 1);
}
}
log('!!!!!! CART: ' + JSON.stringify($session.cart));
}

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

Затем с помощью функции log() выведем сообщение о внесенных изменениях. Во вкладке Логи при удалении товара будет появляться следующее сообщение:

!!!!!! CART: [{"name":"Пепперони","id":7,"quantity":1}]

getTotalSum()

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

Создадим переменную totalSum, в которой будем хранить сумму. Пройдемся циклом по всем товарам в корзине и для каждого вида пицц посчитаем сумму, умножив стоимость variation.price на количество конкретного товара current_position.quantity.

function getTotalSum(){
var totalSum = 0;
var $session = $jsapi.context().session;

for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
for(var id = 1; id < Object.keys(pizza).length + 1; id++){
if (current_position.name === pizza[id].value.title){
var variation = _.find(pizza[id].value.variations, function(variation){
return variation.id === current_position.id;
});
totalSum += variation.price * current_position.quantity;
}
}
}
log("!!!!!!!!!!!! totalSum = " + totalSum);
return totalSum;
}

Затем с помощью функции log() выведем сумму всех товаров в корзине. Во вкладке Логи появится следующее сообщение:

!!!!!!!!!!!! totalSum = 299

editText()

Напишем функцию, которая будет редактировать сообщения. Функция editText(messageId, text) использует метод editMessageText и позволяет редактировать предыдущие сообщения бота. В процессе редактирования корзины мы заменяем название удаленной пиццы на сообщение 'Удален'.

function editText(messageId, text) {
var $response = $jsapi.context().response;
var reply = {
type: "raw",
body: {
text: text,
message_id: messageId,
reply_markup: {
"resize_keyboard": false,
}
},
method: "editMessageText"
};

$response.replies = $response.replies || [];
$response.replies.push(reply);
}
предупреждение
Редактирование предыдущих сообщений доступно только в Telegram.

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

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

require: function.js

theme: /

state: Cart
intent!: /корзина
a: Ваша корзина:
script:
$temp.totalSum = 0;
var n = 0;
for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
for(var id = 1; id < Object.keys(pizza).length + 1; id++){
if (current_position.name == pizza[id].value.title){
var variation = _.find(pizza[id].value.variations, function(variation){
return variation.id === current_position.id;
});

n++;

if (!variation) {
$reactions.answer("Что-то пошло не так, вариант не найден для id " + current_position.id);
} else {
$reactions.answer(n + ". " + current_position.name + ", " + variation.name + "\nЦена: " + variation.price + "\nКоличество: " + current_position.quantity);

$reactions.inlineButtons({text: "Удалить", callback_data: current_position.name});

$temp.totalSum += variation.price * current_position.quantity;
}
}
}
}
$session.messageId = $request.rawRequest.message.message_id + n + 2;

a: Общая сумма заказа: {{ $temp.totalSum }} рублей.
a: Если все верно, отправьте свой номер телефона, и наш менеджер с вами свяжется.
buttons:
{text: "Отправить номер телефона", request_contact: true}
"Меню" -> /ChoosePizza

state: Edit
event: telegramCallbackQuery
script:
var name = $request.rawRequest.callback_query.data;
deleteFromCart(name);
var message_id = $request.rawRequest.callback_query.message.message_id;

editText(message_id, 'Удален');
editText($session.messageId, 'Общая сумма заказа: ' + getTotalSum() + ' руб.');
if: $session.cart.length == 0
a: Вы очистили корзину
go!: /ChoosePizza

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

state: GetPhoneNumber
event: telegramSendContact
script:
$client.phone_number = $request.rawRequest.message.contact.phone_number;
a: Спасибо! Наш менеджер свяжется с вами по номеру телефона {{ $client.phone_number }}.

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

В начале сценария под тегом require подключаем справочник function.js.

require: function.js

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

require: cart.sc

Стейты

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

  • Cart — вывод содержимого корзины и общей суммы заказа.
  • Edit — редактирование корзины.
  • GetPhoneNumber — отправка номера телефона для подтверждения заказа.

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

Cart

state: Cart
intent!: /корзина
a: Ваша корзина:
script:
$temp.totalSum = 0;
var n = 0;
for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
for(var id = 1; id < Object.keys(pizza).length + 1; id++){
if (current_position.name == pizza[id].value.title){
var variation = _.find(pizza[id].value.variations, function(variation){
return variation.id === current_position.id;
});
n++;
if (!variation) {
$reactions.answer("Что-то пошло не так, вариант не найден для id " + current_position.id);
} else {
$reactions.answer(n + ". " + current_position.name + ", " + variation.name + "\nЦена: " + variation.price + "\nКоличество: " + current_position.quantity);
$reactions.inlineButtons({text: "Удалить", callback_data: current_position.name});
$temp.totalSum += variation.price * current_position.quantity;
}
}
}
}
$session.messageId = $request.rawRequest.message.message_id + n + 2;

a: Общая сумма заказа: {{ $temp.totalSum }} рублей.
a: Если все верно, отправьте свой номер телефона, и наш менеджер с вами свяжется.
buttons:
{text: "Отправить номер телефона", request_contact: true}
"Меню" -> /ChoosePizza

Интент

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

Перейдите на вкладку NLU > Интенты, расположенную в боковом меню. Создайте интент и добавьте в поле Тренировочные фразы следующие фразы:

покажи корзину
что там в корзине
что в корзине
корзина

Создание интента корзина

Скрипт

Здесь бот выводит список всех товаров из корзины и их полную стоимость.

Создадим переменную $temp.totalSum, в которую будем записывать стоимость товаров.

script:
$temp.totalSum = 0;
var n = 0;
for(var i = 0; i < $session.cart.length; i++){
var current_position = $session.cart[i];
for(var id = 1; id < Object.keys(pizza).length + 1; id++){
if (current_position.name == pizza[id].value.title){
var variation = _.find(pizza[id].value.variations, function(variation){
return variation.id === current_position.id;
});

n++;

if (!variation) {
$reactions.answer("Что-то пошло не так, вариант не найден для id " + current_position.id);
} else {
$reactions.answer(n + ". " + current_position.name + ", " + variation.name + "\nЦена: " + variation.price + "\nКоличество: " + current_position.quantity);

$reactions.inlineButtons({text: "Удалить", callback_data: current_position.name});
$temp.totalSum += variation.price * current_position.quantity;
}
}
}
}
$session.messageId = $request.rawRequest.message.message_id + n + 2;

Теперь предложим клиенту отправить номер телефона, чтобы завершить заказ. Для этого поставим две кнопки: Отправить номер телефона и Меню. Первая будет вызывать API метод Telegram request_contact для отправки номера телефона, а вторая направлять в стейт ChoosePizza.

a: Если все верно, отправьте свой номер телефона, и наш менеджер с вами свяжется.
buttons:
{text: "Отправить номер телефона", request_contact: true}
"Меню" -> /ChoosePizza

Edit

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

В процессе редактирования корзины мы заменяем название удаленной пиццы на сообщение Удален. Если корзина окажется пустой, то бот выведет сообщение Вы очистили корзину и перейдет в стейт ChoosePizza.

state: Edit
event: telegramCallbackQuery
script:
var name = $request.rawRequest.callback_query.data;
deleteFromCart(name);
var message_id = $request.rawRequest.callback_query.message.message_id;

editText(message_id, 'Удален');
editText($session.messageId, 'Общая сумма заказа: ' + getTotalSum() + ' руб.');
if: $session.cart.length == 0
a: Вы очистили корзину
go!: /ChoosePizza

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

Добавим вложенный стейт ClickButtons:

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

GetPhoneNumber

Для оформления заказа попросим клиента оставить свой номер телефона. Как только он отправит свой номер, сработает событие telegramSendContact. Полученный номер будем хранить в переменной $client.phone_number.

state: GetPhoneNumber
event: telegramSendContact
script:
$client.phone_number = $request.rawRequest.message.contact.phone_number;
a: Спасибо! Наш менеджер свяжется с вами по номеру телефона {{ $client.phone_number }}.

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

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

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

Далее перейдем к тестированию сценария.