Шаблон Yclients

Настройка шаблона

Идентификатор вашего филиала (или филиала вашего заказчика), он находится в разделе Обзор - Сводка в YCLIENTS (Рисунок 18)

Рисунок 18

Для работы с шаблоном, вам нужно в настройках проекта задать переменные:

Рисунок 18.1

yclients_url - https://store.salebot.pro/function/yclients2 yclients_company_id - идентификатор вашего филиала Yclients yclients_partner_token - partner_token ваш секретный ключ Yclients yclients_user_token - токен пользователя (как получить описано ниже) back=Назад;0 - текст и условие на кнопках Назад back_str=0. Назад - текст внизу списка (можно не передавать в запросе, но тогда нужно прописать ее в нужных местах) with_buttons=["0", "1", "2", "5", "8"] - для каких мессенджеров возвращать кнопки another_date=11. Другая дата - кнопка с текстом для даты buttons_type=reply - вид возвращаемой клавиатуры или inline remind_birthday_days=2 - за сколько дней до дня рождения отсылать спецпредложение back_to_main_menu=Для возврата в главное меню отправьте слово: Начало widget_id=283192 - идентификатор онлайн виджета для ссылки, используется для перехода в виджета и редактирования своих записей

Точка входа в бот

Рисунок 19

Зеленый блок на скриншоте — это главная точка входа. В нем пропишите условия (фразы) для запуска.

От него идет раздвоение, это проверка переменной клиента yclients_client_id, если она есть, то клиент в salebot уже связан с клиентом в yclients и можно отправлять клиента сразу в главное меню.

Если же переменной yclients_client_id у клиента нет, тогда:

  1. если клиент ватсап, отправляем запрос на поиск клиента и если такой не найдет, то запрос имени и отправка на запись на услугу.

  2. если клиент не ватсап, тогда запрос телефона и поиск клиента, если найден, то отправляем его в главное меню, если не найден тогда ввод имени и отправка на запись на услугу.

Поиск клиента происходит по номеру телефона, если по номеру клиент не найдет идет поиск по email. Запрос выглядит следующим образом:

Рисунок 20

Если клиент найден в карточку клиента в сейлбот запишутся его данные из yclients.

Клиент ищется вначале по номеру телефона, потом по email (если передан).

Онлайн запись на прием

Рисунок 21

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

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

Авторизация пользователя и получение токена

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

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

Внимание! При изменении пароля, токен также меняется и его нужно получить повторно.

