ДОКУМЕНТАЦИЯ
Основы платформы

Вебхуки

Вебхуки — простейший способ постить сообщения в каналы Lolka. Тебе не нужен бот и не нужно получать токен OAuth: достаточно создать вебхук в настройках канала и отправлять HTTP POST на секретный URL.

Сейчас Lolka поддерживает только входящие (incoming) вебхуки — внешние сервисы отправляют запросы в Lolka, а Lolka постит сообщение в канал.

Создание вебхука

Вебхук принадлежит конкретному текстовому каналу внутри сервера. Создавать и редактировать вебхуки может любой участник, у которого есть право Управление вебхуками на этом канале.

  • Открой настройки канала → вкладка «Интеграции» → «Вебхуки».
  • Нажми «Новый вебхук», задай имя (1–80 символов) и, при желании, аватар.
  • Скопируй URL — его и нужно будет использовать для отправки сообщений.

Также можно управлять вебхуками на уровне сервера (страница «Интеграции сервера»): там видно все вебхуки по всем каналам, куда у тебя есть доступ.

Объект вебхука

Когда вебхук отдаётся наружу (например, при создании), он имеет такую структуру:

ПолеТипОписание
idsnowflakeидентификатор вебхука
typeintegerвсегда 1 (Incoming)
channel_idsnowflakeканал, в который постит вебхук
server_idsnowflakeсервер, которому принадлежит канал
namestringимя по умолчанию (1–80 символов)
avatar_url?stringURL аватарки, которая выводится у сообщений
token?stringсекрет вебхука; возвращается только при создании, регенерации и при запросе с правом Управление вебхуками
url?stringполный URL вида /api/webhooks/{id}/{token}; возвращается вместе с токеном
useruser objectкраткий профиль пользователя, создавшего вебхук

Пример

JSON
{
  "id": 7234876123234,
  "type": 1,
  "channel_id": 881723489234,
  "server_id": 771223489001,
  "name": "Captain Hook",
  "avatar_url": "https://cdn.lolka.app/avatars/webhook/..../256.webp",
  "token": "NzIzNDg3NjEyMzIzNA.q8F2C...",
  "url": "https://lolka.app/api/webhooks/7234876123234/NzIzNDg3NjEyMzIzNA.q8F2C...",
  "user": {
    "id": 100000000001,
    "username": "nikita",
    "display_name": "Никита",
    "avatar_url": "https://cdn.lolka.app/avatars/user/..../128.webp"
  }
}

Отправка сообщения

POST/api/webhooks/{webhook.id}/{webhook.token}

Постит сообщение в канал вебхука. Аутентификация — самим token в URL; ни сессионный cookie, ни Authorization header не нужны.

Query-параметры

ПараметрТипПо умолчаниюОписание
waitbooleantrueесли true — в ответе придёт созданное сообщение (200); если false — 204 без тела

Тело запроса (JSON)

ПолеТипОписание
contentstringтекст сообщения
usernamestringпереопределяет имя вебхука для этого сообщения (1–80 символов после нормализации)
avatar_urlstringHTTPS-URL на картинку, которая будет подставлена как аватар автора сообщения. Картинку мы скачаем, перекодируем в WebP и закешируем
embedsarray of embedдо 10 rich-embed объектов — см. раздел Rich-embeds
Хотя бы одно из полей content, embeds или файлов (см. ниже) должно быть задано — пустое сообщение отправить нельзя.

Пример

curl
curl -X POST \
  "https://lolka.app/api/webhooks/7234876123234/NzIzNDg3NjEyMzIzNA.q8F2C..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Привет из CI! Сборка #123 прошла :)",
    "username": "build-bot",
    "avatar_url": "https://example.com/bot.png"
  }'

Ответ

При wait=true (по умолчанию) в ответ приходит созданное сообщение в стандартном формате канальных сообщений:

JSON
{
  "id": 98234876234,
  "channel_id": 881723489234,
  "author": {
    "id": 7234876123234,
    "username": "build-bot",
    "is_webhook": true,
    "webhook_id": 7234876123234
  },
  "content": "Привет из CI! Сборка #123 прошла :)",
  "created_at": "2026-04-22T12:00:03Z"
}

Отправка файлов

