Кастомный канал уведомлений — это адрес вашего сервиса, на который MACRO отправляет уведомления сотрудников. Сервис получает уведомление в фиксированном формате и сам доставляет его в корпоративный мессенджер или любую другую систему.
Канал подходит, когда уведомления нужно получать там, с чем MACRO не интегрирована напрямую: в корпоративном мессенджере внутри периметра компании, в собственном боте, в системе заявок. Уведомление при этом остаётся и в самой MACRO: канал его дублирует, а не заменяет.
#Как это работает
- Администратор компании заводит канал: адрес приёмника и секрет для подписи запросов.
- Сотрудник в своём профиле отмечает, какие уведомления получать в этот канал.
- Когда в MACRO возникает уведомление для сотрудника, система отправляет на адрес канала
POST-запрос с уведомлением, подписанный секретом канала. - Приёмник отвечает кодом
2xx— уведомление доставлено. Если приёмник недоступен или ответил ошибкой сервера, MACRO повторяет отправку около суток.
Каналов у компании может быть сколько угодно, у каждого свой адрес и свой секрет. Сотрудник выбирает уведомления для каждого канала отдельно.
#Как добавить канал
Управлять каналами могут сотрудники с правом редактирования компании.
- Откройте Компания → Интеграции → Каналы уведомлений.

- Нажмите
Добавить канали заполните форму:

| Поле | Что указать |
|---|---|
| Название | Его сотрудники видят в настройках оповещений. Оно же уходит приёмнику в теле запроса |
| Адрес приёмника | Адрес вашего сервиса, только https:// |
| Подпись поля идентификатора сотрудника | Необязательно. Например, «Логин в мессенджере». Если заполнить, каждый сотрудник сможет указать в профиле свой логин, и он будет приходить в запросе. Оставьте пустым, если приёмник узнаёт сотрудника по почте или идентификатору MACRO |
| Канал включён | Выключенный канал ничего не отправляет |
| Секрет подписи | Строка, которой MACRO подписывает каждый запрос, а приёмник проверяет подпись. Обязателен для включённого канала |
| Дополнительные заголовки | Необязательно. Например, Authorization: Bearer …, если приёмник требует свой токен |
- Нажмите
Сохранить. Канал появится в списке, а адрес приёмника будет проверен сразу при сохранении.
#Как проверить канал
Нажмите Проверить в строке канала. MACRO сразу отправит на адрес канала пробный запрос и покажет код ответа приёмника, время ответа и тело ответа:

Пробный запрос никому не адресован — это только проверка настройки. Приёмник должен ответить кодом 2xx и ничего не отправлять сотрудникам. Отличить пробу от настоящего уведомления можно по заголовку X-Macro-Event: notification.test или по полю "test": true в теле.
Проба уходит сразу, мимо очереди: в колонке «Последняя доставка» она не отражается и не повторяется при ошибке. У выключенного канала проба не отправляется.
#Как сотрудник подписывается на канал
- Сотрудник открывает свой профиль → Оповещения.
- В таблице появляется колонка с названием канала. Сотрудник включает те группы уведомлений, которые хочет получать в этот канал:

- Если в настройках канала задана подпись поля идентификатора, ниже появляется блок «Идентификаторы в каналах компании». Сотрудник указывает там свой логин — он будет приходить в запросе как
recipient.externalUserName:

- Сотрудник нажимает
Сохранить.
Колонка показывается только для включённых каналов. Уволенным сотрудникам уведомления в канал не отправляются.
#Где смотреть результат доставки
В колонке «Последняя доставка» раздела Каналы уведомлений показан исход последней отправки по каналу:
| Состояние | Что значит |
|---|---|
| «Попыток доставки ещё не было» | В канал ещё ничего не отправлялось. Проверьте, что сотрудники подписаны на канал |
| «Доставлено» | Приёмник ответил кодом 2xx |
| «Повторяется» | Приёмник недоступен, не ответил за 15 секунд или ответил 5xx / 429. MACRO повторит отправку сама. Под состоянием — число попыток, код и начало ответа |
| «Доставка прекращена» | Приёмник отклонил запрос (4xx) или сутки повторов не помогли. Под состоянием — код и начало ответа приёмника |
| «Отменено» | Уведомление подошло к отправке, пока канал был выключен |
Уведомления в состоянии «Доставка прекращена» и «Отменено» сами больше не отправляются. Если их нужно доставить повторно, обратитесь в службу сопровождения в течение 30 дней.
#Изменение секрета и заголовков
Откройте канал кнопкой Настроить:

