Concevoir des cartes de message
Tout ce qu’un bot publie, depuis un webhook, une réponse à une commande ou la mise à jour d’un bouton, est une carte. Une bonne carte dit ce qui s’est passé en un coup d’œil : une bordure colorée, un titre, un statut, les détails en dessous.
Ce que vous pouvez faire
- Afficher un statutUne pastille colorée comme Ouverte, Mergée ou Réussi, avec les lignes ajoutées et supprimées.
- Lister les détailsDes lignes libellé et valeur que les membres copient en un appui.
- Écrire en markdownGras, code en ligne, blocs de code, citations et cases à cocher.
- Montrer que tu travaillesUn indicateur qui tourne pendant que ton bot réfléchit, puis son raisonnement derrière un bouton à déplier.
Dans l'app
Quatre cartes telles que les membres les voient. Chacune tient en quelques lignes de JSON.
Anatomie d’une carte
Les parties d’une carte, de haut en bas. Omets ce dont tu n’as pas besoin : une carte avec seulement un titre, ça marche.
- En-tête« Message de » et un nom : le nom du webhook, ou celui de ta communauté pour une réponse de commande. Une réponse peut ajouter un
badge, comme le dépôt. - Titre et statutLe
title, qui devient un lien si tu définistitle_url, avec la pastillestatusà côté. - Sous-titreUne deuxième ligne en gras,
sub_title. - DescriptionLe corps, en markdown.
- ChampsDes lignes libellé et valeur, avec un bouton de copie.
- Pied de carteL’heure, et les lignes ajoutées et supprimées si tu les envoies.
{
"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
}
}Tous les champs
Ils vont dans message_container. Une carte a besoin d’une description, ou d’un indicateur de chargement. Les champs marqués « Réponses de commande » sont ignorés quand tu publies via un webhook.
| Champ | Type | Ce qu’il fait |
|---|---|---|
type | string | embed_message (par défaut) ou system_message. |
badge | string | Une petite pastille après le nom dans l’en-tête, comme acme/web. Réponses de commande |
avatar_url | string | Une image par-dessus l’icône de la carte. |
color | string | La couleur de la bordure. Voir les couleurs plus bas. |
title | string | La première ligne, en gras. |
title_url | string | Transforme le titre en lien. |
sub_title | string | Une deuxième ligne en gras sous le titre. |
description | string | Le corps, en markdown. |
fields | array | [{ "field": "…", "value": "…" }] : des lignes libellé et valeur. |
image_url, image_base64 | string | Une image sur la carte. |
images | array | [{ "image_url": "…" }] : une galerie de plusieurs images. |
status | object ou string | Une pastille colorée à côté du titre. Voir plus bas. Réponses de commande |
additions, deletions, files_changed | number | Les stats de diff dans le pied de carte. Réponses de commande |
loader, loader_text, loader_sub_text | boolean, string | Un indicateur de chargement à la place du corps. |
thinking | string | Le raisonnement derrière un bouton Afficher le raisonnement. Réponses de commande |
thinking comprennent le markdown : **gras**, _italique_, ~~barré~~, `code en ligne`, les blocs de code délimités, > citations, les cases à cocher - [x], les @mentions et :emoji:.Statut et stats de diff
Une pastille de statut raconte l’histoire avant qu’on lise le texte. Elle se place à côté du titre, ou dans le pied de carte s’il n’y a pas de titre ; les stats de diff s’affichent à côté de l’heure. Les deux fonctionnent dans les réponses de commande, et l’intégration GitHub native s’en sert. Un webhook les ignore.
{
"message_container": {
"color": "red",
"title": "Build failed on main",
"status": { "label": "Failing", "color": "red" },
"description": "`search.test.js`: 2 of 212 tests failed."
}
}| Champ | Type | Ce qu’il fait |
|---|---|---|
status | object ou string | Une simple chaîne sert de libellé : "status": "Open". |
status.label | string | Le texte de la pastille. Sans lui, pas de pastille. |
status.color | string | green, purple, red, orange, yellow, blue ou gray. |
status.icon | string | Une icône facultative, choisie dans la liste ci-dessous. |
additions | number | Les lignes ajoutées, affichées en vert : +86. |
deletions | number | Les lignes supprimées, affichées en rouge : -12. |
files_changed | number | Les fichiers modifiés, affichés sous la forme 3 files. |
Icônes
| Valeur | Icône | Usage typique |
|---|---|---|
pull_request | git-pull-request | Une pull request ouverte |
pull_request_closed | git-pull-request-closed | Fermée sans merge |
merge, merged | git-merge | Mergée |
commit | git-commit | Un commit poussé |
issue | circle-dot | Une issue ouverte |
issue_closed | circle-check | Une issue fermée |
check | circle-check | Tests réussis, tâche terminée avec succès |
Une correspondance qui marche pour GitHub
L’intégration GitHub native utilise celles-ci ; reprends-les pour tes propres outils.
| Événement | Libellé | Couleur | Icône |
|---|---|---|---|
| Pull request ouverte | Open | green | pull_request |
| Brouillon | Draft | gray | pull_request |
| Mergée | Merged | purple | merged |
| Fermée sans merge | Closed | red | pull_request_closed |
| Issue ouverte | Open | green | issue |
| Issue fermée | Closed | purple | issue_closed |
| Commit poussé | Commit | gray | commit |
| Tests réussis | Passing | green | check |
| Tests en échec | Failing | red | aucune |
Chargement et raisonnement
Pour tout ce qui prend un moment, comme une réponse d’IA ou une longue tâche, publie d’abord une carte avec un indicateur de chargement, puis remplace-la par le résultat. Le chargement fonctionne depuis les webhooks et les réponses de commande. Dans une réponse de commande, tu peux aussi mettre le raisonnement du modèle dans thinking : les membres voient un bouton Afficher le raisonnement au lieu d’un pavé de texte.
D’abord : le chargement
Ensuite : la réponse, raisonnement replié
{
"message_container": {
"type": "embed_message",
"color": "blue",
"loader": true,
"loader_text": "Thinking…",
"loader_sub_text": "Reading the last 50 messages"
}
}{
"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…"
}
}| Champ | Type | Ce qu’il fait |
|---|---|---|
loader | boolean | true affiche l’indicateur à la place du corps. |
loader_text | string | La ligne à côté de l’indicateur, comme « Réflexion… ». |
loader_sub_text | string | Une ligne plus petite en dessous. |
thinking | string | Le raisonnement replié sous la description, en markdown. |
Pour remplacer le chargement par la réponse, mets à jour le message avec une nouvelle carte sans loader. La marche à suivre est sur mises à jour en direct.
Descriptions longues
Une description peut faire jusqu’à 50 000 octets. Au-delà des 1 000 premiers, les membres voient le début et un bouton Afficher plus qui charge le reste, pour qu’un long rapport n’inonde pas le salon.
Messages système
Mets "type": "system_message" pour un avis plutôt qu’un message de bot : fenêtres de maintenance, changements de règles, tout ce qui parle au nom de la communauté elle-même. Il accepte les mêmes champs et les mêmes boutons.
{
"message_container": {
"type": "system_message",
"color": "orange",
"title": "Maintenance tonight",
"description": "The build servers are down from 22:00 to 23:00."
}
}Couleurs
La couleur de la bordure est le signal le plus rapide d’une carte. Utilise toujours la même couleur pour le même genre de nouvelle.
| Couleur | À utiliser pour |
|---|---|
green | Succès : réussi, déployé, terminé |
red | Échec : raté, hors ligne, refusé |
orange | Un avertissement qui mérite un coup d’œil |
yellow | En attente de quelqu’un : validations, questions |
blue | Information, la couleur par défaut |
purple | Événements de code, ou quelque chose de spécial |
Construis ton embed
Modifie les champs ou le payload JSON. Les deux restent synchronisés. Regarde le message s’afficher exactement comme dans un canal. C’est le vrai body du webhook ; copie-le quand le résultat te convient.