---
title: "Вебхуки: публикуйте сообщения в канал mssgs"
description: "Отправляйте сообщение или карточку в канал mssgs из CI, мониторинга или скрипта одним HTTP-запросом. Форматы, файлы, подпись, ответы, ошибки, лимиты и GitHub."
canonical: https://docs.mss.gs/ru/webhooks
language: ru
---

# Публикуйте сообщения через вебхук

Вебхук представляет собой URL, через который сообщения попадают в ваше сообщество. Отправьте на него JSON из чего угодно, что умеет делать HTTP-запросы: из CI, мониторинга, cron-задачи или скрипта, и сообщение появится в канале.

## Что можно сделать

- **Публикуйте текст или карточку** Обычный текст или карточка с заголовком, цветом, markdown, полями и изображениями.

- **Прикрепляйте файлы** До пяти файлов на сообщение: логи, отчёты, скриншоты.

- **Добавляйте кнопки** Ссылки или кнопки, которые меняют карточку или обращаются к вашему сервису.

- **Меняйте сообщение позже** В ответе есть callback URL, чтобы обновить или удалить сообщение.

В приложении

#### Сборка #1847 прошла успешно

Один запрос из CI, одна карточка в #deploys. Имя вверху совпадает с именем, которое вы дали вебхуку.