- Секрет. Чтобы сменить секрет, введите новый и сохраните. Пустое поле означает «оставить прежний». Новый секрет действует сразу для всех запросов, в том числе для повторов уже стоящих в очереди уведомлений, поэтому на время смены приёмнику лучше принимать подпись обоими секретами.
- Заголовки. Значения заголовков не показываются, поэтому изменить один заголовок нельзя. Отметьте «Задать заголовки заново» и укажите весь набор — он заменит прежний целиком. «Удалить заголовки» убирает их все.
- Заголовок
Content-Typeзадать нельзя: тело всегда JSON. Нельзя также переопределить заголовкиUser-AgentиX-Macro-*— их выставляет MACRO.
#Выключение и удаление канала
- Выключение останавливает отправку: новые уведомления в канал не попадают, проба не уходит, а колонка канала пропадает из профиля сотрудников. Подписки сотрудников сохраняются и снова работают после включения.
- Уведомление, которое ждало повторной отправки, не будет отправлено, если его очередная попытка придётся на время, пока канал выключен. Если канал включат до очередной попытки — оно будет доставлено.
- Удаление останавливает отправку насовсем, канал исчезает из списка и из профиля сотрудников. Подписки на удалённый канал не восстанавливаются: на новый канал сотрудникам нужно подписаться заново.
#Для разработчиков приёмника
#Требования к приёмнику
- Адрес —
https://на стандартном порту 443, с действительным сертификатом, TLS 1.2 и выше. - В адресе — имя сервера, а не IP-адрес. Имя должно указывать на публичный адрес в интернете и не должно содержать домен, на котором работает MACRO вашей компании.
- Логин и пароль в адресе не допускаются. Для авторизации используйте подпись или дополнительный заголовок канала.
- Приёмник отвечает за 15 секунд. Если обработка дольше — примите запрос, ответьте
2xxи обработайте уведомление у себя асинхронно. - Приёмник проверяет подпись запроса, отбрасывает повторы по ключу идемпотентности и принимает пробные запросы.
#Запрос
POST <адрес приёмника>
Content-Type: application/json; charset=utf-8
User-Agent: MacroCRM-Webhook/1.0
X-Macro-Event: notification.created
X-Macro-Delivery: 3f6c0a9e-2b71-4c58-9e0d-8b4f2a1c7d35
X-Macro-Timestamp: 1791261667
X-Macro-Idempotency-Key: 500.12.987654
X-Macro-Signature: sha256=07b3de7fcb9d092243a8d45ed4fb5367b5077649110a4ea7a589ecb3603d3b45
Плюс дополнительные заголовки из настроек канала.
| Заголовок | Значение |
|---|---|
X-Macro-Event | notification.created — уведомление, notification.test — проба |
X-Macro-Delivery | Идентификатор попытки. У каждого повтора новый |
X-Macro-Timestamp | Время отправки этой попытки, Unix-время в секундах |
X-Macro-Idempotency-Key | Ключ уведомления: одинаков у всех повторов одного уведомления в один канал |
X-Macro-Signature | Подпись запроса |
#Пример уведомления
Сотруднику назначили задачу:
{
"deliveryId": "3f6c0a9e-2b71-4c58-9e0d-8b4f2a1c7d35",
"sentAt": "2026-10-06T04:41:07+00:00",
"schemaVersion": "1.0",
"event": "notification.created",
"channel": {
"id": 12,
"name": "Корпоративный мессенджер"
},
"company": {
"macroId": 500,
"name": "Пример Девелопмент",
"host": "crm.example.ru"
},
"recipient": {
"macroUserId": 12345,
"fullName": "Иванов Иван Иванович",
"email": "i.ivanov@example.ru",
"phone": "+7 (900) 000-00-00",
"externalUserName": "i.ivanov"
},
"notification": {
"macroId": 987654,
"type": "tasks_assigned",
"group": "common",
"priority": 0,
"createdAt": "2026-10-06T09:41:06+05:00",
"subject": "Вы назначены исполнителем по задаче",
"text": "Позвонить клиенту\n🙂 Петров Пётр\n🗓 06.10.2026, 18:00",
"html": "<a href=\"https://crm.example.ru/account/tasks/view/1001/\">Позвонить клиенту</a><br /><br />🙂 Петров Пётр<br />🗓 06.10.2026, 18:00",
"entity": {
"type": "tasks",
"id": 1001
},
"sender": {
"macroUserId": 42,
"fullName": "Петров Пётр"
},
"data": {
"task_id": 1001,
"task_title": "Позвонить клиенту",
"role": "manager",
"date_finish": "2026-10-06 18:00:00",
"date_finish_time": "18:00"
}
}
}
Пробный запрос (X-Macro-Event: notification.test) содержит только данные канала:
{
"deliveryId": "8c2e5d14-6a90-4b3f-a1d7-0e9f4b6c2a58",
"sentAt": "2026-10-06T04:41:17+00:00",
"test": true,
"channel": {
"id": 12,
"name": "Корпоративный мессенджер"
}
}
Разбирайте тело как JSON-объект: порядок полей не гарантируется. В реальном запросе символ / в строках экранирован (https:\/\/crm.example.ru\/...) — это то же значение JSON.
#Поля уведомления
| Поле | Описание |
|---|---|
channel.id | Идентификатор канала в MACRO. Не меняется, по нему приёмник различает каналы |
channel.name | Название канала. Может меняться |
company.macroId, company.name, company.host | Компания и домен MACRO, из которого собираются ссылки |
recipient.macroUserId | Идентификатор сотрудника в MACRO. Есть всегда и не меняется |
recipient.email, recipient.phone, recipient.fullName | Данные из карточки сотрудника. Почта и телефон — если заполнены |
recipient.externalUserName | Логин, который сотрудник указал в профиле. Есть, только если у канала задана подпись поля и сотрудник его заполнил |
notification.macroId | Идентификатор уведомления |
notification.type | Точное событие, например tasks_assigned |
notification.group | Группа уведомлений, на которую подписан сотрудник, например common — «Основные» |
notification.createdAt | Когда возникло уведомление |
notification.subject | Заголовок уведомления, до 255 символов |
notification.text | Текст уведомления без разметки, переносы строк — \n, до 1000 символов. Его можно сразу отправить в мессенджер |
notification.html | Текст уведомления в том виде, как его показывает MACRO, со ссылкой на карточку, до 1000 символов |
notification.actionUrl | Ссылка на карточку в MACRO. Приходит не у всех типов уведомлений; ссылка также есть в html |
notification.entity | Объект, к которому относится уведомление: type и id |
notification.sender | Сотрудник, который совершил действие. Может отсутствовать |
notification.data | Исходные данные события. Состав зависит от типа — пригодится, если приёмник собирает собственный текст сообщения |
Длинные subject, text и html обрезаются, последний символ обрезанного значения — …. В тексте сохраняются эмодзи, которыми MACRO помечает поля уведомления: «👤» — контакт, «🗓» — срок, «🙂» — инициатор, «📎» — файл, «💬» — сообщение.
Сотрудника приёмник может узнать по любому полю recipient: по логину из профиля, по почте или по идентификатору MACRO.
#Группы уведомлений
Поле notification.group совпадает со строкой в настройках оповещений, которую включил сотрудник. По нему удобно раскладывать уведомления по разным чатам.
notification.group | Строка в настройках оповещений |
|---|---|
common | Основные |
docs_agreement_required | Документы: Необходимо выполнить процесс |
docs_approve_cancel_notify | Документы: Отмена завершения процесса/Возврат на редактирование |
docs_add_delete_approvers | Документы: Добавление или удаление участников в документе |
docs_new_messages | Документы: Новые комментарии к договору |
finances_income_incomplete | Финансы: Не поступил платеж по графику |
finances_transaction_paid | Финансы: Ваша финансовая операция оплачена |
finances_transaction_accepted | Финансы: Ваша финансовая операция акцептована к оплате |
finances_need_approve_accept | Финансы: Необходимо согласовать/акцептовать операцию |
finances_new_messages | Финансы: Новые комментарии к финансовой операции |
estate_transfer_out_request | Передача объектов: Новый запрос на передачу объекта клиенту |
contacts_new_message | Контакты: Новое входящее сообщение от контакта |
calls_incoming_call | Звонки: Входящий звонок |
tasks_auto_message | Задачи: Автоматические сообщения |
documents_approve_task | Задачи: Согласование документа |
im_new_message | Чат: Новое сообщение |
Полный справочник типов уведомлений и полей data можно запросить в службе сопровождения.
#Проверка подписи
Подпись считается от времени из заголовка X-Macro-Timestamp и «сырого» тела запроса — ровно тех байтов, которые пришли:
X-Macro-Signature = "sha256=" + hex(hmac_sha256(секрет, X-Macro-Timestamp + "." + тело))
Не разбирайте и не собирайте JSON заново перед проверкой — получатся другие байты и другая подпись. Рекомендуем также отклонять запросы, у которых X-Macro-Timestamp отличается от текущего времени больше чем на 5 минут.
Python:
import hashlib
import hmac
import time
def is_valid(raw_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
expected = 'sha256=' + hmac.new(secret.encode(), timestamp.encode() + b'.' + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
PHP:
$rawBody = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_MACRO_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_MACRO_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
if (!hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
http_response_code(401);
exit;
}
Node.js (тело нужно получить буфером, до разбора JSON):
const crypto = require('crypto');
function isValid(rawBody, timestamp, signature, secret) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
return false;
}
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(timestamp + '.').update(rawBody).digest('hex');
return expected.length === signature.length
&& crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
#Ответ приёмника и повторы
| Ответ приёмника | Что делает MACRO |
|---|---|
2xx | Уведомление доставлено |
4xx, кроме 429 | Не повторяет. В разделе — «Доставка прекращена» с кодом и началом ответа |
3xx | Не идёт по перенаправлению и не повторяет |
429, 5xx, нет ответа за 15 секунд, ошибка соединения | Повторяет по расписанию |
Повторы идут с нарастающими паузами: 30 секунд, 1, 2, 5, 15 и 30 минут, 1, 2, 4, 6 и 8 часов — всего 12 попыток примерно за 22 часа. Если приёмник ответил 429 или 503 с заголовком Retry-After, следующая попытка будет не раньше указанного времени (не дольше часа).
Тело ответа MACRO не разбирает, важен только код. Начало тела ответа с ошибкой показывается администратору в разделе — поэтому в ответе с ошибкой полезно коротко написать причину.
#Повторы и порядок
- Доставка гарантируется по принципу «не менее одного раза»: одно и то же уведомление может прийти повторно, например если ответ приёмника не дошёл до MACRO. У повторов одинаковый
X-Macro-Idempotency-Key— храните обработанные ключи и отбрасывайте дубли. - Порядок доставки не гарантирован: при повторах более позднее уведомление может прийти раньше. Ориентируйтесь на
notification.createdAt.
#Если уведомления не приходят
- Нажмите
Проверитьу канала. Если запрос не отправлен — проверьте, что канал включён. Если приёмник ответил ошибкой — передайте код и тело ответа разработчику приёмника. - Посмотрите колонку «Последняя доставка»: код и начало ответа приёмника подскажут причину.
- Проверьте, что сотрудник включил нужную группу уведомлений в колонке канала в профиле → Оповещения.
- Если адрес не сохраняется — проверьте требования к адресу в разделе «Требования к приёмнику».
Если не получается разобраться, обратитесь в службу сопровождения и приложите название канала, время уведомления и, если есть, запись запроса на стороне приёмника.