Исходящие вебхуки - это вызов (post-запрос) из Битрикс24 внешнего сервиса при наступлении события внутри вашего портала. Т.е. наступает событие (создана новая задача, создали событие в календаре...) и Битрикс24 отправляет запрос в ваш сервис автоматически, сам. Какие события могут инициировать Исходящий вебхук (вызов указанного url обработчика) описал подробно в статье Вебхуки в Битрикс24>>>. Также к Исходящим вебхукам можно отнести вызов вашего обработчика из Роботов. Там событием является перемещение объекта (сделки, задачи...) на нужную стадию и тут Битрикс24 стучится сам в ваш обработчик. Этот сценарий описал в статье Обрабатываем Исходящие вебхуки Битрикс24 из роботов на Питоне>>>. Здесь опишу, как можно на питоне обрабатывать "классические" вебхуки из раздела Разработчикам-Другое-Исходящий вебхук https://<url_your_bitrix24>/devops/section/standard/.
- Создание Исходящего вебхука
- Обработчик post-запроса на Flask
- Что отправляет Битрикс24 в обработчик исходящего вебхука?
1. Создание Исходящего вебхука
Кликаем на Исходящие вебхуки на скрине/ссылке выше, получаем страничку создание.
В качестве отлавливаемого события выберем Создание новой сделки, а обрабатывать событие это будем на адресе https://example.runpython.ru/outwebhook/:
Токен приложения в нашем случае может не использоваться, но для лишней верификации получаемых обработчиком данных никогда лишним не будет. Исходящий вебхук на стороне Битрикс24 создан. Теперь идем на наш хостинг и уже на его стороне напишем обработчик для указанного адреса https://example.runpython.ru/outwebhook/, чтобы когда Битрикс24 отправлял запрос по этому адресу мы на своей стороне уже получали эти данные.
2. Обработчик post-запроса на Flask
Пример инфраструктуры для обработчика вебхука на python на реальном хостинге описал в статье. Используем все тот же доступный хостинг Jino. Исходим из того, что мы Не знаем изначально, что пришлет Битрикс24 при наступлении события. Плюс для разных событий данные, которые он пришлет могут отличаться и не лишним будет для каждого нового для себя события потестировать и посмотреть исходные запросы, какие нам направляет портал. Для удобства напишем функцию, которая будет сохранять полученные данные в запросе от Битрикса в текстовый файл:
____________________________________________________
def any_saver(data):
"""Сохраняем в файл"""
with open('log_out_webhook.txt', 'a') as f:
f.write(f"{datetime.now()} {str(data)}\r")
____________________________________________________
Дальше разворачиваем классическое веб-приложение на Flask, где пока мы просто примем запрос на outwebhook и сохраним полученные данные в файл log_out_webhook.txt:
____________________________________________________
from flask import Flask, request
from datetime import datetime
from werkzeug.datastructures import ImmutableMultiDict
app = Flask(__name__)
def any_saver(data):
"""Сохраняем в файл"""
with open('log_out_webhook.txt', 'a') as f:
f.write(f"{datetime.now()} {str(data)}\r")
@app.route("/outwebhook/", methods=['POST']) # Принимаем и сохраняем исходящий вебхук
def outwebhook():
any_saver( request.headers.get('Content-Type'))
request_data = request.form
any_saver(request_data)
request_data = request_data.to_dict()
any_saver(request_data)
return "WORK"
if __name__ == "__main__":
app.run(debug=True)
____________________________________________________
В функции, обрабатывающей наш url, несколько раз вызываем созданную any_saver, чтобы сохранить в текстовый лог-файлик:
- получаемый Content-Type (any_saver( request.headers.get('Content-Type')));
- соответствующие полученные данные исходные (request.form);
- данные уже преобразованные в более стандартный тип Словарь request_data.to_dict().
Теперь создаем новую сделку в Б24 и проверим, что у нас в логе сервера корректный ответ 200:
3. Что отправляет Битрикс24 в обработчик исходящего вебхука?
А теперь смотрим, что у нас пришло в файлик log_out_webhook.txt:
Битрикс в заголовках Content-Type отдает: application/x-www-form-urlencoded (первая запись), тип получаемых данных при такой обработке у нас выходит ImmutableMultiDict (вторая запись), этот тип преобразовываем в словарь методом .to_dict(). Неплохо работа с этими методами описана на стороннем ресурсе.
Основной интерес в нашем случае вызывает словарик 'data[FIELDS][ID]': '22392'. Именно он содержит айди созданной сделки новой. В наш обработчик теперь всегда будет приходить такой массив данных, где будет айди соответствующей сущности.
Собранный обработчик почти универсален, хотя пока и не учитывает многих нужных опций логирования, обработки ошибок, безопасности, обработки токенов... Но вполне может служить стартом для начала сбора большого приложения для обработки данных в Битрикс24.
Для примера создадим Исходящий вебхук на событие Создание события календаря. В нашем обработчике на сервере закомментируем лишнее и в файлик будем сохранять только словарь (третья запись):
Отличием от получения айди сделки тут будет название ключа. При создании События календаря айди будет в 'data[id]' вместо 'data[FIELDS][ID]' для сделки. Примерно по такой же схеме можно наладить обработку и иных вебхуков:
- изначально принимаем, выводим максимум данных, присылаемых из Битрикс24;
- обрабатываем соответствующими методами;
- выбираем интересующие нас значения.
В приведенных примерах нам в Исходящем вебхуке основную информативную часть несет лишь одно поле, айди записи. И выглядит не особо информативно, что с ней делать. А дальше включается необходимая бизнес-логика. На текущем этапе мы знаем, что произошло в портале и айди созданного документа. Теперь можем отправить в портал Входящий вебхук на python, например, 'crm.deal.get', в параметрах отдать "id": <id сделки>, в ответ получить все ее поля, что там внесли по ней пользователи для последующей обработки.