Далее необходимо авторизовать пользователя в системе и получить секретный токен (в вызовах АПИ его надо подставлять в параметр «user_token».

Рисунок 22

Для получения токена необходимо сделать АПИ вызов, в котором указать логин и пароль нужного пользователя:

Рисунок 23

Ответ :#{custom_answer}

Тип запроса: POST-json

URL-запроса: #{yclients_url}

Сохраняемые значения из ответа:

user_token -> client.yclients_client_token

JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_auth", "login": "#{login}", "password": "#{password}"}

Блоки онлайн записи

Каждый переход с выбором (категории, услуги, мастер, дата и время) возвращает вот такие данные (* - это category, service, date и тд):

buttons_* - готовые варианты для кнопок str_* – для цифрового меню checker_* - цифра и название и для условия перехода, чтобы минимизировать возможность ошибки при записи клиента *_list_data - служебная, в ней список с данными, передается вместе с выбором пользователя для *_list - список, для произвольного использования, можно собственные кнопки или список делать

Также если что-то не работает выведите в нужном месте переменную #{custom_answer} - в ней выводится информация, что пошло не так.

Все блоки для выбора аналогичны, вначале запрос данных и проверка предыдущего ввода и в следующем блоке их вывод.

Выбор категории

Рисунок 24

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: buttons_categories -> buttons_categories; str_categories -> str_categories; checker_categories -> checker_categories; categories_list_data -> categories_list_data; categories_list -> categories_list JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_categories", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "buttons_type": "#{buttons_type}"} Назначение переменных при переходе: обнуляем все старые данные

В следующем блоке выводим услуги и кнопки и обнуляем переменные от старой записи для последующего запроса мастера и от него стрелка с условием #{checker_categories}, чтоб фильтровать ввод и сохранить его в input_category

Рисунок 24.1

В настройках стрелки указываем: Условие: #{checker_categories} Активировать “Пользователь вводит данные” Вводимые данные: input_category

Рисунок 24.2

Запись без выбора категорий

Категорию можно убрать, если они не нужны, тогда нужно заменить часть отвечающую за вывод сервисов.

Эта часть находится в дополнительных блоках:

Рисунок 25

Ее нужно вставить вместо той, которая уже в схеме записи.

Выбор услуги

Рисунок 26

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: buttons_services -> buttons_services; str_services -> str_services; checker_services -> checker_services; category_title -> category_title; category_id -> category_id; services_list_data -> services_list_data; services_list -> services_list JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_services", "input_category": "#{input_category}", "categories_list_data": "#{categories_list_data}", "currency": "руб", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "buttons_type": "#{buttons_type}"}

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

Рисунок 26.1
Рисунок 26.2

В настройках стрелки указываем:

Условие: #{checker_services} Активировать “Пользователь вводит данные” Вводимые данные: input_service

Выбор мастера

Рисунок 27

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: status -> status; buttons_staff -> buttons_staff; str_staff -> str_staff; checker_staff -> checker_staff; service_title -> service_title; service_id -> service_id; staff_list_data -> staff_list_data; staff_list -> staff_list JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_staff", "input_service": "#{input_service}", "services_list_data": "#{services_list_data}", "category_id": "#{category_id}", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "buttons_type": "#{buttons_type}"

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

Рисунок 27.1
Рисунок 28

В настройках стрелки указываем:

Условие: #{checker_staff} Активировать “Пользователь вводит данные” Вводимые данные: input_staff

Выбор даты

Рисунок 29

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: buttons_date -> buttons_date; str_date -> str_date; checker_date -> checker_date; staff_title -> staff_title; staff_id -> staff_id; staff_specialization -> staff_specialization; dates_list_data -> dates_list_data; date_list -> date_list JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_date", "input_staff": "#{input_staff}", "staff_list_data": "#{staff_list_data}", "service_id": "#{service_id}", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "another_date": "#{another_date}", "buttons_type": "#{buttons_type}"}

В следующем блоке выводим даты и кнопки, а также обнуляем переменные от старой записи для последующего запроса времени.

Рисунок 30

В настройках стрелки указываем:

Условие: #{checker_date} Активировать “Пользователь вводит данные” Вводимые данные: input_date

Рисунок 31

По умолчанию выводится 10 ближайших дат, 11 кнопка или номер в списке это возможность перейти на ввод произвольной даты.

Рисунок 32

Выбор времени

Рисунок 33

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: status -> status; buttons_time -> buttons_time; str_time -> str_time; checker_time -> checker_time; visit_date -> visit_date; times_list_data -> times_list_data; time_list -> time_list JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_time", "input_date": "#{input_date}", "dates_list_data": "#{dates_list_data}", "staff_id": "#{staff_id}", "user_date": "#{user_date}", "service_id": "#{service_id}", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "buttons_type": "#{buttons_type}"}

В следующем блоке выводим доступное для записи время и кнопки.

Рисунок 34

В настройках стрелки указываем: Условие: #{checker_date} Активировать “Пользователь вводит данные” Вводимые данные: input_date

Рисунок 35

Преобразуем время из цифры или кнопки во время

Рисунок 36

Обработка ввода пользователя, после выбора времени.

#{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: visit_time -> visit_time JSON POST-параметров: { "command": "save_time", "input_time": "#{input_time}", "times_list_data": "#{times_list_data}", "buttons_type": "#{buttons_type}"}

Напоминание по смс и емейл

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

Рисунок 37

Также в дополнительных блоках, есть часть схемы с запросом емейла и запросом часов для напоминания по емейлу. Также можно задать значение переменно notify_by_email в поле “назначение переменных”

Рисунок 38

Если не указать эти переменные, то по умолчанию напоминание не будет отправлено.

Рекомендуется убрать из цепочки шаги с напоминанием (чем меньше шагов тем больше конверсия) и указать, если нужно его в каком-то из блоков перед отправкой запроса на запись, например в блоке записи:

Рисунок 39

Спрашиваем комментарий к записи

Рисунок 40

Уточняем, все ли верно заполнено

Рисунок 41

Ответ: Вы подтверждаете запись? Услуга: #{service_title} Мастер: #{staff_title} Дата: #{visit_date} Время: #{visit_time} Напомнить за #{notify_by_sms} ч.

Отправляем запрос на запись

Рисунок 42

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: answer-> answer; yclients_record_id_mobile->yclients_record_id_mobile JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "command": "appoint", "staff_id": "#{staff_id}", "service_id": "#{service_id}", "visit_date": "#{visit_date}", "visit_time": "#{visit_time}", "appointment_id": "#{appointment_id}", "phone": "#{phone}", "client_name": "#{yclients_name}", "email": "#{email}", "comment": "#{comment}", "notify_by_sms": "#{notify_by_sms}", "order_id": "#{order_id}", "notify_by_email": "#{notify_by_email}", "sms_code": "#{sms_code}"} yclients_record_id_mobile - идентификатор записи, также при колбеке (record create) запишется в yclients_record_id old_client = 1 - нужно для развилки на точке входа, в зависимости это наш записавшийся ранее клиент или новый appointment_id – генерируем некое число, которое надо для отправки запроса на запись (не принципиально какое), а record_type – переменная, которая является ключевой в вилке сообщений-реакций (колбеков) при записи на услугу. Попросту отмечаем, что только что сделали запись через бота.

