Запустить туннель бесплатно
☰
Гайды

Вебхуки Битрикс24 на localhost: принять событие CRM через HTTPS

Как принять исходящий вебхук Битрикс24 на localhost: обработчик Python, HTTPS-туннель, проверка application_token и постоянный адрес для CRM.

Сделка изменилась в Битрикс24, а код обработчика пока работает на вашем компьютере. Исходящий вебхук может доставить событие на этот компьютер через публичный HTTPS-адрес fxTunnel. Обработчик ниже печатает ID сделки. Проверьте его обычным curl до подключения CRM.

Какой вебхук нужен

У Битрикс24 есть два вида вебхуков. Входящий даёт вашему коду секретный URL для вызова REST API с правами сотрудника. Вашему компьютеру для такого запроса нужен доступ в интернет; открывать туннель не требуется.

Исходящий сообщает о событии: Битрикс24 отправляет POST на ваш обработчик. Ему нужен адрес, доступный снаружи. localhost и адрес вашей домашней сети для этого не подходят.

ЗадачаЧто использовать
Прочитать сделку из локального скриптаВходящий вебхук
Принять событие изменения сделки на компьютереИсходящий вебхук и HTTPS-туннель
CRMБитрикс24ONCRMDEALUPDATE
сервер fxTunnelпубличный адресcrmhook.fxtun.ru/b24
ваш компьютерклиент fxtunnelfxtunnel http 8080
локальнообработчик Python127.0.0.1:8080/b24
Рис. 1. Битрикс24 отправляет POST на адрес туннеля, клиент fxTunnel передаёт запрос локальному обработчику.

1. Запустите обработчик и проверьте его локально

Нужен Python 3. Сохраните код в b24_hook.py. Это учебный обработчик: он проверяет путь, формат и токен, затем печатает событие. Сделку он не меняет.

PYTHON
# b24_hook.py
import hmac
import os
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs

TOKEN = os.environ["B24_APP_TOKEN"]
if not TOKEN:
    raise ValueError("B24_APP_TOKEN must not be empty")


class Hook(BaseHTTPRequestHandler):
    def do_POST(self):
        if self.path != "/b24":
            self.send_error(404)
            return
        content_type = self.headers.get("Content-Type", "").split(";", 1)[0]
        if content_type != "application/x-www-form-urlencoded":
            self.send_error(415)
            return
        try:
            size = int(self.headers.get("Content-Length", "0"))
        except ValueError:
            self.send_error(400)
            return
        if not 0 < size <= 65536:
            self.send_error(413)
            return
        raw = self.rfile.read(size)
        form = parse_qs(raw.decode(errors="replace"))
        token = form.get("auth[application_token]", [""])[0]
        if not hmac.compare_digest(token.encode(), TOKEN.encode()):
            self.send_error(401)
            return
        event = form.get("event", [""])[0]
        deal_id = form.get("data[FIELDS][ID]", [""])[0]
        print(event, deal_id, flush=True)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"ok\n")


HTTPServer(("127.0.0.1", 8080), Hook).serve_forever()

Сначала используйте условный токен для проверки. В терминале Linux или macOS:

BASH
B24_APP_TOKEN=local-demo-token python3 b24_hook.py

В PowerShell:

POWERSHELL
$env:B24_APP_TOKEN="local-demo-token"
python b24_hook.py

Отправьте POST из другого терминала. Многострочные команды curl в этой статье рассчитаны на Bash, в том числе Git Bash на Windows:

BASH
curl -i 'http://127.0.0.1:8080/b24' \
  --data-urlencode 'event=ONCRMDEALUPDATE' \
  --data-urlencode 'data[FIELDS][ID]=662' \
  --data-urlencode 'auth[application_token]=local-demo-token'

В PowerShell ту же форму отправляет Invoke-WebRequest:

POWERSHELL
$body = @{
    event = 'ONCRMDEALUPDATE'
    'data[FIELDS][ID]' = '662'
    'auth[application_token]' = 'local-demo-token'
}
$response = Invoke-WebRequest -UseBasicParsing -Uri 'http://127.0.0.1:8080/b24' -Method Post -ContentType 'application/x-www-form-urlencoded' -Body $body
$response.StatusCode
$response.Content

Ожидаемый результат: HTTP 200, тело ok и строка ONCRMDEALUPDATE 662 в терминале Python. --data-urlencode выбирает POST и кодирует поля формы. Повторите запрос с неверным токеном: должен прийти 401. Если локальный тест не проходит, сначала исправьте обработчик.

2. Установите fxTunnel и откройте HTTPS-адрес

Выберите GUI или CLI на странице скачивания. В GUI создайте HTTP-туннель на локальный порт 8080 и укажите свободный поддомен. Для CLI выполните следующие команды.

На Linux и macOS:

BASH
curl -fsSL https://fxtun.ru/install.sh | sh
fxtunnel login
fxtunnel http 8080 --domain crmhook

