Bots et messages interactifs
Un compte de bot est un utilisateur créé pour un programme. Il possède son propre nom, sa propre image et ses propres jetons, et un badge BOT s'affiche à côté de son nom. Cette page aborde également les aspects interactifs des messages : boutons, menus et boîtes de dialogue, que toute intégration peut utiliser.
Pourquoi un compte de bot
- Ses messages proviennent d'une identité claire, avec un badge BOT, au lieu de provenir du compte d'un collègue.
- Ses jetons continuent de fonctionner lorsque la personne qui l'a configuré change de rôle ou quitte l'organisation (sauf si le serveur désactive les bots dont le propriétaire est désactivé, voir ci-dessous).
- Les bots ne peuvent pas se connecter avec un mot de passe et ne voient jamais l'application web.
Les applications créent leurs propres bots, tels que les bots Todo ou Playbooks, via l'API de plugin (EnsureBotUser).
Activer les comptes de bot
Un admin système active Activer la création de comptes de bot dans Console système › Intégrations › Comptes de bot (ServiceSettings.EnableBotAccountCreation, AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION). Cette option est désactivée par défaut. Seuls les admins système peuvent créer des bots, sauf s'ils accordent ce droit à d'autres rôles dans les paramètres de permissions.
Sur la même page, Désactiver les comptes de bot lorsque leur propriétaire est désactivé (ServiceSettings.DisableBotsWhenOwnerIsDeactivated, activé par défaut) désactive un bot lorsque le compte de son propriétaire est désactivé.
Créer un bot
- Ouvrez votre avatar en haut à droite, puis Intégrations › Comptes de bot, puis Ajouter un compte de bot.
- Saisissez un Nom d'utilisateur (lettres minuscules, chiffres, points, tirets et tirets bas), ainsi que, en option, une Icône du bot, un Nom d'affichage et une Description.
- Choisissez le Rôle : Membre, ou Admin système pour un bot qui gère le serveur. Accordez au bot le minimum nécessaire.
- Cochez message:canaux pour lui permettre de publier dans tous les canaux publics, ou message:tous pour tous les canaux, y compris les canaux privés et les messages personnels, sans en être membre.
- Définissez la date d'expiration de son jeton par défaut, puis choisissez Créer un compte de bot.
- Copiez le jeton d'accès affiché. Il ne sera plus affiché ensuite.
Plus tard, Créer un nouveau jeton sur la ligne du bot ajoute un jeton, et chaque jeton peut être désactivé ou supprimé. Les jetons de bot fonctionnent même lorsque les jetons d'accès personnels sont désactivés pour les utilisateurs.
Via l'API :
# create the bot (you become its owner)
curl -X POST https://chat.example.com/api/v4/bots \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"username": "deploy-bot", "display_name": "Deploy", "description": "Posts deployments"}'
# give it a token
curl -X POST https://chat.example.com/api/v4/users/$BOT_USER_ID/tokens \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"description": "deploy pipeline"}'
Depuis la ligne de commande, connecté en tant qu'admin (et non en mode local) : amctl bot create deploy-bot --display-name Deploy --with-token --expires-in 90d. Autres points d'accès : GET /api/v4/bots, PUT /api/v4/bots/{bot_user_id}, POST /api/v4/bots/{bot_user_id}/disable et /enable, POST /api/v4/bots/{bot_user_id}/assign/{user_id} pour changer son propriétaire.
Ajouter le bot aux communautés et aux canaux
Un nouveau bot n'appartient à aucune communauté. Ajoutez-le comme un utilisateur, depuis la gestion des membres de la communauté ou via l'API :
curl -X POST https://chat.example.com/api/v4/teams/$TEAM_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"team_id": "'$TEAM_ID'", "user_id": "'$BOT_USER_ID'"}'
curl -X POST https://chat.example.com/api/v4/channels/$CHANNEL_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"user_id": "'$BOT_USER_ID'"}'
Un bot disposant de message:canaux ou message:tous peut publier sans être membre, mais il ne reçoit des événements WebSocket que pour les canaux auxquels il appartient.
Publier en tant que bot
Utilisez le jeton du bot pour tout appel à l'API ; POST /api/v4/posts est le plus courant (voir Ressources principales). Pour écrire directement à quelqu'un, ouvrez d'abord le canal de message personnel :
# returns the channel; use its "id" as channel_id
curl -X POST https://chat.example.com/api/v4/channels/direct \
-H "Authorization: Bearer $BOT_TOKEN" -H 'Content-Type: application/json' \
-d '["'$BOT_USER_ID'", "'$USER_ID'"]'
Pour réagir à ce que disent les utilisateurs, suivez le WebSocket avec le jeton du bot et répondez aux événements posted qui vous intéressent. Ignorez les messages du bot lui-même pour éviter les boucles.
Un message visible par une seule personne (un message éphémère) est envoyé avec POST /api/v4/posts/ephemeral et {"user_id", "post": {"channel_id", "message"}}. Il nécessite la permission create_post_ephemeral, dont seuls les admins système disposent par défaut. Les intégrations envoient généralement des messages éphémères en réponse aux commandes slash et aux boutons.
Messages interactifs : boutons et menus
Tout message avec des pièces jointes peut porter des actions : des boutons, et des menus pour faire un choix. Ils fonctionnent dans les messages publiés via l'API, les webhooks et les réponses aux commandes slash. Quand quelqu'un en utilise un, Antimatter appelle l'URL de votre intégration.
{
"channel_id": "…",
"message": "Deploy **api 2.4.0** to production?",
"props": {
"attachments": [{
"actions": [
{
"id": "approve",
"type": "button",
"name": "Approve",
"style": "primary",
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "approve"}}
},
{
"id": "env",
"type": "select",
"name": "Pick an environment",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}],
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "env"}}
}
]
}]
}
}
type:buttonouselect.id: lettres, chiffres, tirets et tirets bas, différents pour chaque action du message. Il est généré si vous l'omettez.style(boutons) :default,primary,success,good,warning,danger, ou une couleur en hexadécimal.options(menus), oudata_source:usersouchannelspour choisir une personne ou un canal.default_optionprésélectionne une valeur.integration.url: l’endroit où le clic est envoyé. Une application (plugin) peut utiliser sa propre route, par exemple/plugins/com.example.deploy/actions.integration.contextest à vous : il revient avec le clic, et les clients ne le voient jamais.
La requête reçue par votre intégration
{
"user_id": "…",
"user_name": "priya",
"channel_id": "…",
"channel_name": "releases",
"team_id": "…",
"team_domain": "lumen-labs",
"post_id": "…",
"trigger_id": "…",
"type": "button",
"context": {"release": "2.4.0", "action": "approve"}
}
Pour un menu, type est select et context.selected_option contient la valeur choisie.
Votre réponse
{
"update": {"message": "Deploy of **api 2.4.0** approved by @priya", "props": {}},
"ephemeral_text": "Done. The deploy starts in a minute."
}
update: remplace le texte et les propriétés du message, par exemple pour retirer les boutons une fois utilisés (unpropsvide).ephemeral_text: un message que seule la personne qui a cliqué voit.goto_location: une URL à ouvrir.- Un corps vide ne change rien.
Le serveur attend aussi longtemps que le Délai d’attente des requêtes d’intégration le permet (30 secondes par défaut). Les URL d’intégration sur des adresses de réseau privé doivent être autorisées par un admin système, comme pour les webhooks.
Dialogues
Un dialogue est un formulaire qui s’ouvre par-dessus la discussion. Vous ne pouvez l’ouvrir qu’en réponse à quelque chose que la personne vient de faire, une commande slash ou un bouton, car il a besoin du trigger_id de cette requête. Le trigger_id est valide pendant la durée du délai d’attente des requêtes d’intégration.
curl -X POST https://chat.example.com/api/v4/actions/dialogs/open \
-H 'Content-Type: application/json' \
-d '{
"trigger_id": "'$TRIGGER_ID'",
"url": "https://deploy.example.com/dialog",
"dialog": {
"callback_id": "new-release",
"title": "New release",
"introduction_text": "Fill in the release details.",
"submit_label": "Create",
"notify_on_cancel": false,
"state": "anything you want back",
"elements": [
{"display_name": "Version", "name": "version", "type": "text", "placeholder": "2.4.0"},
{"display_name": "Notes", "name": "notes", "type": "textarea", "optional": true},
{"display_name": "Environment", "name": "env", "type": "select",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}]},
{"display_name": "Owner", "name": "owner", "type": "select", "data_source": "users"},
{"display_name": "Notify the channel", "name": "notify", "type": "bool", "default": "true"}
]
}
}'
| Type d’élément | Ce qu’il affiche |
|---|---|
text | Un champ sur une ligne. subtype : text, email, number, password, tel ou url. min_length et max_length le limitent. |
textarea | Un champ sur plusieurs lignes. |
select | Une liste : options, ou data_source users, channels, ou dynamic avec un data_source_url. multiselect autorise plusieurs valeurs. |
bool | Une case à cocher. |
radio | Un choix parmi options. |
date, datetime | Une date, ou une date et une heure. |
Chaque élément prend display_name, name, help_text, placeholder, default et optional.
Lorsque la personne soumet, Antimatter envoie une requête POST à l’url du dialogue :
{
"type": "dialog_submission",
"callback_id": "new-release",
"state": "anything you want back",
"user_id": "…",
"channel_id": "…",
"team_id": "…",
"submission": {"version": "2.4.0", "notes": "", "env": "staging", "owner": "…", "notify": true},
"cancelled": false
}
Répondez avec un corps vide pour fermer le dialogue, ou gardez-le ouvert et montrez ce qui ne va pas :
{"errors": {"version": "This version already exists."}}
{"error": "…"} affiche un message pour tout le formulaire. Avec notify_on_cancel, la fermeture du dialogue envoie "cancelled": true. Les dialogues fonctionnent de la même manière dans les applications : OpenInteractiveDialog de l’API des plugins prend la même requête.