Mattermost
Mattermost (plugin)
Section intitulée « Mattermost (plugin) »Statut : pris en charge via un plugin (jeton de bot + événements WebSocket). Les canaux, les groupes et les DM sont pris en charge. Mattermost est une plateforme de messagerie d’équipe auto-hébergeable ; voir le site officiel à mattermost.com pour les détails sur le produit et les téléchargements.
Plugin requis
Section intitulée « Plugin requis »Mattermost est fourni sous forme de plugin et n’est pas inclus dans l’installation principale.
Installation via CLI (registre npm) :
openclaw plugins install @openclaw/mattermostExtraction locale (lors de l’exécution depuis un dépôt git) :
openclaw plugins install ./path/to/local/mattermost-pluginSi vous choisissez Mattermost lors de la configuration et qu’une extraction git est détectée, OpenClaw proposera automatiquement le chemin d’installation local.
Détails : Plugins
Configuration rapide
Section intitulée « Configuration rapide »- Installez le plugin Mattermost.
- Créez un compte bot Mattermost et copiez le jeton de bot (bot token).
- Copiez l’URL de base de Mattermost (par ex.,
https://chat.example.com). - Configurez OpenClaw et démarrez 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 facultatives. Lorsqu’elles sont activées, OpenClaw enregistre les commandes slash oc_* via
l’API Mattermost 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", }, }, },}Notes :
native: "auto"est désactivé par défaut pour Mattermost. Définisseznative: truepour activer.- Si
callbackUrlest omis, OpenClaw en dérive un à partir de l’hôte/du port de la passerelle +callbackPath. - Pour les configurations multi-comptes,
commandspeut être défini au niveau supérieur ou souschannels.mattermost.accounts.<id>.commands(les valeurs de compte remplacent les champs de niveau supérieur). - Les rappels de commandes sont validés avec des jetons par commande et échouent en mode fermé lorsque les vérifications de jeton échouent.
- Exigence d’accessibilité : le point de terminaison de rappel doit être accessible depuis le serveur Mattermost.
- Ne définissez pas
callbackUrlsurlocalhostsauf si Mattermost s’exécute sur le même hôte/espace de noms réseau qu’OpenClaw. - Ne définissez pas
callbackUrlsur votre URL de base Mattermost sauf si cette URL fait un proxy inverse de/api/channels/mattermost/commandvers OpenClaw. - Une vérification rapide est
curl https://<gateway-host>/api/channels/mattermost/command; un GET devrait renvoyer405 Method Not Alloweddepuis OpenClaw, et non404.
- Ne définissez pas
- Exigence de liste d’autorisation de sortie Mattermost :
- Si vos cibles de rappel sont des adresses privées/tailnet internes, définissez Mattermost
ServiceSettings.AllowedUntrustedInternalConnectionspour 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
- Bon :
- Si vos cibles de rappel sont des adresses privées/tailnet internes, définissez Mattermost
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 variables d’environnement :
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Les variables d’env ne s’appliquent qu’au compte par défaut (default). Les autres comptes doivent utiliser les valeurs de configuration.
Modes de discussion
Section intitulée « Modes de discussion »Mattermost répond automatiquement aux DMs. Le comportement du canal est contrôlé par chatmode :
oncall(par défaut) : répondre uniquement lorsqu’on est @mentionné dans les canaux.onmessage: répondre à chaque message de channel.onchar: 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 de channel et de groupe restent dans le channel principal ou commencent un fil sous le message déclencheur.
off(par défaut) : répondre dans un fil uniquement lorsque le message entrant en fait déjà partie.first: pour les messages de channel/groupe de niveau supérieur, démarrer un fil sous ce message et acheminer la conversation vers une session limitée au fil.all: même comportement quefirstpour Mattermost aujourd’hui.- Les messages directs ignorent ce paramètre et restent non fils de discussion.
Exemple de configuration :
{ channels: { mattermost: { replyToMode: "all", }, },}Notes :
- Les sessions délimitées par un fil utilisent l’ID de la publication déclencheuse 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 de jumelage). - Approuver via :
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- DMs publics :
channels.mattermost.dmPolicy="open"pluschannels.mattermost.allowFrom=["*"].
Canaux (groupes)
Section intitulée « Canaux (groupes) »- Par défaut :
channels.mattermost.groupPolicy = "allowlist"(limité par mention). - Autoriser les expéditeurs avec
channels.mattermost.groupAllowFrom(IDs utilisateur recommandés). - La correspondance
@usernameest modifiable et activée uniquement lorsquechannels.mattermost.dangerouslyAllowNameMatching: true. - Canaux ouverts :
channels.mattermost.groupPolicy="open"(limité par mention). - Note d’exécution : si
channels.mattermostest complètement manquant, l’exécution revient àgroupPolicy="allowlist"pour les vérifications de groupe (même sichannels.defaults.groupPolicyest défini).
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 Mattermost API)
Les IDs opaques simples (comme 64ifufp...) sont ambigus dans Mattermost (ID utilisateur vs ID de channel).
OpenClaw les résout user-first :
- Si l’ID existe en tant qu’utilisateur (
GET /api/v4/users/<id>réussit), OpenClaw envoie un DM en résolvant le canal direct via/api/v4/channels/direct. - Sinon, l’ID est traité comme un ID de channel.
Si vous avez besoin d’un comportement déterministe, utilisez toujours les préfixes explicites (user:<id> / channel:<id>).
Nouvelle tentative de canal DM
Section intitulée « Nouvelle tentative de canal DM »Lorsque OpenClaw envoie à une cible DM Mattermost et doit résoudre le canal direct en premier, il réessaie par défaut les échecs temporaires de création de canal direct.
Utilisez channels.mattermost.dmChannelRetry pour régler 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 canaux DM (
/api/v4/channels/direct), et non à chaque appel d’API Mattermost. - Les nouvelles tentatives s’appliquent aux échecs temporaires tels que les limites de taux, 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 sont pas réessayées.
Réactions (outil de message)
Section intitulée « Réactions (outil de message) »- Utilisez
message action=reactavecchannel=mattermost. messageIdest l’ID de 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éaction 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=trueConfig :
channels.mattermost.actions.reactions: activer/désactiver les actions de réaction (par défaut true).- Redéfinition par compte :
channels.mattermost.accounts.<id>.actions.reactions.
Boutons interactifs (outil de message)
Section intitulée « Boutons interactifs (outil 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.
Activez les boutons en ajoutant inlineButtons aux fonctionnalités du canal :
{ channels: { mattermost: { capabilities: ["inlineButtons"], }, },}Utilisez message action=send avec un paramètre buttons. Les boutons sont un tableau 2D (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 :
text(requis) : libellé d’affichage.callback_data(requis) : valeur renvoyée au clic (utilisée comme ID d’action).style(facultatif) :"default","primary"ou"danger".
Lorsqu’un utilisateur clique sur un bouton :
- Tous les boutons sont remplacés par une ligne de confirmation (par exemple, ”✓ Yes sélectionné par @user”).
- L’agent reçoit la sélection en tant que message entrant et répond.
Notes :
- 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 au clic — une suppression partielle n’est pas possible.
- Les ID d’action contenant des tirets ou des traits de soulignement sont nettoyés automatiquement (limitation du routage Mattermost).
Configuration :
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.com). Utilisez ceci lorsque Mattermost ne peut pas atteindre la passerelle directement sur son hôte de liaison.- Dans les configurations multi-comptes, vous pouvez également définir le même champ sous
channels.mattermost.accounts.<id>.interactions.callbackBaseUrl. - Si
interactions.callbackBaseUrlest omis, OpenClaw déduit l’URL de rappel à partir degateway.customBindHost+gateway.port, puis revient àhttp://localhost:<port>. - Règle d’accessibilité : l’URL de rappel du bouton doit être accessible depuis le serveur Mattermost.
localhostne 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 à Mattermost
ServiceSettings.AllowedUntrustedInternalConnections.
Intégration directe API (scripts externes)
Section intitulée « Intégration directe API (scripts externes) »Les scripts externes et les webhooks peuvent poster des boutons directement via l’Mattermost REST API au lieu de passer par l’outil message de l’agent. Utilisez buildButtonAttachments() de l’extension lorsque possible ; si vous postez 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 }, }, }, ], }, ], },}Règles critiques :
- Les pièces jointes vont dans
props.attachments, et non au niveau supérieurattachments(ignoré silencieusement). - Chaque action a besoin de
type: "button"— sans cela, les clics sont ignorés silencieusement. - Chaque action a besoin d’un champ
id— Mattermost ignore les actions sans ID. - L’action
iddoit être uniquement alphanumérique ([a-zA-Z0-9]). Les tirets et les underscores cassent le routage des actions côté serveur de Mattermost (renvoie 404). Supprimez-les avant utilisation. context.action_iddoit correspondre auiddu bouton pour que le message de confirmation affiche le nom du bouton (ex : “Approuver”) au lieu d’un identifiant brut.context.action_idest requis — le gestionnaire d’interactions renvoie 400 sans lui.
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érivez le secret du jeton du bot :
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken) - Construisez l’objet de contexte avec tous les champs sauf
_token. - Sérialisez avec clés triées et sans espaces (la passerelle utilise
JSON.stringifyavec des clés triées, ce qui produit une sortie compacte). - Signez :
HMAC-SHA256(key=secret, data=serializedContext) - Ajoutez l’empreinte hexadécimale résultante en tant que
_tokendans le contexte.
Exemple 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 (moins
_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=True— 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 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 les cibles #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 channels.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 salons : assurez-vous que le bot est dans le salon et mentionnez-le (oncall), utilisez un préfixe de déclenchement (onchar), ou définissez
chatmode: "onmessage". - Erreurs d’authentification : vérifiez le jeton du bot, l’URL de base, et si le compte est activé.
- Problèmes multi-comptes : les env vars ne s’appliquent qu’au compte
default. - 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 ne font rien : vérifiez que
AllowedUntrustedInternalConnectionsdans la configuration du serveur Mattermost inclut127.0.0.1 localhost, et queEnablePostActionIntegrationesttruedans ServiceSettings. - Les boutons renvoient une erreur 404 au clic : le
iddu bouton contient probablement des traits d’union ou des tirets du bas. Le routeur d’action de Mattermost échoue avec les ID non alphanumériques. Utilisez uniquement[a-zA-Z0-9]. - Le Gateway journalise
invalid _token: inadéquation HMAC. Vérifiez que vous signez tous les champs de contexte (pas un sous-ensemble), utilisez des clés triées, et utilisez JSON compact (sans espaces). Voir la section HMAC ci-dessus. - Le Gateway journalise
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 »- Vue d’ensemble des canaux — tous les canaux pris en charge
- Appariement — authentification DM et flux d’appariement
- Groupes — comportement de la conversation de groupe et filtrage des mentions
- Routage de canal — routage de session pour les messages
- Sécurité — modèle d’accès et durcissement