Pular para o conteúdo principal
Desenvolvedores Cartões de mensagem

Crie cartões de mensagem

Tudo o que um bot publica, seja por um webhook, numa resposta a um comando ou numa atualização por botão, é um cartão. Um bom cartão mostra o que aconteceu num relance: uma borda colorida, um título, um status e os detalhes embaixo.

O que você pode fazer

  • Mostre um statusUma pílula colorida como Open, Merged ou Passing, com as linhas adicionadas e removidas.
  • Liste os detalhesLinhas de rótulo e valor que os membros copiam com um toque.
  • Escreva em markdownNegrito, código inline, blocos de código, citações e caixas de seleção.
  • Mostre que está trabalhandoUm spinner enquanto o seu bot pensa, e depois o raciocínio dele atrás de um botão de alternância.

No app

Quatro cartões como os membros os veem. Cada um é poucas linhas de JSON.

Anatomia de um cartão

As partes de um cartão, de cima para baixo. Deixe de fora o que você não precisa: um cartão só com título também vale.

  1. Cabeçalho“Message from” e um nome: o nome do webhook ou, numa resposta a comando, o nome da sua comunidade. Uma resposta pode acrescentar um badge, como o repositório.
  2. Título e statusO title, que vira link quando você define title_url, com a pílula de status ao lado.
  3. SubtítuloUma segunda linha em negrito, sub_title.
  4. DescriçãoO corpo, em markdown.
  5. CamposLinhas de rótulo e valor, com um botão de copiar.
  6. RodapéO horário e as linhas adicionadas e removidas, se você as enviar.
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
  }
}

Todos os campos

Estes campos vão em message_container. Um cartão precisa de uma descrição ou de um loader. Os campos marcados como “Respostas a comandos” são descartados quando você publica por um webhook.

CampoTipoO que faz
typestringembed_message (o padrão) ou system_message.
badgestringUm pequeno selo depois do nome no cabeçalho, como acme/web. Respostas a comandos
avatar_urlstringUma imagem sobre o ícone do cartão.
colorstringA cor da borda. Veja as cores abaixo.
titlestringA primeira linha, em negrito.
title_urlstringTransforma o título num link.
sub_titlestringUma segunda linha em negrito embaixo do título.
descriptionstringO corpo, em markdown.
fieldsarray[{ "field": "…", "value": "…" }]: linhas de rótulo e valor.
image_url, image_base64stringUma imagem no cartão.
imagesarray[{ "image_url": "…" }]: uma galeria de várias imagens.
statusobject ou stringUma pílula colorida ao lado do título. Veja abaixo. Respostas a comandos
additions, deletions, files_changednumberEstatísticas de diff no rodapé. Respostas a comandos
loader, loader_text, loader_sub_textboolean, stringUm spinner no lugar do corpo.
thinkingstringRaciocínio atrás de um botão Show thinking. Respostas a comandos
A descrição e thinking entendem markdown: **bold**, _italic_, ~~strike~~, `inline code`, blocos de código entre crases triplas, > quotes, caixas de seleção - [x], @menções e :emoji:.

Status e estatísticas de diff

Uma pílula de status conta a história antes que alguém leia o texto. Ela fica ao lado do título, ou no rodapé quando não há título; as estatísticas de diff aparecem ao lado do horário. As duas funcionam em respostas a comandos, e a integração nativa com o GitHub usa ambas. Um webhook as descarta.

json
{
  "message_container": {
    "color": "red",
    "title": "Build failed on main",
    "status": { "label": "Failing", "color": "red" },
    "description": "`search.test.js`: 2 of 212 tests failed."
  }
}
CampoTipoO que faz
statusobject ou stringUma string simples é o rótulo: "status": "Open".
status.labelstringO texto da pílula. Sem ele, não há pílula.
status.colorstringgreen, purple, red, orange, yellow, blue ou gray.
status.iconstringUm ícone opcional da lista abaixo.
additionsnumberLinhas adicionadas, mostradas como +86 em verde.
deletionsnumberLinhas removidas, mostradas como -12 em vermelho.
files_changednumberArquivos alterados, mostrados como 3 files.

Ícones

ValorÍconeUso típico
pull_requestgit-pull-requestUm pull request aberto
pull_request_closedgit-pull-request-closedFechado sem merge
merge, mergedgit-mergeMesclado
commitgit-commitUm commit enviado
issuecircle-dotUma issue aberta
issue_closedcircle-checkUma issue fechada
checkcircle-checkTestes passaram, um job deu certo

Um mapeamento que funciona para o GitHub

A integração nativa com o GitHub usa estes valores; copie-os para as suas próprias ferramentas.

EventoRótuloCorÍcone
Pull request abertoOpengreenpull_request
RascunhoDraftgraypull_request
MescladoMergedpurplemerged
Fechado sem mergeClosedredpull_request_closed
Issue abertaOpengreenissue
Issue fechadaClosedpurpleissue_closed
Commit enviadoCommitgraycommit
Testes passaramPassinggreencheck
Testes falharamFailingrednenhum

Loader e raciocínio

Para qualquer coisa que leve um momento, como uma resposta de IA ou um job longo, publique primeiro um cartão com um spinner e depois troque pelo resultado. O loader funciona em webhooks e em respostas a comandos. Numa resposta a comando, você também pode colocar o raciocínio do modelo em thinking: os membros veem um botão Show thinking em vez de um paredão de texto.

assistant
System
Message from Assistant
Pensando…Lendo as últimas 50 mensagens

Primeiro: o loader

assistant
System
Message from Assistant

maya: que horas é o standup?

O standup é às 09:30, em #daily.
Conferi as mensagens fixadas e o evento recorrente em #daily.

Depois: a resposta, com o raciocínio recolhido

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…"
  }
}
CampoTipoO que faz
loaderbooleantrue mostra o spinner no lugar do corpo.
loader_textstringA linha ao lado do spinner, como “Pensando…”.
loader_sub_textstringUma linha menor embaixo dela.
thinkingstringRaciocínio recolhido embaixo da descrição, em markdown.

Para trocar o loader pela resposta, atualize a mensagem com um cartão novo sem loader. Como fazer isso está em atualizações ao vivo.

Descrições longas

Uma descrição pode ter até 50.000 bytes. Passando dos primeiros 1.000, os membros veem o começo e um botão Show more que carrega o resto, para que um relatório longo não inunde o canal.

Mensagens de sistema

Defina "type": "system_message" para um aviso em vez de uma publicação de bot: janelas de manutenção, mudanças de regras, qualquer coisa que fale em nome da própria comunidade. Aceita os mesmos campos e botões.

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

Cores

A cor da borda é o sinal mais rápido de um cartão. Use sempre a mesma cor para o mesmo tipo de notícia.

CorUse para
greenSucesso: passou, implantado, concluído
redFalha: falhou, fora do ar, rejeitado
orangeUm aviso que merece uma olhada
yellowEsperando alguém: aprovações, perguntas
blueInformação, o padrão
purpleEventos de código, ou algo especial

Monte seu embed

Edite os campos ou o payload JSON: os dois ficam sincronizados. A prévia mostra a mensagem exatamente como ela vai aparecer num canal. Este é o body real do webhook; copie quando estiver tudo certo.

Modelos
Botões
Prévia
Body do webhook

Continue criando