Mattermost
État : plugin téléchargeable (jeton de bot + événements WebSocket). Les channels, les groupes et les DMs sont pris en charge. Mattermost est une plateforme de messagerie d’équipe auto-hébergeable ; consultez le site officiel à mattermost.com pour plus de détails sur le produit et les téléchargements.
Installer
Section intitulée « Installer »Installez Mattermost avant de configurer le canal :
bash openclaw plugins install @openclaw/mattermost
bash openclaw plugins install ./path/to/local/mattermost-plugin
Détails : Plugins
Configuration rapide
Section intitulée « Configuration rapide »S'assurer que le plugin est disponible
Les versions actuelles empaquetées de OpenClaw l’incluent déjà. Les installations plus anciennes ou personnalisées peuvent l’ajouter manuellement avec les commandes ci-dessus.
Créer un bot Mattermost
Créez un compte bot Mattermost et copiez le bot token.
Copier l'URL de base
Copiez l’URL de base de Mattermost (par ex.,
https://chat.example.com).Configurer OpenClaw et démarrer la passerelle
Configuration minimale :
{channels: {mattermost: {enabled: true,botToken: "mm-token",baseUrl: "https://chat.example.com",dmPolicy: "pairing",},},}
Commandes slash natives
Section intitulée « Commandes slash natives »Les commandes slash natives sont optionnelles. Lorsqu’elles sont activées, OpenClaw enregistre des commandes slash oc_* via l’Mattermost API et reçoit des POST de rappel sur le serveur HTTP de la passerelle.
{ channels: { mattermost: { commands: { native: true, nativeSkills: true, callbackPath: "/api/channels/mattermost/command", // Use when Mattermost cannot reach the gateway directly (reverse proxy/public URL). callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, }, },}Remarques sur le comportement
native: "auto"Mattermost est désactivé par défaut pour Mattermost. Définisseznative: truepour activer.- Si
callbackUrlOpenClaw est omis, OpenClaw en dérive un à partir de l’hôte/port de la passerelle +callbackPath. - Pour les configurations multi-comptes,
commandspeut être défini au niveau supérieur ou sous `channels.mattermost.accounts.
.commandsMattermostOpenClaw (les valeurs de compte remplacent les champs de niveau supérieur). - Les rappels de commande sont validés avec les jetons par commande renvoyés par Mattermost lorsqu'OpenClaw enregistre les commandes oc_*`OpenClawMattermostMattermostAPI.
- OpenClaw actualise l’enregistrement actuel de la commande Mattermost avant d’accepter chaque rappel, afin que les jetons périmés des commandes slash supprimées ou régénérées cessent d’être acceptés sans redémarrage de la passerelle.
- La validation des rappels échoue en mode fermé si l’API Mattermost ne peut pas confirmer que la commande est toujours actuelle ; les validations échouées sont mises en cache brièvement, les recherches simultanées sont fusionnées et les nouvelles recherches sont limitées par taux par commande pour borner la pression de relecture.
- Les rappels slash échouent en mode fermé lorsque l’enregistrement a échoué, le démarrage était partiel, ou que le jeton de rappel ne correspond pas au jeton enregistré de la commande résolue (un jeton valide pour une commande ne peut pas atteindre la validation en amont pour une autre commande).
Exigence d'accessibilité
Le point de terminaison de rappel doit être accessible depuis le serveur Mattermost.
- Ne définissez pas
callbackUrlsurlocalhostMattermostOpenClaw sauf si Mattermost s’exécute sur le même hôte/espace de réseau qu’OpenClaw. - Ne définissez pas
callbackUrlMattermost sur votre URL de base Mattermost, sauf si cette URL effectue un proxy inverse de/api/channels/mattermost/commandOpenClaw vers OpenClaw. - Une vérification rapide est `curl https://
/api/channels/mattermost/command; une requête GET doit renvoyer405 Method Not AllowedOpenClaw depuis OpenClaw, et non 404`.
MattermostListe blanche de sortie Mattermost
Si vos cibles de rappel sont des adresses privées/tailnet/internes, définissez Mattermost ServiceSettings.AllowedUntrustedInternalConnections pour inclure l’hôte/le domaine de rappel.
Utilisez des entrées d’hôte/de domaine, pas des URL complètes.
- Bon :
gateway.tailnet-name.ts.net - Mauvais :
https://gateway.tailnet-name.ts.net
Variables d’environnement (compte par défaut)
Section intitulée « Variables d’environnement (compte par défaut) »Définissez-les sur l’hôte de la passerelle si vous préférez les env vars :
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Modes de discussion
Section intitulée « Modes de discussion »Mattermost répond automatiquement aux DMs. Le comportement du channel est contrôlé par Mattermostchatmode :
Répondre uniquement lorsqu’il est mentionné (@mention) dans les channels.
Répondre à chaque message de channel.
Répondre lorsqu’un message commence par un préfixe de déclenchement.
Exemple de configuration :
{ channels: { mattermost: { chatmode: "onchar", oncharPrefixes: [">", "!"], }, },}Notes :
oncharrépond toujours aux mentions @ explicites.channels.mattermost.requireMentionest respecté pour les configurations héritées maischatmodeest préféré.
Fils de discussion et sessions
Section intitulée « Fils de discussion et sessions »Utilisez channels.mattermost.replyToMode pour contrôler si les réponses dans les channels et les groupes restent dans le channel principal ou commencent un fil sous le message déclencheur.
off(par défaut) : ne répond dans un fil que si le message entrant est déjà dans un fil.first: pour les messages de channel/groupe de niveau supérieur, démarre un fil sous ce message et route la conversation vers une session délimitée par le fil.all: même comportement quefirstpour Mattermost aujourd’hui.- Les messages directs ignorent ce paramètre et restent non threadés.
Exemple de configuration :
{ channels: { mattermost: { replyToMode: "all", }, },}Notes :
- Les sessions délimitées par un fil utilisent l’ID du message déclencheur comme racine du fil.
firstetallsont actuellement équivalents car une fois que Mattermost a une racine de fil, les blocs suivants et les médias continuent dans ce même fil.
Contrôle d’accès (DMs)
Section intitulée « Contrôle d’accès (DMs) »- Par défaut :
channels.mattermost.dmPolicy = "pairing"(les expéditeurs inconnus reçoivent un code d’appairage). - Approuver via :
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- DMs publics :
channels.mattermost.dmPolicy="open"pluschannels.mattermost.allowFrom=["*"]. channels.mattermost.allowFromaccepte les entréesaccessGroup:<name>. Voir Groupes d’accès.
Canaux (groupes)
Section intitulée « Canaux (groupes) »- Par défaut :
channels.mattermost.groupPolicy = "allowlist"(limité par mention). - Liste blanche des expéditeurs avec
channels.mattermost.groupAllowFrom(IDs utilisateur recommandés). channels.mattermost.groupAllowFromaccepte les entréesaccessGroup:<name>. Voir Groupes d’accès.- Les remplacements de mention par channel se trouvent sous
channels.mattermost.groups.<channelId>.requireMentionouchannels.mattermost.groups["*"].requireMentionpour une valeur par défaut. - La correspondance
@usernameest modifiable et uniquement activée lorsquechannels.mattermost.dangerouslyAllowNameMatching: true. - Channels ouverts :
channels.mattermost.groupPolicy="open"(limité par mention). - Remarque d’exécution : si
channels.mattermostest totalement absent, l’exécution revient par défaut àgroupPolicy="allowlist"pour les vérifications de groupe (même sichannels.defaults.groupPolicyest défini).
Exemple :
{ channels: { mattermost: { groupPolicy: "open", groups: { "*": { requireMention: true }, "team-channel-id": { requireMention: false }, }, }, },}Cibles pour la livraison sortante
Section intitulée « Cibles pour la livraison sortante »Utilisez ces formats de cible avec openclaw message send ou cron/webhooks :
channel:<id>pour un channeluser:<id>pour un DM@usernamepour un DM (résolu via l’Mattermost API)
Nouvelle tentative de channel DM
Section intitulée « Nouvelle tentative de channel DM »Lorsque OpenClaw envoie à une cible DM Mattermost et doit d’abord résoudre le channel direct, il réessaie par défaut les échecs transitoires de création de channel direct.
Utilisez channels.mattermost.dmChannelRetry pour ajuster ce comportement globalement pour le plugin Mattermost, ou channels.mattermost.accounts.<id>.dmChannelRetry pour un compte.
{ channels: { mattermost: { dmChannelRetry: { maxRetries: 3, initialDelayMs: 1000, maxDelayMs: 10000, timeoutMs: 30000, }, }, },}Notes :
- Cela s’applique uniquement à la création de channel DM (
/api/v4/channels/direct), et non à chaque appel à l’Mattermost API. - Les nouvelles tentatives s’appliquent aux échecs transitoires tels que les limites de débit, les réponses 5xx, et les erreurs réseau ou d’expiration.
- Les erreurs client 4xx autres que
429sont traitées comme permanentes et ne font pas l’objet d’une nouvelle tentative.
Aperçu du streaming
Section intitulée « Aperçu du streaming »Mattermost diffuse la réflexion, l’activité des outils et le texte de réponse partiel dans un seul brouillon de publication de prévisualisation qui est finalisé sur place lorsque la réponse finale est prête à être envoyée. La prévisualisation se met à jour sur le même identifiant de publication au lieu de spammer le channel avec des messages par fragment. Les finales médias/erreur annulent les modifications de prévisualisation en attente et utilisent la livraison normale au lieu de vider une publication de prévisualisation jetable.
Activer via channels.mattermost.streaming :
{ channels: { mattermost: { streaming: "partial", // off | partial | block | progress }, },}Modes de streaming
partialest le choix habituel : une publication de prévisualisation qui est modifiée au fur et à mesure que la réponse grandit, puis finalisée avec la réponse complète.blockutilise des fragments de brouillon de type ajout à l’intérieur de la publication de prévisualisation.progressaffiche une prévisualisation de l’état lors de la génération et ne publie la réponse finale qu’à la fin.offdésactive le streaming de prévisualisation.
Notes sur le comportement du streaming
- Si le flux ne peut pas être finalisé sur place (par exemple si le message a été supprimé pendant le flux), OpenClaw se rabat sur l’envoi d’un nouveau message final pour que la réponse ne soit jamais perdue.
- Les payloads contenant uniquement de la réflexion sont supprimés des messages de channel, y compris le texte qui arrive sous forme de
> Thinkingblockquote. Définissez/reasoning onpour voir la réflexion sur d’autres surfaces ; le message final Mattermost ne conserve que la réponse. - Voir Streaming pour la matrice de mappage des channels.
Réactions (outil de message)
Section intitulée « Réactions (outil de message) »- Utilisez
message action=reactavecchannel=mattermost. messageIdest l’identifiant de la publication Mattermost.emojiaccepte les noms commethumbsupou:+1:(les deux-points sont facultatifs).- Définissez
remove=true(booléen) pour supprimer une réaction. - Les événements d’ajout/suppression de réactions sont transférés en tant qu’événements système vers la session de l’agent acheminé.
Exemples :
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsupmessage action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=trueConfiguration :
channels.mattermost.actions.reactions: activer/désactiver les actions de réaction (par défaut true).- Remplacement par compte :
channels.mattermost.accounts.<id>.actions.reactions.
Boutons interactifs (tool de message)
Section intitulée « Boutons interactifs (tool de message) »Envoyez des messages avec des boutons cliquables. Lorsqu’un utilisateur clique sur un bouton, l’agent reçoit la sélection et peut répondre.
Les réponses normales de l’agent peuvent également inclure des charges utiles presentationOpenClawMattermost sémantiques. OpenClaw restitue les boutons de valeur sous forme de boutons interactifs Mattermost, garde les boutons d’URL visibles dans le texte du message et rétrograde les menus de sélection en texte lisible.
Activez les boutons en ajoutant inlineButtons aux fonctionnalités du channel :
{ channels: { mattermost: { capabilities: ["inlineButtons"], }, },}Utilisez message action=send avec un paramètre buttons. Les boutons sont un tableau à 2 dimensions (lignes de boutons) :
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]Champs de bouton :
Lorsqu’un utilisateur clique sur un bouton :
Boutons remplacés par une confirmation
Tous les boutons sont remplacés par une ligne de confirmation (par exemple, ”✓ Oui sélectionné par @utilisateur”).
L'agent reçoit la sélection
L’agent reçoit la sélection sous forme de message entrant et répond.
Notes de mise en œuvre
- Les rappels de boutons utilisent la vérification HMAC-SHA256 (automatique, aucune configuration requise).
- Mattermost supprime les données de rappel de ses réponses API (fonctionnalité de sécurité), donc tous les boutons sont supprimés lors du clic - une suppression partielle est impossible.
- Les ID d’action contenant des traits d’union ou des tirets bas sont nettoyés automatiquement (limitation de routage Mattermost).
Config et accessibilité
channels.mattermost.capabilities: tableau de chaînes de capacités. Ajoutez"inlineButtons"pour activer la description de l’outil de boutons dans le prompt système de l’agent.channels.mattermost.interactions.callbackBaseUrl: URL de base externe facultative pour les rappels de boutons (par exemplehttps://gateway.example.comMattermost). Utilisez-la lorsque Mattermost ne peut pas atteindre la passerelle directement à son hôte de liaison.- Dans les configurations multi-comptes, vous pouvez également définir le même champ sous `channels.mattermost.accounts.
.interactions.callbackBaseUrl. - Si interactions.callbackBaseUrlOpenClaw est omis, OpenClaw dérive l'URL de rappel à partir de gateway.customBindHost+gateway.port, puis revient à http://localhost:
Mattermost. - Règle d'accessibilité : l'URL de rappel des boutons doit être accessible depuis le serveur Mattermost. localhostMattermostOpenClawMattermost ne fonctionne que lorsque Mattermost et OpenClaw s'exécutent sur le même hôte/espace de noms réseau. - Si votre cible de rappel est privée/tailnet/interne, ajoutez son hôte/domaine à ServiceSettings.AllowedUntrustedInternalConnections` de Mattermost.
Intégration directe à l’API (scripts externes)
Section intitulée « Intégration directe à l’API (scripts externes) »Les scripts externes et les webhooks peuvent publier des boutons directement via l’API REST de Mattermost au lieu de passer par l’outil MattermostAPImessage de l’agent. Utilisez buildButtonAttachments() du plugin lorsque cela est possible ; si vous publiez du JSON brut, suivez ces règles :
Structure de la charge utile :
{ channel_id: "<channelId>", message: "Choose an option:", props: { attachments: [ { actions: [ { id: "mybutton01", // alphanumeric only - see below type: "button", // required, or clicks are silently ignored name: "Approve", // display label style: "primary", // optional: "default", "primary", "danger" integration: { url: "https://gateway.example.com/mattermost/interactions/default", context: { action_id: "mybutton01", // must match button id (for name lookup) action: "approve", // ... any custom fields ... _token: "<hmac>", // see HMAC section below }, }, }, ], }, ], },}Génération de jeton HMAC
La passerelle vérifie les clics sur les boutons avec HMAC-SHA256. Les scripts externes doivent générer des jetons qui correspondent à la logique de vérification de la passerelle :
Dériver le secret du jeton du bot
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)Construire l'objet de contexte
Construisez l’objet de contexte avec tous les champs sauf
_token.Sérialiser avec des clés triées
Sérialisez avec des clés triées et sans espaces (la passerelle utilise
JSON.stringifyavec des clés triées, ce qui produit une sortie compacte).Signer la charge utile
HMAC-SHA256(key=secret, data=serializedContext)Ajouter le jeton
Ajoutez l’empreinte hexadécimale résultante en tant que
_tokendans le contexte.
Exemple en Python :
import hmac, hashlib, json
secret = hmac.new( b"openclaw-mattermost-interactions", bot_token.encode(), hashlib.sha256).hexdigest()
ctx = {"action_id": "mybutton01", "action": "approve"}payload = json.dumps(ctx, sort_keys=True, separators=(",", ":"))token = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
context = {**ctx, "_token": token}Pièges courants liés à HMAC
- Le
json.dumpsde Python ajoute des espaces par défaut ({"key": "val"}). Utilisezseparators=(",", ":")pour correspondre à la sortie compacte de JavaScript ({"key":"val"}). - Signez toujours tous les champs de contexte (à l’exception de
_token). La passerelle supprime_tokenpuis signe tout ce qui reste. Signer un sous-ensemble entraîne un échec silencieux de la vérification. - Utilisez
sort_keys=TrueMattermost - la passerelle trie les clés avant de signer, et Mattermost peut réorganiser les champs de contexte lors du stockage de la charge utile. - Dérivez le secret du jeton du bot (déterministe), et non d’octets aléatoires. Le secret doit être identique entre le processus qui crée les boutons et la passerelle qui les vérifie.
Adaptateur de répertoire
Section intitulée « Adaptateur de répertoire »Le plugin Mattermost inclut un adaptateur de répertoire qui résout les noms de canaux et d’utilisateurs via l’API Mattermost. Cela permet d’utiliser des cibles MattermostMattermostAPI#channel-name et @username dans openclaw message send et les livraisons cron/webhook.
Aucune configuration n’est nécessaire - l’adaptateur utilise le jeton du bot à partir de la configuration du compte.
Multi-compte
Section intitulée « Multi-compte »Mattermost prend en charge plusieurs comptes sous Mattermostchannels.mattermost.accounts :
{ channels: { mattermost: { accounts: { default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" }, alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" }, }, }, },}Dépannage
Section intitulée « Dépannage »Pas de réponses dans les canaux
Assurez-vous que le bot est dans le canal et mentionnez-le (oncall), utilisez un préfixe de déclencheur (onchar), ou définissez chatmode: "onmessage".
Erreurs d'authentification ou multi-compte
- Vérifiez le jeton du bot, l’URL de base, et si le compte est activé.
- Problèmes multi-compte : les vars d’env ne s’appliquent qu’au compte
default.
Les commandes slash natives échouent
Unauthorized: invalid command token.OpenClawMattermost : OpenClaw n’a pas accepté le jeton de rappel. Causes courantes :- l’enregistrement de la commande slash a échoué ou n’a été que partiellement terminé au démarrage
- le rappel atteint la mauvaise passerelle ou le mauvais compte
- Mattermost possède encore d’anciennes commandes pointant vers une cible de rappel précédente
- la passerelle a redémarré sans réactiver les commandes slash
- Si les commandes slash natives cessent de fonctionner, vérifiez les journaux pour
mattermost: failed to register slash commandsoumattermost: native slash commands enabled but no commands could be registered. - Si
callbackUrlest omis et que les journaux avertissent que le rappel a résolu vershttp://127.0.0.1:18789/...MattermostOpenClaw, cette URL n’est probablement accessible que lorsque Mattermost s’exécute sur le même hôte ou espace de noms réseau qu’OpenClaw. Définissez plutôt uncommands.callbackUrlexplicitement accessible de l’extérieur.
Problèmes de boutons
- Les boutons apparaissent comme des cases blanches : l’agent peut envoyer des données de bouton malformées. Vérifiez que chaque bouton possède à la fois les champs
textetcallback_data. - Les boutons s’affichent mais les clics n’ont aucun effet : vérifiez que
AllowedUntrustedInternalConnectionsdans la configuration du serveur Mattermost inclut127.0.0.1 localhost, et queEnablePostActionIntegrationesttruedans ServiceSettings. - Les boutons renvoient une erreur 404 lors du clic : le
iddu bouton contient probablement des tirets ou des tirets du bas. Le routeur d’action de Mattermost ne fonctionne pas avec les ID non alphanumériques. Utilisez uniquement[a-zA-Z0-9]. - Le Gateway consigne
invalid _token: incohérence HMAC. Vérifiez que vous signez tous les champs de contexte (pas un sous-ensemble), utilisez des clés triées et du JSON compact (sans espaces). Consultez la section HMAC ci-dessus. - Le Gateway consigne
missing _token in context: le champ_tokenn’est pas dans le contexte du bouton. Assurez-vous qu’il est inclus lors de la construction de la charge utile d’intégration. - La confirmation affiche l’ID brut au lieu du nom du bouton :
context.action_idne correspond pas auiddu bouton. Définissez les deux avec la même valeur nettoyée. - L’agent ne connaît pas les boutons : ajoutez
capabilities: ["inlineButtons"]à la configuration du canal Mattermost.
Connexes
Section intitulée « Connexes »- Routage de canal - routage de session pour les messages
- Aperçu des canaux - tous les canaux pris en charge
- Groupes - comportement du chat de groupe et filtrage des mentions
- Appariement - authentification DM et flux d’appariement
- Sécurité - modèle d’accès et durcissement