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

# Надсилайте повідомлення через вебхук

Вебхук це URL, який публікує повідомлення у вашій спільноті. Надішліть на нього JSON із будь-чого, що вміє робити HTTP-запити, як-от CI, моніторинг, cron-завдання чи скрипт, і повідомлення з’явиться в каналі.

## Що можна зробити

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

- **Додавайте файли** До п’яти файлів на повідомлення: логи, звіти, знімки екрана.

- **Додавайте кнопки** Посилання або кнопки, що змінюють картку чи звертаються до вашого сервісу.

- **Змінюйте згодом** Відповідь містить callback URL, щоб оновити або видалити повідомлення.

У застосунку

#### Збірка #1847 успішна

Один запит із CI, одна картка в #deploys. Ім’я вгорі це назва, яку ви дали вебхуку.

- [Швидкий старт](#quick-start)

- [Що можна надіслати](#format)

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

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

- [Відповіді та помилки](#responses)

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

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

## Швидкий старт

### Створіть вебхук

У настільному застосунку відкрийте у своїй спільноті **Manage Server → Webhooks** (керування сервером, вебхуки), створіть вебхук, виберіть канали, у яких він може публікувати, і скопіюйте URL для потрібного каналу. Він має такий вигляд:

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

### Надішліть повідомлення

Підпишіть JSON секретом вебхука й надішліть його методом POST. Вебхук, створений у настільному застосунку, завжди має секрет: скопіюйте його з поля **Webhook Secret** (секрет вебхука) в налаштуваннях вебхука.

```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/uk/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/uk/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 @-
```

## Підпис запитів

Вебхук із секретом приймає лише запити, які доводять, що знають його, а вебхук, створений у настільному застосунку, завжди має секрет (**Webhook Secret** у його налаштуваннях). Підпишіть сире тіло запиту за допомогою HMAC-SHA256 із цим секретом і надішліть hex-дайджест у нижньому регістрі в заголовку 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/uk/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/uk/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/uk/integrations). Вони отримують відповідь {"success": true} без callback URL.

| Джерело | Як розпізнається | Що публікує |
| --- | --- | --- |
| GitHub | Заголовок x-github-event | Push, pull requests і рев’ю, issues і коментарі, гілки й теги, релізи. Серію змін одного issue чи pull request буде зібрано в одну картку. |
| UniFi Protect | User agent protect-alarm-manager | Дзвінки у двері, рух, а також люди, транспорт чи посилки, помічені вашими камерами. |
| App Store Connect | Тіло сповіщення або заголовок x-apple-signature | Сповіщення App Store Connect. |

## Що далі
