Webhooks (вебхуки) позволяют получать HTTP-уведомления в необходимый сервис о регистрации или покупке курса, завершении учеником урока или задания, об окончании доступа к курсу.
Для отправки вебхуков необходимо:
1. Создать процесс в разделе «Автоматизация» и выбрать необходимый триггер.
2. Выбрать действие «Отправить HTTP-уведомление».
3. В поле URL вставить ссылку.
На указанный URL наша платформа будет отправлять уведомления о событиях. Ссылка может вести на собственный сервер, который должен быть заранее настроен на приём уведомлений, либо на готовую интеграцию со сторонним сервисом.
* Под готовой интеграцией предполагаются различные CRM, CMS-системы или сервисы Albato, Zapier и др. Подобные интеграции выдают ссылку, которую нужно вставить в поле URL.
** Мы отправляем только POST-запросы.
4. Далее потребуется сохранить процесс как черновик и снова зайти в редактирование созданного процесса.
На данном шаге появится поле «Секретный ключ» (не отображается при создании процесса автоматизации).
Секретный ключ невозможно изменить. Он предназначен для авторизации запросов от Zenclass. Принимающая сторона (сервер, готовая интеграция) может не проверять секретный ключ. В таком случае, будет возможна ситуация, когда кто-то посторонний пришлет HTTP-запрос на указанный URL, из-за чего могут произойти нежелательные действия на принимающей стороне.
5. Когда процесс по автоматизации будет полностью настроен, то можно его запустить.
Реализация защиты от посторонних запросов через проверку секретного ключа.
1. Сохраните секретный ключ в той системе, которая отвечает за прием вебхуков от Zenclass (CRM, CMS, Albato, Zapier и др.)
*Обращаем внимание, что хранить ключ требуется в секрете. То есть секретный ключ не нужно дополнительно хранить в других местах, а его просмотр не должен быть доступен посторонним.
2. Каждый раз, когда на указанный URL приходит запрос, требуется проверить подпись запроса по алгоритму (см. ниже). Это можно сделать с помощью секретного ключа, т.к. ключ известен только Zenclass и принимающей системе. Пройденная проверка будет означать, что запрос действительно был отправлен нашей платформой.
1. Соедините с помощью символа & в одну строку следующие поля:
2. Получившуюся строку требуется передать в функцию sha1, чтобы посчитать хэш.
3. Сравните полученное значение с тем, что было отправлено в поле hash.
Приведем пример:
Предположим, секретный ключ это very_secret_phrase_123
В теле запроса отправлены поля
id со значением 123456
timestamp со значением 1703765506
Соединяем эти значения следующим образом:
very_secret_phrase_123&123456&1703765506
Далее по алгоритму эту строку требуется передать в функцию sha1 (пример кода на PHP):
$secret = 'very_secret_phrase_123'; $id = $request->get('id'); $timestamp = $request->get('timestamp'); $concatenated = "$secret&$id&$timestamp"; $hash = sha1($concatenated); if ($hash === $request->get('hash')) { // Всё хорошо }
Все запросы содержат следующие поля:
id – уникальный идентификатор запроса
hash – хэш для проверки подписи, см. выше
event_name – название события, к которому привязан вебхук
timestamp – целое число (Unix time) – дата события
payload – объект, содержимое которого напрямую зависит от того, какое событие привело к триггеру вебхука.
Доступные события и данные, которые отправляются в этих событиях (payload):
Событие | event_name | payload |
---|---|---|
Урок завершен | lesson_completed |
|
Продукт оплачен | payment_accepted |
|
Студент подписался на продукт | product_user_subscribed |
|
Задание отправлено на проверку | lesson_task_submitted_for_review |
|
Задание принято | lesson_task_accepted |
|
Закончился доступ к курсу | access_to_course_expired |
|
Изменён статус по кредиту/банковской рассрочке | bank_credit_status_changed |
|
*Уточнение для credit_status:
credit_status 0 — ученик заполнил анкету на кредит/рассрочку;
credit_status 1 — ученик получил одобрение на кредит/рассрочку от банка;
credit_status 2 — ученик получил отказ по всем банкам;
credit_status 3 — ученик успешно получил кредит/рассрочку от банка.
*Уточнение по триггеру «Задание принято» для содержимого task_result:
Для теста с автопроверкой будет передаваться информация с количеством правильно выбранных ответов учеником в формате "количество правильных ответов/количество вопросов", например, "5/7". Для обычного задания в task_result будет передана информация в виде статуса "ок", так как по триггеру задание принято.
Пример полученного вебхука по событию «Изменён статус по кредиту/банковской рассрочке»:
{ "id": "qwRGTkRy6gQJWbrH3EGaD0b5Ikm69gtY", "hash": "d0e5afbc9524551d1a7b65d31e2fda45beab0b3b", "event_name": "bank_credit_status_changed", "timestamp": 1730809343, "payload": { "user_id": "t5121d12-ee49-4323-adfc-6b8508ebeebd", "user_email": "example@mail.ru", "payment_id": 123456, "payment_variant": "bank_credit", "payment_amount": 179000, "payment_commission": 2000, "product_type": "course", "product_id": "50b67993-f276-4772-86b7-4e132ab9a14b", "product_name": "Тестовый курс", "course_type": "common", "credit_status": 3 } }
Пример полученного вебхука по событию «Продукт оплачен»:
{ "id": "TsTYrfgcZKZEIEh9O1VWvCPFZNOrnIvf", "hash": "d0e5afbc9524551d1a7b65d31e2fda45beab0b3b", "event_name": "payment_accepted", "timestamp": 1730215453, "payload": { "user_id": "2701c05f-1601-4fb8-9102-46e12f5507b9", "user_email": "test@mail.ru", "payment_id": 90257, "payment_variant": "single", "payment_amount": 100, "payment_commission": 4.5, "product_type": "course", "product_id": "776fad98-5c05-4914-a332-9dae9f373333", "product_name": "Тест вебхука", "course_type": "common" } }
Запрос считается доставленным, если сервер, указанный в поле URL, ответил HTTP-кодом 200. Если сервер ответил любым другим кодом или не ответил в течение 5 секунд, то производится повторная попытка, через 5 минут после неудачи. Далее следуют еще попытки:
через 30 минут
через 60 минут
через 3 часа
через 6 часов
Таким образом, не более 5 повторных попыток.
Если ни один запрос не завершился ответом 200, попытки доставить http-уведомление прекращаются.
Каждый запрос содержит поле id. Значение этого поля будет отличаться в разных вебхуках, но будет повторяться при повторных попытках.
Это нужно для того, чтобы принимающая сторона могла проверить – возможно запрос с таким id уже был обработан ранее, а Zenclass по каким-то причинам прислал его еще раз.
Таким образом, в тех случаях, когда произошла повторная отправка, необходимо обратить внимание на поле notification_id. Если оно совпадает у двух вебхуков, а первый уже обработан, то второй и последующие можно игнорировать.