Wiki
Веб-хуки
Исходящие уведомления по репозиторию (Discord, Slack, Teams, custom) при check-in и сводках активности. Создание, формат сообщений, переменные шаблона, защита от SSRF.
Введение
Веб-хук отправляет исходящее уведомление во внешнюю службу (Discord, Slack, Microsoft Teams, или URL по вашему выбору) каждый раз, когда в репозитории (проекте, версионируемом на сервере) происходит событие: check-in или периодическая сводка активности. Это самый простой способ держать команду в курсе, не открывая клиент: сообщение приходит в ваш канал, когда кто-то отправляет работу.
Веб-хуки настраиваются для каждого репозитория, в панели администрирования настольного клиента, на вкладке Webhooks. У репозитория может быть несколько веб-хуков (например, один в Discord для всей команды, один в приватный Slack для лидов).
Доступ и роли
Управление веб-хуками доступно только администраторам репозитория: суперадминистратору
(роль admin) в любом репозитории или project_admin в репозиториях,
которыми он управляет. Другие роли эту вкладку не видят.
Создание веб-хука
1. Открыть вкладку Webhooks
В панели администрирования сначала выберите репозиторий в селекторе строки PROJECT, затем откройте вкладку Webhooks той же строки: веб-хук принадлежит репозиторию. Репозиторий, у которого их нет, показывает No webhooks configured.
2. Открыть форму
Нажмите Add Webhook, вверху справа во вкладке. Окно Create Webhook открывается пустым.
3. Заполнить поля
Два поля обязательны, Name и URL, и хотя бы одно событие должно быть выбрано в Events (это кликабельные «таблетки», а не выпадающий список). Type должен соответствовать службе, на которую указывает URL.
| Поле | Значение |
|---|---|
| Name | Метка, чтобы его узнать (напр. Discord équipe). Обязательно. |
| URL | URL веб-хука, предоставленный целевой службой. Обязательно. См. Безопасность об отклоняемых URL. |
| Type | discord, slack, teams или custom. |
| Events | Хотя бы один обязателен. На практике: checkin и activity_summary. О checkout см. События. |
| Enabled | Переключатель активации (виден при редактировании и из списка). |
Чтобы получить URL на стороне Discord: Настройки канала → Интеграции → Веб-хуки → Новый веб-хук → Копировать URL, подробно в руководстве ниже. На стороне Slack: создайте Incoming Webhook в настройках приложения Slack. На стороне Teams: Соединители → Incoming Webhook на канале.
4. Подтвердите, затем отправьте тест
Нажмите Create Webhook. Веб-хук появляется в списке, активным. В его строке нажмите значок самолёта Send test: uVersion отправляет тестовое уведомление в службу и показывает результат в конце строки, зелёную галочку или крест с возвращённым HTTP-кодом. Сделайте это сейчас: это единственный способ узнать, что URL и тип верны, прежде чем полагаться на этот веб-хук.
Руководство: веб-хук Discord
Это самый распространённый случай. Часть «получить URL» полностью выполняется в Discord, всего один раз.
На стороне Discord: получить URL
- Откройте Discord и перейдите на свой сервер. Выберите (или создайте) текстовый канал, который будет получать уведомления, например
#uversion. - Наведите курсор на название канала и нажмите значок шестерёнки («Редактировать канал»).
- В меню слева откройте вкладку Интеграции.
- Нажмите Веб-хуки, затем Новый веб-хук. Discord автоматически создаст его, привязанным к этому каналу.
- Нажмите созданный веб-хук, чтобы открыть его. Дайте ему имя (например
uVersion) и проверьте, что целевой канал верный. Изображение аватара необязательно. - Нажмите Копировать URL веб-хука. URL выглядит так:
https://discord.com/api/webhooks/123456789/AbCdEf....
На стороне uVersion: подключить URL
Пройдите процедуру Создание веб-хука выше с такими значениями: Name метка
для вас (напр. Discord équipe), URL тот, что вы только что скопировали,
Type discord (необходимо, чтобы сообщение ушло как embed Discord),
Events checkin. Завершите нажатием Send test: сообщение должно
появиться в канале Discord в течение нескольких секунд.
Если тест завершается с HTTP-кодом 401 или 404, URL неверен или веб-хук был
удалён на стороне Discord: скопируйте URL заново. Если тест зелёный, но ничего не приходит, проверьте, что вы смотрите
в нужный канал и что веб-хук не был отключён в Discord.
Типы и форматы
Type определяет, как uVersion форматирует сообщение перед отправкой. Выберите тот, что соответствует службе, на которую указывает URL, иначе сообщение придёт неправильно оформленным (или будет отклонено службой).
| Type | Отправляемый формат |
|---|---|
discord | Embed Discord (заголовок, цвет, поля). |
slack | Полезная нагрузка Slack (блоки сообщения). |
teams | Карточка Microsoft Teams (MessageCard). |
custom | Тело JSON, полностью определяемое вами: см. Пользовательские веб-хуки. |
События
Сервер реально эмитирует два события:
| Событие | Срабатывает, когда… |
|---|---|
checkin | Пользователь отправляет коммит в репозиторий. |
activity_summary | Планировщик сервера формирует периодическую сводку активности (ежедневную / еженедельную). |
checkout: флажок присутствует, событие никогда не эмитируется
Форма предлагает третий флажок, checkout, призванный сигнализировать о блокировке файла
(блокировкой называется резервирование, которое пользователь ставит на файл, пока его изменяет).
Он объявлен, но до сих пор ни разу не эмитировался: его установка не вызовет никакого уведомления.
Не полагайтесь на него и не используйте его как единственный выбор: веб-хук, в котором отмечено только это событие,
навсегда останется безмолвным.
Отмечайте только то, что нужно вашему каналу. На практике полезной комбинацией является checkin для
рабочей ленты команды и activity_summary для периодической сводки.
Пользовательские веб-хуки
С типом custom появляются два дополнительных поля: Custom Headers (JSON)
и Custom Template (JSON). Они позволяют интегрировать любую службу, принимающую POST в формате JSON.
Template
Шаблон представляет собой отправляемое тело JSON. uVersion заменяет в нём переменные в двойных фигурных скобках значениями события. Пример:
{"text": "{{event_type}} par {{username}} dans {{repository}}"}
Доступные переменные:
| Переменная | Содержимое |
|---|---|
{{event_type}} | Тип события (checkin или activity_summary). |
{{repository}} | Имя репозитория. |
{{username}} | Пользователь, вызвавший событие. |
{{message}} | Сообщение коммита (для check-in). |
{{file_count}} | Число затронутых файлов. |
{{commit_hash}} | Хеш коммита. |
{{timestamp}} | Метка времени события. |
Headers
Объект JSON из HTTP-заголовков, добавляемых к запросу, например токен аутентификации:
{"Authorization": "Bearer VOTRE_JETON"}
По умолчанию {} (без заголовков). Заголовки, зарезервированные для транспорта
(host, content-length, transfer-encoding, connection)
удаляются автоматически и не могут быть переопределены.
Тест, включение, удаление
Каждый веб-хук в списке предлагает следующие действия:
- Send test (значок самолёта): отправляет тестовое уведомление в службу и показывает результат в строке (зелёная галочка или крест). Полезно проверить URL и тип, прежде чем на него полагаться.
- Переключатель: включает / отключает веб-хук без удаления.
- Edit: изменить любое поле.
- Delete: окончательное удаление (запрашивается подтверждение).
Безопасность: защита от SSRF
Веб-хук заставляет сервер отправить HTTP-запрос. Чтобы вредоносный URL не мог использоваться для зондирования внутренней сети сервера (атака SSRF), uVersion применяет строгую защиту при создании, при изменении и при тесте:
- Схема должна быть
httpилиhttps. Любая другая схема отклоняется. - Имя хоста разрешается через DNS, и проверяется каждый полученный IP-адрес. Веб-хук
отклоняется, если один из них указывает на непубличный адрес: loopback, частные сети (RFC1918), link-local,
broadcast, диапазон CGNAT
100.64.0.0/10, облачные метаданные169.254.169.254, ULA / IPv6 link-local и их эквиваленты IPv4-mapped-IPv6. - HTTP-перенаправления не отслеживаются (поэтому 307 на внутренний хост не может обойти защиту).
- Тело ответа вышестоящего сервера никогда не возвращается клиенту (нет SSRF-оракула).
На практике: URL веб-хука должен указывать на публичную службу (Discord, Slack, Teams или
ваш собственный эндпоинт, доступный из Интернета). URL на localhost, частный IP
(10.x, 192.168.x, 172.16-31.x) или внутреннюю службу отклоняется с
сообщением «Webhook URL refused: …».
Частые ошибки
Тип не соответствует службе
Отправка формата Discord на URL Slack (или наоборот) даёт неправильно оформленное сообщение или отказ на стороне службы. Поле Type должно соответствовать URL. Если сомневаетесь, выполните Send test.
Не отмечено ни одного события
Веб-хук без события никогда не срабатывает. Клиент блокирует сохранение, пока не выбрано ни одного события («At least one event is required»).
Внутренний URL отклонён
Если вы тестируете против службы на своей машине или в своей LAN, защита от SSRF её отклоняет. Опубликуйте службу на публичном URL (или через туннель), чтобы использовать её как цель веб-хука.
Забытый отключённый веб-хук
Отключённый веб-хук остаётся в списке, но ничего не отправляет. Если уведомления затихли, сначала проверьте переключатель активации, прежде чем подозревать URL.