На Windows установите клиент, затем выполните последние две команды в PowerShell. fxtunnel login предложит вход через браузер или API-токен. Имя crmhook приведено для примера; замените его свободным именем и возьмите HTTPS-адрес из вывода клиента.

Повторите предыдущий curl с адресом https://crmhook.fxtun.ru/b24. В PowerShell выполните тот же Invoke-WebRequest, заменив значение -Uri на HTTPS-адрес и оставив $body. Если снова получили 200 и строку в Python, запрос прошёл весь путь через туннель. Оставьте клиент и обработчик запущенными.

3. Подключите исходящий вебхук Битрикс24

В Битрикс24 откройте Приложения > Разработчикам > Готовые сценарии > Другое > Исходящий вебхук. Укажите полный URL https://crmhook.fxtun.ru/b24, выберите событие изменения сделки ONCRMDEALUPDATE и создайте вебхук.

Скопируйте показанный Битрикс24 токен. Остановите учебный обработчик и запустите его снова, заменив local-demo-token в B24_APP_TOKEN этим значением. Токен из настроек относится именно к созданному исходящему вебхуку. Не публикуйте его.

Измените тестовую сделку в CRM. В терминале Python должно появиться название события и ID этой сделки. Обработчик получает поля формы события: event, data[FIELDS][ID] и служебный auth[application_token]. Полный набор полей сделки нужно запросить отдельно.

Проверка токена в примере использует hmac.compare_digest. Сохраните её и в своём обработчике. Публичный HTTPS-адрес доступен любому отправителю; токен позволяет отсеивать посторонние запросы.

Исходящий вебхук недоступен в демо-режиме Битрикс24; для коробочной версии нужна активная лицензия. Условия приведены в документации вебхуков.

Как получить полные данные сделки

Создайте входящий вебхук с доступом к CRM и вызовите crm.item.get. Для сделки entityTypeId равен 2; ID возьмите из события.

BASH
curl --fail-with-body -X POST \
  'https://example.bitrix24.ru/rest/1/xxxxxxxx/crm.item.get' \
  -H 'Content-Type: application/json' \
  -d '{"entityTypeId":2,"id":662}'

Замените портал, ID сотрудника и секретный код своим входящим вебхуком. В JSON-ответе также проверяйте поле error: HTTP-статус сам по себе не подтверждает успешный вызов API. Этот URL содержит секрет; храните его на стороне обработчика.

Учебный код выше только подтверждает приём. Для рабочей интеграции добавьте получение данных и обработку ошибок. Перед действиями с заказами или оплатой нужна защита от повторов.

Когда нужен платный тариф

Бесплатного HTTP-туннеля достаточно для первого события. --domain crmhook выбирает имя, но пока туннель выключен, свободное имя может занять другой пользователь.

Если адрес уже сохранён в CRM, зарезервируйте его после проверки:

BASH
fxtunnel domains add crmhook
fxtunnel http 8080 --domain crmhook

Резерв имени доступен с Base. Он сохраняет имя за аккаунтом между запусками; доставлять событие смогут только работающие клиент и обработчик. Для своего домена и лимитов смотрите тарифы и постоянный адрес туннеля.

На Base и выше Inspector показывает запросы и ответы. Его обычный адрес http://127.0.0.1:4040; точный адрес смотрите в строке Inspector: клиента, поскольку занятый порт будет заменён. Replay отправляет сохранённый запрос локальному обработчику повторно, поэтому после правки кода можно обойтись без нового изменения сделки. Повтор также запустит бизнес-действия вашего обработчика; для учебного кода это только печать ID. Подробнее: инспектор трафика.

Если событие не приходит

Что наблюдаетеЧто проверить
Локальный curl не соединяетсяPython запущен и слушает порт 8080
Локально всё работает, через HTTPS нетКлиент fxTunnel работает, URL взят из его вывода, порт совпадает
Ответ 401В B24_APP_TOKEN токен именно этого исходящего вебхука
Ответ 404 или 415Путь /b24, метод POST и тело формы
Ручной POST проходит, CRM молчитВыбрано ONCRMDEALUPDATE, изменена тестовая сделка, в CRM записан полный URL
После перезапуска события пропалиИмя туннеля не изменилось и не занято другим пользователем

Если вместо Python событие принимает n8n, укажите в Битрикс24 Production URL узла Webhook и проверяйте application_token в workflow. Настройка n8n на localhost: тестовый и рабочий URL.

Инспектор запросов

Инспектор показывает каждый запрос через туннель и повторяет его одним кликом — удобно отлаживать вебхуки. Доступен с тарифа Base.

Выберите клиент на странице скачивания: GUI для работы через графический интерфейс или CLI для терминала.

$ curl -fsSL https://fxtun.ru/install.sh | sh
@mephistofx

Пишу fxTunnel — туннели для разработчиков без белого IP. Рассказываю, как это устроено изнутри.

Написать в Telegram →

Читайте дальше