Перейти к основному содержанию
Разработчикам Карточки сообщений

Оформляйте карточки сообщений

Всё, что публикует бот, будь то вебхук, ответ на команду или обновление по кнопке, является карточкой. Хорошая карточка с одного взгляда говорит, что произошло: цветная кромка, заголовок, статус и подробности под ними.

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

  • Показывайте статусЦветная плашка вроде «Открыт», «Слит» или «Успешно», с числом добавленных и удалённых строк.
  • Перечисляйте подробностиСтроки «название: значение», которые участники копируют одним нажатием.
  • Пишите в markdownЖирный шрифт, встроенный код, блоки кода, цитаты и чекбоксы.
  • Показывайте, что идёт работаСпиннер, пока бот думает, а потом его размышления за переключателем.

В приложении

Четыре карточки такими, какими их видят участники. Каждая занимает несколько строк JSON.

Устройство карточки

Части карточки сверху вниз. Пропустите то, что вам не нужно: карточка из одного заголовка тоже подойдёт.

  1. Шапка«Сообщение от» и имя: имя вебхука или, для ответа на команду, название вашего сообщества. Ответ может добавить badge, например репозиторий.
  2. Заголовок и статусtitle, который становится ссылкой, если задан title_url, а рядом плашка status.
  3. ПодзаголовокВторая строка жирным шрифтом, sub_title.
  4. ОписаниеОсновной текст в markdown.
  5. ПоляСтроки «название: значение» с кнопкой копирования.
  6. Нижняя строкаВремя, а также добавленные и удалённые строки, если вы их передали.
json
{
  "message_container": {
    "type": "embed_message",
    "badge": "acme/web",
    "color": "purple",
    "title": "Pull request #212 opened",
    "title_url": "https://github.com/acme/web/pull/212",
    "status": { "label": "Open", "color": "green", "icon": "pull_request" },
    "sub_title": "Faster search in the channel list",
    "description": "Search now runs **per keystroke** with a 120 ms debounce.",
    "fields": [
      { "field": "Author", "value": "maya" },
      { "field": "Reviewers", "value": "dani, sam" }
    ],
    "additions": 86,
    "deletions": 12,
    "files_changed": 3
  }
}

Все поля

Они передаются в message_container. Карточке нужно описание или индикатор загрузки. Поля с пометкой «Ответы на команды» отбрасываются, если публиковать через вебхук.

ПолеТипЧто делает
typestringembed_message (по умолчанию) или system_message.
badgestringНебольшой чип после имени в шапке, например acme/web. Ответы на команды
avatar_urlstringИзображение поверх иконки карточки.
colorstringЦвет кромки. См. цвета ниже.
titlestringПервая строка жирным шрифтом.
title_urlstringПревращает заголовок в ссылку.
sub_titlestringВторая строка жирным шрифтом под заголовком.
descriptionstringОсновной текст в markdown.
fieldsarray[{ "field": "…", "value": "…" }]: строки «название: значение».
image_url, image_base64stringИзображение на карточке.
imagesarray[{ "image_url": "…" }]: галерея из нескольких изображений.
statusobject или stringЦветная плашка рядом с заголовком. См. ниже. Ответы на команды
additions, deletions, files_changednumberСтатистика diff в нижней строке. Ответы на команды
loader, loader_text, loader_sub_textboolean, stringСпиннер вместо основного текста.
thinkingstringРазмышления за переключателем Показать размышления. Ответы на команды
Описание и thinking понимают markdown: **bold**, _italic_, ~~strike~~, `inline code`, блоки кода в тройных обратных кавычках, > quotes, чекбоксы - [x], @упоминания и :emoji:.

Статус и статистика diff

Плашка статуса рассказывает суть ещё до того, как кто-то прочтёт текст. Она стоит рядом с заголовком, а если заголовка нет, то в нижней строке; статистика diff отображается рядом со временем. И то и другое работает в ответах на команды, и их использует встроенная интеграция GitHub. Вебхук их отбрасывает.