Просмотр всех записей

Из главного меню есть переход в цепочку для редактирования записей. Разберем ее подробнее.

Рисунок 43

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: status -> status; buttons_records -> buttons_records; str_records -> str_records; checker_records -> checker_records; records_list -> records_list; records_list_data -> records_list_data JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_all_appoints", "user_token": "#{yclients_user_token}", "phone": "#{phone}", "email": "#{email}", "current_date": "#{current_date}", "current_time": "#{current_time}", "yclients_client_id": "#{client.yclients_client_id}", "with_buttons": "#{with_buttons}", "back_str": "#{back_str}", "buttons_type": "#{buttons_type}"}

При успешном запросе со статусом 1 будет выведен список всех записей и возможность выбрать и удалить либо изменить время записи. Если статус 0, тогда выведет сообщение, что нет активных записей и вернет в главное меню.

Рисунок 44

Удаление записи

Рисунок 45

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: status-> status JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "user_token": "#{yclients_user_token}", "command": "delete", "record_id": "#{edit_record_id}"}

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

Редактирование даты и времени записи

Чтобы использовать функционал для изменения времени записи из бота, нужно авторизовать пользователя и сохранить его токен

Добавить передачу этого токена в запрос записи и при изменении времени.

Без токена авторизации изменить время из бота не получится

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

Рисунок 46

Выбор даты и времени такой же как и при основной записи. Разберем блок отправки новых данных.

Ответ: #{answer} Тип запроса: POST-json URL-запроса: #{yclients_url}JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "user_token": "#{client.yclients_client_token}", "command": "change_appoint", "visit_date": "#{visit_date}", "visit_time": "#{visit_time}", "record_id": "#{edit_record_id}", "comment": "#{comment}"}

Вилка сообщений при колбеке о создании записи

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

В сообщении, которое приходит после записи через бот (зеленый блок) указываем в блоке Назначение переменных при переходе:

our_client = 1 record_type = remind_visit_time = addMinutes(yclients_time, -yclients_sms_before * 60) remind_visit_date = if(remind_visit_time < yclients_time, yclients_date, addDays(yclients_date, -1))