- [Быстрый старт](#quick-start)

- [Что можно отправить](#format)

- [Файлы](#attachments)

- [Подпись](#signing)

- [Ответы и ошибки](#responses)

- [Лимиты](#limits)

- [GitHub, UniFi, App Store](#special)

## Быстрый старт

### Создайте вебхук

В настольном приложении откройте в своём сообществе **Управление сервером → Вебхуки**, создайте вебхук, выберите каналы, в которые он может публиковать, и скопируйте URL для нужного канала. Он выглядит так:

```url
https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
```

### Отправьте сообщение

Подпишите JSON секретом вебхука и отправьте его методом POST. У вебхука, созданного в настольном приложении, секрет есть всегда: скопируйте его из поля **Секрет вебхука** в настройках вебхука.

```bash
BODY='{"content": "Build #1847 passed on main"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MSSGS_WEBHOOK_SECRET" | sed 's/^.* //')

curl -X POST "$MSSGS_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -H "X-Mssgs-Signature: sha256=$SIG" \
  -d "$BODY"
```

### Прочитайте ответ

В ответе есть id сообщения и callback_url , чтобы изменить сообщение позже.

```json
{
  "success": true,
  "message_id": "aZZ1a2b-...",
  "callback_url": "https://mss.gs/api/v1/trigger-callback/8f14e45f-...",
  "stream_url": "https://mss.gs/api/v1/instant/6b1e...c0?token=a1b2c3d4-..."
}
```

## Что можно отправить

Сообщение отправляется либо в короткой форме (текст с заголовком и цветом), либо полной карточкой, и в обоих случаях к нему можно добавить кнопки и файлы. Имя вверху карточки всегда совпадает с именем самого вебхука. В настройках вебхука вы также решаете, может ли он публиковать изображения и упоминать людей.

### Короткая форма

Этого хватает для большинства оповещений.

```json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
```

| Поле | Тип | Что делает |
| --- | --- | --- |
| content | string | Текст сообщения. Обязателен, если вы не отправляете карточку или файлы. |
| color | string | blue (по умолчанию), green , orange , red , yellow или purple . |
| title | string | Заголовок над текстом. По умолчанию имя вебхука. |

### Полная карточка

Отправьте message_container , чтобы получить карточку с заголовком-ссылкой, подзаголовком, markdown, полями и изображениями. Через вебхук карточка принимает type , color , title , title_url , sub_title , description , fields , avatar_url , image_url , image_base64 , images и поля индикатора загрузки. Плашка статуса, бейдж, статистика diff и свёрнутые размышления доступны только в ответах на команды. Все поля описаны на странице [карточек сообщений](https://docs.mss.gs/ru/bots).

```json
{
  "message_container": {
    "type": "embed_message",
    "color": "green",
    "title": "Build #1847 passed",
    "title_url": "https://ci.example.com/builds/1847",
    "description": "All 212 tests green on **main**.",
    "fields": [
      { "field": "Duration", "value": "2m 34s" },
      { "field": "Commit", "value": "1a2b3c4" }
    ]
  }
}
```

#### Сборка #1847 прошла успешно

### Кнопки

Добавьте массив actions , чтобы разместить кнопки под сообщением. Как они работают, описано на странице [о кнопках](https://docs.mss.gs/ru/buttons).

## Файлы

Публикуйте вместе с сообщением настоящие файлы: лог, отчёт, скриншот. Они отображаются как любые другие вложения: строкой для скачивания, а изображения, видео и аудио прямо в сообщении. Сообщение только с файлами тоже допустимо: просто не передавайте content и карточку.

```json
{
  "message_container": {
    "color": "orange",
    "title": "Log dump: ios",
    "description": "DMs stopped arriving after switching networks"
  },
  "attachments": [
    {
      "name": "mssgs-logs-20260803-141205.log",
      "content_base64": "MjAyNi0wOC0wMyAxNDoxMjowNSBbV1NdIGNvbm5lY3RlZAo=",
      "mime_type": "text/plain"
    }
  ]
}
```

| Поле | Тип | Что делает |
| --- | --- | --- |
| name | string | Имя, под которым файл скачивается. Обязательно. От пути остаётся только последняя часть. |
| content_base64 | string | Байты файла в base64, простой строкой или как data: URI. mssgs сохраняет файл и оставляет в сообщении только ссылку. |
| mime_type | string | Тип содержимого content_base64 . По умолчанию text/plain . |
| url | string | Файл, уже размещённый на mssgs: путь /static/... или URL https://mss.gs/... . |

| Лимит | Значение |
| --- | --- |
| Файлов на сообщение | **5** |
| Размер файла после декодирования | **8 МБ** |
| Имя файла | 200 символов |
| Весь запрос | Около 10 МБ. Base64 увеличивает файл на треть, поэтому один файл больше примерно 7 МБ не поместится. |

### Почему url принимает только адреса mssgs

URL вебхука часто оказывается вставленным в чужие дашборды. Если он утечёт, это не должно позволить кому-то заставить приложение каждого участника загрузить файл с выбранного им сервера. Если ваш файл лежит в другом месте, отправьте его как content_base64 , и mssgs разместит его у себя.

### Неудачная загрузка не отменяет сообщение

Файлы проверяются сразу, а загружаются позже. Если загрузка не удалась, этот файл пропускается, а остальное сообщение всё равно публикуется, без ошибки: лучше потерять файл, чем весь отчёт. Если файл важен, проверьте, что он дошёл.

### Файл из командной строки

```bash
BODY='{"attachments":[{"name":"report.csv","content_base64":"'"$(base64 < report.csv | tr -d '\n')"'","mime_type":"text/csv"}]}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MSSGS_WEBHOOK_SECRET" | sed 's/^.* //')

printf '%s' "$BODY" | curl -sS -X POST "$MSSGS_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -H "X-Mssgs-Signature: sha256=$SIG" \
  --data-binary @-
```

## Подпись запросов

Вебхук с секретом принимает только те запросы, которые доказывают, что знают его, а у вебхука, созданного в настольном приложении, секрет есть всегда (**Секрет вебхука** в его настройках). Подпишите необработанное тело запроса с помощью HMAC-SHA256 этим секретом и отправьте шестнадцатеричный дайджест в нижнем регистре в заголовке X-Mssgs-Signature в виде sha256=<hex> .

```javascript
import crypto from 'node:crypto';

const body = JSON.stringify({ content: 'Deploy finished' });
const signature = crypto.createHmac('sha256', process.env.MSSGS_WEBHOOK_SECRET)
  .update(body)
  .digest('hex');

await fetch(process.env.MSSGS_WEBHOOK_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Mssgs-Signature': `sha256=${signature}`
  },
  body
});
```

Собственный заголовок GitHub X-Hub-Signature-256 тоже принимается, так что вебхук GitHub с тем же секретом работает без изменений. В подписи нет метки времени, поэтому она не мешает повторно отправить перехваченный запрос: главным секретом остаётся сам URL.

## Ответы и ошибки

Опубликованное сообщение возвращается с id и callback_url , через который его можно обновить или удалить в течение 30 минут.

```json
{
  "success": true,
  "message_id": "aZZ1a2b-...",
  "callback_url": "https://mss.gs/api/v1/trigger-callback/8f14e45f-...",
  "stream_url": "https://mss.gs/api/v1/instant/6b1e...c0?token=a1b2c3d4-..."
}
```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{ "error": "ATTACHMENT_TOO_LARGE" }
```

```javascript
const res = await fetch(webhookUrl, { method: 'POST', headers, body });
const reply = await res.json().catch(() => null);

// A rejected payload still comes back as 200: read the body.
if (!res.ok || (reply && reply.error)) {
  throw new Error(`webhook rejected: ${reply?.error ?? res.status}`);
}
```

Если у сообщения есть кнопки, в ответе также есть stream_url : живой поток ответов, реакций и нажатий кнопок на этом сообщении. Он открыт 10 минут или час, если отправить "sse_event_extended_timeout": true . Подробнее на странице [обновлений вживую](https://docs.mss.gs/ru/live-updates).

### Коды статуса

| Статус | Когда |
| --- | --- |
| 401 | У вебхука есть секрет, а подпись отсутствует или неверна. |
| 403 | Этому вебхуку нельзя публиковать в этот канал. |
| 404 | По этому URL нет вебхука. |
| 413 | Запрос слишком большой. |
| 429 | Слишком много запросов. Сбавьте темп и повторите попытку. |
| 502 | Сообщение не удалось доставить. Повторите попытку. |

### Коды ошибок

| Код | Что означает |
| --- | --- |
| MISSING_CONTENT | Нечего публиковать: нет ни текста, ни карточки, ни файлов. |
| INVALID_MESSAGE_CONTAINER | message_container не является объектом. |
| INVALID_MESSAGE_CONTAINER_TYPE | Тип карточки не embed_message и не system_message . |
| MISSING_MESSAGE_CONTAINER_DESCRIPTION | Карточке нужно описание, если это не индикатор загрузки. |
| MISSING_MESSAGE_CONTAINER_LOADER_TEXT | Карточке с индикатором загрузки нужен loader_text . |
| INVALID_WEBHOOK_BINDING | Этому вебхуку нельзя публиковать в этот канал. |
| INVALID_SIGNATURE | Заголовок подписи отсутствует или неверен. |
| REQUEST_BODY_TOO_LARGE | Запрос превышает лимит размера. |
| PUBLISH_FAILED | Сообщение не удалось доставить. |
| INVALID_ACTIONS_FORMAT , INVALID_ACTION_MISSING_FIELDS , DUPLICATE_ACTION_ID , INVALID_TRIGGERS_FORMAT , INVALID_TRIGGER_MISSING_ACTION , INVALID_TRIGGER_ACTION_NOT_ALLOWED | Что-то не так с кнопкой. Подробнее на странице [о кнопках](https://docs.mss.gs/ru/buttons). |

### Ошибки файлов

| Код | Что означает |
| --- | --- |
| INVALID_ATTACHMENTS_FORMAT | attachments не является списком, или один из элементов не является объектом. |
| TOO_MANY_ATTACHMENTS | Больше пяти файлов. |
| MISSING_ATTACHMENT_NAME | У файла нет имени. |
| INVALID_ATTACHMENT_NAME | От имени не остаётся ничего пригодного, например .. . |
| MISSING_ATTACHMENT_SOURCE | Нет ни url , ни content_base64 . |
| AMBIGUOUS_ATTACHMENT_SOURCE | Переданы и url , и content_base64 . |
| INVALID_ATTACHMENT_BASE64 | Base64 не декодируется. |
| ATTACHMENT_TOO_LARGE | Файл больше 8 МБ после декодирования. |
| INVALID_ATTACHMENT_URL | url не является адресом mssgs. |

## Лимиты

| Лимит | Значение |
| --- | --- |
| Размер запроса | Около 10 МБ |
| Файлов на сообщение | 5, каждый до 8 МБ |
| Описание карточки | До 50 000 байт. Если оно длиннее 1 000 байт, участники видят начало и кнопку **Показать больше**. |
| Изменение сообщения после публикации | 30 минут, через callback_url |
| Живой поток сообщения с кнопками | 10 минут или час по запросу |

Число запросов ограничено. Получив 429 , подождите, прежде чем отправлять снова, а оповещения, которые приходят пачками, объединяйте в одно сообщение.

## GitHub, UniFi и App Store Connect

Направьте один из этих сервисов на URL вебхука, и mssgs распознает его и опубликует полноценную карточку, без payload, который нужно писать самому. См. [интеграции](https://mss.gs/ru/integrations). На такие запросы приходит ответ {"success": true} без callback URL.

| Источник | Как распознаётся | Что публикует |
| --- | --- | --- |
| GitHub | Заголовок x-github-event | Пуши, pull request и ревью, issues и комментарии, ветки и теги, релизы. Серия изменений в одном issue или pull request собирается в одну карточку. |
| UniFi Protect | User agent protect-alarm-manager | Звонки в дверь, движение, а также люди, машины или посылки, которые заметили ваши камеры. |
| App Store Connect | Тело уведомления или заголовок x-apple-signature | Уведомления App Store Connect. |

## Что дальше