json
{
  "message_container": {
    "color": "red",
    "title": "Build failed on main",
    "status": { "label": "Failing", "color": "red" },
    "description": "`search.test.js`: 2 of 212 tests failed."
  }
}
ПолеТипЧто делает
statusobject или stringОбычная строка считается меткой: "status": "Open".
status.labelstringТекст плашки. Без него плашки нет.
status.colorstringgreen, purple, red, orange, yellow, blue или gray.
status.iconstringНеобязательная иконка из списка ниже.
additionsnumberДобавленные строки, показываются зелёным +86.
deletionsnumberУдалённые строки, показываются красным -12.
files_changednumberЗатронутые файлы, показываются как 3 files.

Иконки

ЗначениеИконкаТипичное применение
pull_requestgit-pull-requestОткрыт pull request
pull_request_closedgit-pull-request-closedЗакрыт без слияния
merge, mergedgit-mergeСлит
commitgit-commitОтправлен коммит
issuecircle-dotОткрыт issue
issue_closedcircle-checkЗакрыт issue
checkcircle-checkТесты прошли, задача выполнена успешно

Соответствие, которое подходит для GitHub

Их использует встроенная интеграция GitHub; скопируйте их для своих инструментов.

СобытиеМеткаЦветИконка
Открыт pull requestOpengreenpull_request
ЧерновикDraftgraypull_request
СлитMergedpurplemerged
Закрыт без слиянияClosedredpull_request_closed
Открыт issueOpengreenissue
Закрыт issueClosedpurpleissue_closed
Отправлен коммитCommitgraycommit
Тесты прошлиPassinggreencheck
Тесты не прошлиFailingredнет

Загрузка и размышления

Для всего, что занимает время, например ответа ИИ или долгой задачи, сначала опубликуйте карточку со спиннером, а потом замените её результатом. Индикатор загрузки работает и в вебхуках, и в ответах на команды. В ответе на команду рассуждения модели можно также поместить в thinking: вместо стены текста участники увидят переключатель Показать размышления.

assistant
System
Сообщение от Assistant
Думаю…Читаю последние 50 сообщений

Сначала: индикатор загрузки

assistant
System
Сообщение от Assistant

maya: когда стендап?

Стендап в 09:30, в #daily.
Проверил закреплённые сообщения и повторяющееся событие в #daily.

Потом: ответ, размышления свёрнуты

json
{
  "message_container": {
    "type": "embed_message",
    "color": "blue",
    "loader": true,
    "loader_text": "Thinking…",
    "loader_sub_text": "Reading the last 50 messages"
  }
}
json
{
  "message_container": {
    "type": "embed_message",
    "color": "blue",
    "sub_title": "maya: when is the standup?",
    "description": "Standup is at **09:30**, in #daily.",
    "thinking": "Checked the pinned messages and the recurring event in #daily…"
  }
}
ПолеТипЧто делает
loaderbooleantrue показывает спиннер вместо основного текста.
loader_textstringСтрока рядом со спиннером, например «Думаю…».
loader_sub_textstringСтрока поменьше под ней.
thinkingstringСвёрнутые размышления под описанием, в markdown.

Чтобы заменить индикатор загрузки ответом, обновите сообщение новой карточкой без loader. Как это сделать, описано на странице обновлений вживую.

Длинные описания

Описание может занимать до 50 000 байт. После первых 1 000 участники видят начало и кнопку Показать больше, которая загружает остальное, так что длинный отчёт не заваливает канал.

Системные сообщения

Задайте "type": "system_message" для объявления, а не поста бота: окна обслуживания, изменения правил, всё, что говорит от имени самого сообщества. Такое сообщение принимает те же поля и кнопки.

json
{
  "message_container": {
    "type": "system_message",
    "color": "orange",
    "title": "Maintenance tonight",
    "description": "The build servers are down from 22:00 to 23:00."
  }
}

Цвета

Цвет кромки считывается на карточке быстрее всего. Всегда используйте один и тот же цвет для одного и того же рода новостей.

ЦветДля чего
greenУспех: пройдено, выкачено, готово
redНеудача: ошибка, недоступно, отклонено
orangeПредупреждение, на которое стоит взглянуть
yellowЖдёт чьего-то решения: одобрения, вопросы
blueИнформация, по умолчанию
purpleСобытия в коде или что-то особенное

Соберите свой embed

Редактируйте поля или JSON-payload. Они синхронизируются в обе стороны. Сообщение отображается точно так же, как в канале. Это настоящее тело webhook-запроса; скопируйте его, когда всё будет готово.

Шаблоны
Кнопки
Предпросмотр
Тело webhook

Что дальше