Оформление заказа
На этом шаге мы создадим сценарий для оформления заказа и функции, с помощью которых будут обработаны выбранные товары.
Функции для работы с корзиной
Создайте файл 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);
}
Создание сценария
Создайте файл сценария 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. Результат запуска:
Далее перейдем к тестированию сценария.