Чтобы прикрепить файлы, отправляй запрос как multipart/form-data. Текстовые параметры передавай как обычные поля формы, а файлы — полями files[0], files[1] и т.д.

  • Максимум 10 файлов за один запрос.
  • До 10 MB на файл.
  • Поддерживаемые типы: image/*, video/*, audio/*, application/pdf, text/plain.
curl
curl -X POST \
  "https://lolka.app/api/webhooks/7234876123234/NzIzNDg3NjEyMzIzNA.q8F2C..." \
  -F "content=Отчёт за день во вложении" \
  -F "files[0]=@./report.pdf"

Rich-embeds

Rich-embed — это блок внутри сообщения с заголовком, описанием, картинками, цветной полосой, полями и футером. Передаётся как элемент массива embeds в теле запроса. Все поля опциональные — достаточно, например, одного title.

Объект embed

ПолеТипОписание
titlestringзаголовок embed, до 256 символов
descriptionstringописание, до 4096 символов. Поддерживает markdown — жирный, курсив, зачёркнутый, inline-код, блочные цитаты, ссылки
urlstringHTTPS-ссылка; если задана, заголовок title становится кликабельным
colorintegerцелое число 0…0xFFFFFF — цвет полоски слева. Конвертируется из hex: #FF7A59 = 16742745
timestampISO 8601 stringвремя, которое показывается в футере. Пример: "2026-04-22T18:00:00.000Z"
authorobjectблок автора (имя + иконка + ссылка) — см. ниже
footerobjectнижний блок (текст + иконка)
imageobjectбольшая картинка снизу
thumbnailobjectмаленькая картинка справа
fieldsarray of fieldдо 25 дополнительных полей «название/значение»

Вложенные объекты

embed.author

ПолеТипОписание
namestringимя автора, до 256 символов
urlstringHTTPS-ссылка — делает name кликабельным
icon_urlstringHTTPS-URL на иконку автора
proxy_icon_urlstringCDN-URL — заполняется сервером

embed.footer

ПолеТипОписание
textstringтекст футера, до 2048 символов
icon_urlstringHTTPS-URL на иконку
proxy_icon_urlstringCDN-URL — заполняется сервером

embed.image / embed.thumbnail

ПолеТипОписание
urlstringHTTPS-URL на картинку — единственное поле, которое задаёт клиент
proxy_urlstringCDN-URL — заполняется сервером
widthintegerширина — заполняется сервером
heightintegerвысота — заполняется сервером
content_typestringMIME-тип — заполняется сервером

embed.fields[]

ПолеТипОписание
namestringназвание поля, до 256 символов
valuestringзначение, до 1024 символов; поддерживает markdown
inlinebooleanесли true — поле встаёт в ряд с соседними inline-полями (до 3 в ряд)

Пример

Полный payload с embed:

JSON
{
  "content": "Новый релиз выкатили 🚀",
  "embeds": [{
    "title": "build #1247 · production",
    "description": "**Успешно** задеплоено в прод.\n\n> Все smoke-тесты зелёные",
    "url": "https://ci.example.com/builds/1247",
    "color": 3066993,
    "timestamp": "2026-04-22T18:00:00.000Z",
    "author": {
      "name": "ci-bot",
      "url": "https://ci.example.com",
      "icon_url": "https://ci.example.com/logo.png"
    },
    "footer": {
      "text": "env: prod · v1.2.3",
      "icon_url": "https://ci.example.com/favicon.png"
    },
    "thumbnail": {
      "url": "https://ci.example.com/status-ok.png"
    },
    "image": {
      "url": "https://ci.example.com/builds/1247/chart.png"
    },
    "fields": [
      { "name": "Ветка", "value": "main", "inline": true },
      { "name": "Коммит", "value": "`a1b2c3d`", "inline": true },
      { "name": "Длительность", "value": "4m 12s", "inline": true }
    ]
  }]
}

В ответе сервер вернёт embed обратно и дополнит поля картинок:

JSON
"embeds": [{
  "type": "rich",
  "title": "build #1247 · production",
  "description": "**Успешно** задеплоено в прод.\n\n> Все smoke-тесты зелёные",
  "url": "https://ci.example.com/builds/1247",
  "color": 3066993,
  "timestamp": "2026-04-22T18:00:00Z",
  "author": {
    "name": "ci-bot",
    "url": "https://ci.example.com",
    "icon_url": "https://ci.example.com/logo.png",
    "proxy_icon_url": "https://cdn.lolka.app/embeds/a1b2c3d4....webp"
  },
  "footer": {
    "text": "env: prod · v1.2.3",
    "icon_url": "https://ci.example.com/favicon.png",
    "proxy_icon_url": "https://cdn.lolka.app/embeds/e5f6g7h8....webp"
  },
  "thumbnail": {
    "url": "https://ci.example.com/status-ok.png",
    "proxy_url": "https://cdn.lolka.app/embeds/f0e1d2c3....webp",
    "width": 200,
    "height": 200
  },
  "image": {
    "url": "https://ci.example.com/builds/1247/chart.png",
    "proxy_url": "https://cdn.lolka.app/embeds/11223344....webp",
    "width": 800,
    "height": 420
  },
  "fields": [...]
}]
Когда в сообщении есть rich-embed, превью для ссылок из content автоматически не добавляется — чтобы не дублировать блок.

Лимиты embed

ЛимитЗначение
Embed на одно сообщениедо 10
titleдо 256 символов
descriptionдо 4096 символов
author.nameдо 256 символов
footer.textдо 2048 символов
fields на один embedдо 25
field.nameдо 256 символов
field.valueдо 1024 символов
Суммарно всех текстов во всех embedдо 6000 символов
URL (во всех полях)только https://
color0 … 0xFFFFFF (16 777 215)

При нарушении любого лимита сервер отвечает 400 Bad Request с описанием ошибки.

Slack- и GitHub-совместимые эндпоинты

Чтобы не переписывать существующие интеграции со Slack и GitHub, Lolka принимает их нативные форматы и сама конвертирует их в сообщение канала.

POST/api/webhooks/{webhook.id}/{webhook.token}/slack

Принимает payload Slack Incoming Webhook (text, attachments, blocks в базовом виде). Достаточно просто подставить URL Lolka-вебхука вместо slack-hooks.

POST/api/webhooks/{webhook.id}/{webhook.token}/github

Принимает payload GitHub-вебхука. Обязателен заголовок X-GitHub-Event (например push, pull_request, issues) — по нему мы выбираем шаблон сообщения.

Управление сообщениями вебхука

У каждого отправленного сообщения можно получить его текущее состояние, отредактировать текст или удалить его. Аутентификация такая же — token вебхука в URL.

Получить сообщение

GET/api/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}

Возвращает сообщение в том же формате, что и ответ на POST.

Отредактировать сообщение

PATCH/api/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}

Меняет содержимое сообщения. Все поля опциональные.

ПолеТипОписание
contentstring | nullnull или отсутствует — оставить как есть; строка — заменить
embedsarray | nullnull или отсутствует — оставить как есть; [] — очистить все embed; массив — заменить полностью. Формат элементов — тот же объект embed
JSON
{
  "content": "Исправленный текст",
  "embeds": [{
    "title": "Обновлено",
    "description": "Статус изменился",
    "color": 16711680
  }]
}

Удалить сообщение

DELETE/api/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}

При успехе возвращает 204 No Content.

Лимиты

ЛимитЗначениеГде применяется
Запросов на один вебхук30 в минутуна каждый отдельный вебхук
Сообщений от вебхуков на канал60 в минутусуммарно по всем вебхукам канала
Вебхуков на канал15максимальное количество одновременно существующих
Файлов за один запрос10multipart upload
Размер одного файла10 MBлюбой тип

При превышении лимитов возвращается 429 Too Many Requests с телом { "code": "WEBHOOK_RATE_LIMIT_EXCEEDED" }. Рекомендуется добавлять экспоненциальный backoff при ретраях.

Безопасность

  • Токен в URL = полный доступ к вебхуку. Любой, у кого есть ссылка, сможет постить сообщения в канал. Не коммить URL в публичные репозитории, не логируй его, не передавай в client-side-коде браузера.
  • Если токен утёк — регенерируй его в настройках канала. Старый URL сразу перестанет работать.
  • Мы не подписываем запросы сервером и не отдаём ни X-Signature, ни X-Timestamp — единственным секретом является сам токен.
  • Все внешние URL (avatar_url, icon_url, image.url и т.д.) должны быть по https:// и доступны из интернета.
Вопросы или баг? Напиши нам на support@lolka.app.