Mattermost (plugin)
Status: ondersteund via plugin (bottoken + WebSocket-events). Kanalen, groepen en DM’s worden ondersteund. Mattermost is een zelf te hosten teamberichtenplatform; zie de officiële site op mattermost.com voor productdetails en downloads.
Plugin vereist
Mattermost wordt als plugin geleverd en is niet gebundeld met de kerninstallatie.
Installeren via CLI (npm-register):
openclaw plugins install @openclaw/mattermost
Lokale checkout (vanuit een git-repo):
openclaw plugins install ./extensions/mattermost
Als je Mattermost kiest tijdens configureren/onboarding en een git-checkout wordt gedetecteerd, biedt OpenClaw automatisch het lokale installatiepad aan.
Details: Plugins
Snelle installatie
- Installeer de Mattermost-plugin.
- Maak een Mattermost-botaccount aan en kopieer het bottoken.
- Kopieer de Mattermost basis-URL (bijv.
https://chat.example.com). - Configureer OpenClaw en start de gateway.
Minimale configuratie:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
Native slash-commando’s
Native slash-commando’s zijn opt-in. Wanneer ingeschakeld, registreert OpenClaw oc_* slash-commando’s via de Mattermost-API en ontvangt callback-POST’s op de gateway HTTP-server.
{
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",
},
},
},
}
Opmerkingen:
native: "auto"staat standaard uitgeschakeld voor Mattermost. Stelnative: truein om in te schakelen.- Als
callbackUrlwordt weggelaten, leidt OpenClaw er een af van gatewayhost/poort +callbackPath. - Voor multi-account-opstellingen kan
commandsop het hoogste niveau of onderchannels.mattermost.accounts.<id>.commandsworden ingesteld (accountwaarden overschrijven velden op het hoogste niveau). - Command-callbacks worden gevalideerd met per-commando-tokens en falen gesloten wanneer tokencontroles mislukken.
- Bereikbaarheidsvereiste: het callback-eindpunt moet bereikbaar zijn vanuit de Mattermost-server.
- Stel
callbackUrlniet in oplocalhosttenzij Mattermost op dezelfde host/netwerknamespace draait als OpenClaw. - Stel
callbackUrlniet in op je Mattermost basis-URL tenzij die URL/api/channels/mattermost/commandreverse-proxyt naar OpenClaw. - Een snelle controle is
curl https://<gateway-host>/api/channels/mattermost/command; een GET zou405 Method Not Allowedvan OpenClaw moeten retourneren, niet404.
- Stel
- Mattermost egress-allowlist-vereiste:
- Als je callback gericht is op privé-/tailnet-/interne adressen, stel dan Mattermost
ServiceSettings.AllowedUntrustedInternalConnectionsin om de callback-host/domein op te nemen. - Gebruik host-/domeinvermeldingen, geen volledige URL’s.
- Goed:
gateway.tailnet-name.ts.net - Fout:
https://gateway.tailnet-name.ts.net
- Goed:
- Als je callback gericht is op privé-/tailnet-/interne adressen, stel dan Mattermost
Omgevingsvariabelen (standaardaccount)
Stel deze in op de gatewayhost als je de voorkeur geeft aan omgevingsvariabelen:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Omgevingsvariabelen gelden alleen voor het standaardaccount (default). Andere accounts moeten configwaarden gebruiken.
Chatmodi
Mattermost reageert automatisch op DM’s. Kanaalgedrag wordt bepaald door chatmode:
oncall(standaard): reageer alleen wanneer @vermeld in kanalen.onmessage: reageer op elk kanaalbericht.onchar: reageer wanneer een bericht begint met een triggerprefix.
Configuratievoorbeeld:
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
Opmerkingen:
oncharreageert nog steeds op expliciete @-vermeldingen.channels.mattermost.requireMentionwordt gehonoreerd voor legacy-configs maarchatmodeheeft de voorkeur.
Threading en sessies
Gebruik channels.mattermost.replyToMode om te bepalen of kanaal- en groepsantwoorden in het hoofdkanaal blijven of een thread starten onder de triggerpost.
off(standaard): antwoord alleen in een thread wanneer de inkomende post al in een thread staat.first: voor posts op het hoogste niveau in kanalen/groepen, start een thread onder die post en routeer het gesprek naar een thread-scoped sessie.all: zelfde gedrag alsfirstvoor Mattermost op dit moment.- Directe berichten negeren deze instelling en blijven zonder thread.
Configuratievoorbeeld:
{
channels: {
mattermost: {
replyToMode: "all",
},
},
}
Opmerkingen:
- Thread-scoped sessies gebruiken het triggerpost-ID als thread-root.
firstenallzijn momenteel equivalent omdat zodra Mattermost een thread-root heeft, vervolgchunks en media in dezelfde thread doorgaan.
Toegangscontrole (DM’s)
- Standaard:
channels.mattermost.dmPolicy = "pairing"(onbekende afzenders krijgen een koppelingscode). - Goedkeuren via:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- Openbare DM’s:
channels.mattermost.dmPolicy="open"pluschannels.mattermost.allowFrom=["*"].
Kanalen (groepen)
- Standaard:
channels.mattermost.groupPolicy = "allowlist"(mention-gated). - Sta afzenders toe met
channels.mattermost.groupAllowFrom(gebruikers-ID’s aanbevolen). @username-matching is veranderlijk en wordt alleen ingeschakeld wanneerchannels.mattermost.dangerouslyAllowNameMatching: true.- Open kanalen:
channels.mattermost.groupPolicy="open"(mention-gated). - Runtime-opmerking: als
channels.mattermostvolledig ontbreekt, valt de runtime terug opgroupPolicy="allowlist"voor groepscontroles (zelfs alschannels.defaults.groupPolicyis ingesteld).
Doelen voor uitgaande aflevering
Gebruik deze doelformaten met openclaw message send of cron/webhooks:
channel:<id>voor een kanaaluser:<id>voor een DM@usernamevoor een DM (opgelost via de Mattermost-API)
Kale ondoorzichtige ID’s (zoals 64ifufp...) zijn ambigu in Mattermost (gebruikers-ID vs. kanaal-ID).
OpenClaw lost ze gebruiker-eerst op:
- Als het ID bestaat als gebruiker (
GET /api/v4/users/<id>slaagt), stuurt OpenClaw een DM door het directe kanaal op te lossen via/api/v4/channels/direct. - Anders wordt het ID behandeld als een kanaal-ID.
Als je deterministisch gedrag nodig hebt, gebruik dan altijd de expliciete prefixen (user:<id> / channel:<id>).
Reacties (berichttool)
- Gebruik
message action=reactmetchannel=mattermost. messageIdis het Mattermost post-ID.emojiaccepteert namen zoalsthumbsupof:+1:(dubbele punten zijn optioneel).- Stel
remove=true(boolean) in om een reactie te verwijderen. - Reactie toevoegen/verwijderen-events worden doorgestuurd als systeemevents naar de gerouteerde agentsessie.
Voorbeelden:
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true
Configuratie:
channels.mattermost.actions.reactions: reactieacties in-/uitschakelen (standaard true).- Per-account-overschrijving:
channels.mattermost.accounts.<id>.actions.reactions.
Interactieve knoppen (berichttool)
Stuur berichten met klikbare knoppen. Wanneer een gebruiker op een knop klikt, ontvangt de agent de selectie en kan reageren.
Schakel knoppen in door inlineButtons toe te voegen aan de kanaalmogelijkheden:
{
channels: {
mattermost: {
capabilities: ["inlineButtons"],
},
},
}
Gebruik message action=send met een buttons-parameter. Knoppen zijn een 2D-array (rijen van knoppen):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
Knopvelden:
text(vereist): weergavelabel.callback_data(vereist): waarde die teruggestuurd wordt bij klik (gebruikt als actie-ID).style(optioneel):"default","primary"of"danger".
Wanneer een gebruiker op een knop klikt:
- Alle knoppen worden vervangen door een bevestigingsregel (bijv. “Ja geselecteerd door @user”).
- De agent ontvangt de selectie als inkomend bericht en reageert.
Opmerkingen:
- Knopcallbacks gebruiken HMAC-SHA256-verificatie (automatisch, geen configuratie nodig).
- Mattermost verwijdert callback-data uit zijn API-antwoorden (beveiligingsfunctie), dus alle knoppen worden verwijderd bij klik — gedeeltelijke verwijdering is niet mogelijk.
- Actie-ID’s met koppeltekens of underscores worden automatisch opgeschoond (Mattermost routeringslimitatie).
Configuratie:
channels.mattermost.capabilities: array van mogelijkheidsstrings. Voeg"inlineButtons"toe om de knoppentoolbeschrijving in de agent-systeemprompt in te schakelen.channels.mattermost.interactions.callbackBaseUrl: optionele externe basis-URL voor knopcallbacks (bijv.https://gateway.example.com). Gebruik dit wanneer Mattermost de gateway niet direct kan bereiken op zijn bindhost.- In multi-account-opstellingen kun je hetzelfde veld ook instellen onder
channels.mattermost.accounts.<id>.interactions.callbackBaseUrl. - Als
interactions.callbackBaseUrlwordt weggelaten, leidt OpenClaw de callback-URL af vangateway.customBindHost+gateway.port, en valt terug ophttp://localhost:<port>. - Bereikbaarheidsregel: de knopcallback-URL moet bereikbaar zijn vanuit de Mattermost-server.
localhostwerkt alleen wanneer Mattermost en OpenClaw op dezelfde host/netwerknamespace draaien. - Als je callbackdoel privé/tailnet/intern is, voeg dan de host/het domein toe aan Mattermost
ServiceSettings.AllowedUntrustedInternalConnections.
Directe API-integratie (externe scripts)
Externe scripts en webhooks kunnen knoppen rechtstreeks via de Mattermost REST API posten in plaats van via de message-tool van de agent. Gebruik waar mogelijk buildButtonAttachments() uit de extensie; als je ruwe JSON post, volg dan deze regels:
Payloadstructuur:
{
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
},
},
},
],
},
],
},
}
Kritische regels:
- Bijlagen gaan in
props.attachments, niet op het hoogste niveauattachments(stilzwijgend genegeerd). - Elke actie heeft
type: "button"nodig — zonder dit worden klikken stilzwijgend genegeerd. - Elke actie heeft een
id-veld nodig — Mattermost negeert acties zonder ID’s. - Actie-
idmoet alleen alfanumeriek zijn ([a-zA-Z0-9]). Koppeltekens en underscores breken de serverside actieroutering van Mattermost (retourneert 404). Verwijder ze voor gebruik. context.action_idmoet overeenkomen met hetidvan de knop zodat het bevestigingsbericht de knopnaam toont (bijv. “Approve”) in plaats van een rauw ID.context.action_idis vereist — de interactie-handler retourneert 400 zonder dit.
HMAC-tokengeneratie:
De gateway verifieert knopklikken met HMAC-SHA256. Externe scripts moeten tokens genereren die overeenkomen met de verificatielogica van de gateway:
- Leid het geheim af van het bottoken:
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken) - Bouw het contextobject met alle velden behalve
_token. - Serialiseer met gesorteerde sleutels en geen spaties (de gateway gebruikt
JSON.stringifymet gesorteerde sleutels, wat compacte uitvoer produceert). - Onderteken:
HMAC-SHA256(key=secret, data=serializedContext) - Voeg de resulterende hex-digest toe als
_tokenin de context.
Python-voorbeeld:
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}
Veelvoorkomende HMAC-valkuilen:
- Python’s
json.dumpsvoegt standaard spaties toe ({"key": "val"}). Gebruikseparators=(",", ":")om overeen te komen met JavaScript’s compacte uitvoer ({"key":"val"}). - Onderteken altijd alle contextvelden (minus
_token). De gateway verwijdert_tokenen ondertekent vervolgens al het resterende. Het ondertekenen van een subset veroorzaakt stille verificatiefout. - Gebruik
sort_keys=True— de gateway sorteert sleutels voor het ondertekenen, en Mattermost kan contextvelden herschikken bij het opslaan van de payload. - Leid het geheim af van het bottoken (deterministisch), niet van willekeurige bytes. Het geheim moet hetzelfde zijn in het proces dat knoppen maakt en de gateway die verifieert.
Directory-adapter
De Mattermost-plugin bevat een directory-adapter die kanaal- en gebruikersnamen oplost via de Mattermost-API. Dit maakt #channel-name en @username doelen mogelijk in openclaw message send en cron/webhook-afleveringen.
Er is geen configuratie nodig — de adapter gebruikt het bottoken uit de accountconfiguratie.
Multi-account
Mattermost ondersteunt meerdere accounts onder 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" },
},
},
},
}
Probleemoplossing
- Geen antwoorden in kanalen: zorg ervoor dat de bot in het kanaal zit en vermeld hem (oncall), gebruik een triggerprefix (onchar), of stel
chatmode: "onmessage"in. - Authenticatiefouten: controleer het bottoken, de basis-URL en of het account is ingeschakeld.
- Multi-accountproblemen: omgevingsvariabelen gelden alleen voor het
default-account. - Knoppen verschijnen als witte vakken: de agent stuurt mogelijk misvormde knopdata. Controleer of elke knop zowel
textalscallback_datavelden heeft. - Knoppen renderen maar klikken doen niets: verifieer dat
AllowedUntrustedInternalConnectionsin de Mattermost-serverconfiguratie127.0.0.1 localhostbevat, en datEnablePostActionIntegrationtrueis in ServiceSettings. - Knoppen retourneren 404 bij klik: het knop-
idbevat waarschijnlijk koppeltekens of underscores. De actieroutering van Mattermost breekt op niet-alfanumerieke ID’s. Gebruik alleen[a-zA-Z0-9]. - Gateway logt
invalid _token: HMAC-mismatch. Controleer of je alle contextvelden ondertekent (niet een subset), gesorteerde sleutels gebruikt en compacte JSON (geen spaties). Zie het HMAC-gedeelte hierboven. - Gateway logt
missing _token in context: het_token-veld staat niet in de context van de knop. Zorg ervoor dat het wordt opgenomen bij het bouwen van de integratie-payload. - Bevestiging toont rauw ID in plaats van knopnaam:
context.action_idkomt niet overeen met hetidvan de knop. Stel beide in op dezelfde opgeschoonde waarde. - Agent weet niets over knoppen: voeg
capabilities: ["inlineButtons"]toe aan de Mattermost-kanaalconfiguratie.