our_client - для навигации клиента при входе в бот по ссылке и на втором этапе реакции на создание записи.

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

В сообщении, которое приходит при записи через сайт оставляем первый блок пустым. А из него делаем вилку с проверкой переменной our_client, если значение 1, то отправляем клиенту сообщение с уведомлением об успешной записи, если переменной our_client нет, тогда проверка клиент ватсап или нет.

Два блока после разделения на ватсап клиент или нет, делают запрос для идентификации клиента. Единственное отличие, это если клиент ватсап, то номер телефона берется из переменной #{platform_id}

Ответ: #{none} Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из JSON-ответа: id-> client.yclients_id; name-> client.yclients_name; email-> client.email; birth_date-> birth_date; remind_birth_date -> remind_birth_date JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "send_value", "user_token": "#{yclients_user_token}", "phone": "#{platform_id}", "email": "#{email}","client_id": "#{client_id}", "remind_birthday_days": "#{remind_birthday_days}"}

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

Далее по цепочке для этих двух блоков идет раздвоение отправка на напоминание перед днем рождения и отправка на напоминание о записи.

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

Получаем дату дня рождения из Yclients.

Дата ДР приходит в бот вместе с вебхуком в тот момент, когда администратор добавляет ее в карточку клиента, а если на момент регистрации клиента в боте она уже есть в его профиле, то добавится при первом контакте.

Получить весь список услуг и категорий

Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из ответа: data -> all_data JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_all_category_and_services"}

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

Получить описание услуги

Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из ответа: data|title-> service_title; data|price_min-> service_price_min; data|price_max-> service_price_max; data|comment->service_comment; data|image_group|images|basic|path-> service_images JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "client_type": "#{client_type}", "command": "get_service_info", "service_id": "#{service_id}", "user_token": "#{yclients_user_token}"}

Автозапись на ближайший сеанс

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

Делается это за два запроса: один запрос позволяет получить услугу, мастера, дату и время ближайшего сеанса, а второй запрос – уже описанный в разделе запись запрос «Отправляем запрос на запись».

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

Тип запроса: POST-json URL-запроса: #{yclients_url} Сохраняемые значения из ответа: status -> status; staff_id-> record_staff_id; staff_name -> record_staff_name; service_id_list -> service_id_list; service_title_list-> service_title_list; visit_date -> record_visit_date; visit_time -> record_visit_time

JSON POST-параметров: {"partner_token":"#{yclients_partner_token}", "company_id": "#{yclients_company_id}", "command": "nearest_appoint", "user_token": "#{yclients_user_token}", "current_date": "#{current_date}", "current_time": "#{current_time}", "minutes_before_record": "60", "time_zone": "0", "yclients_id": "#{yclients_client_id}", "how_many_days": "2"}

  • "minutes_before_record": "60" - искать сеансы, до начала которых, не менее чем указано минут (в примере 60 минут)

  • "time_zone": "0" - позволяет работать в часовых поясах, отличных от Москвы. В Москве он равен "0". В Оренбурге - "2".

  • "how_many_days": "2" - на сколько дней искать вперед, если на сегодня не найдено свободное время (2 - ищет доступное время на сегодня, если не найдет, то на завтра)

В запросе важно настроить следующие данные как вам нужно:

Старые переменные перед запросом обнуляем в поле Назначение переменных при переходе.

status = "" record_staff_id = "" record_staff_name = "" service_id_list = "" service_title_list = "" record_visit_date = "" record_visit_time = ""

В зависимости от статуса ответа клиент получит сообщение:

  • status = 0 - предыдущих записей не найдено

  • status = 2 - за заданный промежуток времени (how_many_days) нет доступных для записи сеансов

  • status = 1 - запись найдена и вывод сообщения с информацией о новой возможной записи

В следующем блоке выводим информацию о доступном сеансе

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

В поле Назначение переменных при переходе, переименовываем переменные нужные в запросе на запись.