Mattermost (Plugin)
Status: Unterstützt via Plugin (Bot-Token + WebSocket-Events). Kanäle, Gruppen und DMs werden unterstützt. Mattermost ist eine selbst-hostbare Team-Messaging-Plattform; Produktdetails und Downloads findest du auf der offiziellen Seite unter mattermost.com.
Plugin erforderlich
Mattermost wird als Plugin ausgeliefert und ist nicht in der Kerninstallation enthalten.
Installation über CLI (npm-Registry):
openclaw plugins install @openclaw/mattermost
Lokaler Checkout (wenn aus einem Git-Repo ausgeführt):
openclaw plugins install ./extensions/mattermost
Wenn du Mattermost während der Konfiguration/des Onboardings auswählst und ein Git-Checkout erkannt wird, bietet OpenClaw automatisch den lokalen Installationspfad an.
Details: Plugins
Schnelleinrichtung
- Installiere das Mattermost-Plugin.
- Erstelle ein Mattermost-Bot-Konto und kopiere den Bot-Token.
- Kopiere die Mattermost-Basis-URL (z. B.
https://chat.example.com). - Konfiguriere OpenClaw und starte das Gateway.
Minimale Konfiguration:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
Native Slash-Befehle
Native Slash-Befehle sind Opt-in. Wenn aktiviert, registriert OpenClaw oc_*-Slash-Befehle über die Mattermost-API und empfängt Callback-POSTs auf dem Gateway-HTTP-Server.
{
channels: {
mattermost: {
commands: {
native: true,
nativeSkills: true,
callbackPath: "/api/channels/mattermost/command",
// Verwende wenn Mattermost das Gateway nicht direkt erreichen kann (Reverse Proxy/öffentliche URL).
callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
},
},
},
}
Hinweise:
native: "auto"ist für Mattermost standardmäßig deaktiviert. Setzenative: truezum Aktivieren.- Wenn
callbackUrlweggelassen wird, leitet OpenClaw eine aus Gateway-Host/Port +callbackPathab. - Für Multi-Account-Setups kann
commandsauf Top-Level oder unterchannels.mattermost.accounts.<id>.commandsgesetzt werden (Kontowerte überschreiben Top-Level-Felder). - Befehls-Callbacks werden mit Pro-Befehls-Tokens validiert und schlagen bei fehlender Token-Prüfung geschlossen fehl.
- Erreichbarkeitsanforderung: Der Callback-Endpunkt muss vom Mattermost-Server erreichbar sein.
- Setze
callbackUrlnicht auflocalhost, es sei denn, Mattermost läuft auf demselben Host/Netzwerk-Namespace wie OpenClaw. - Setze
callbackUrlnicht auf deine Mattermost-Basis-URL, es sei denn, diese URL leitet/api/channels/mattermost/commandper Reverse Proxy an OpenClaw weiter. - Ein schneller Test ist
curl https://<gateway-host>/api/channels/mattermost/command; ein GET sollte405 Method Not Allowedvon OpenClaw zurückgeben, nicht404.
- Setze
- Mattermost-Egress-Allowlist-Anforderung:
- Wenn dein Callback private/Tailnet-/interne Adressen anspricht, setze Mattermosts
ServiceSettings.AllowedUntrustedInternalConnectionsauf den Callback-Host/die Domain. - Verwende Host-/Domain-Einträge, keine vollständigen URLs.
- Richtig:
gateway.tailnet-name.ts.net - Falsch:
https://gateway.tailnet-name.ts.net
- Richtig:
- Wenn dein Callback private/Tailnet-/interne Adressen anspricht, setze Mattermosts
Umgebungsvariablen (Standardkonto)
Setze diese auf dem Gateway-Host, wenn du Umgebungsvariablen bevorzugst:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Umgebungsvariablen gelten nur für das Standard-Konto (default). Andere Konten müssen Konfigurationswerte verwenden.
Chat-Modi
Mattermost antwortet auf DMs automatisch. Das Kanalverhalten wird durch chatmode gesteuert:
oncall(Standard): Nur bei @Mention in Kanälen antworten.onmessage: Auf jede Kanalnachricht antworten.onchar: Antworten, wenn eine Nachricht mit einem Trigger-Präfix beginnt.
Konfigurationsbeispiel:
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
Hinweise:
oncharantwortet weiterhin auf explizite @Mentions.channels.mattermost.requireMentionwird für Legacy-Konfigurationen berücksichtigt, aberchatmodeist bevorzugt.
Threading und Sessions
Verwende channels.mattermost.replyToMode, um zu steuern, ob Kanal- und Gruppenantworten im Hauptkanal bleiben oder einen Thread unter dem auslösenden Beitrag starten.
off(Standard): Nur in einem Thread antworten, wenn der eingehende Beitrag bereits in einem ist.first: Für Top-Level-Kanal-/Gruppenbeiträge einen Thread unter diesem Beitrag starten und die Konversation in eine Thread-bezogene Session leiten.all: Gleiches Verhalten wiefirstfür Mattermost derzeit.- Direktnachrichten ignorieren diese Einstellung und bleiben ohne Thread.
Konfigurationsbeispiel:
{
channels: {
mattermost: {
replyToMode: "all",
},
},
}
Hinweise:
- Thread-bezogene Sessions verwenden die auslösende Beitrags-ID als Thread-Root.
firstundallsind derzeit gleichwertig, da Mattermost nach einem Thread-Root Folge-Chunks und Medien im selben Thread fortsetzt.
Zugriffssteuerung (DMs)
- Standard:
channels.mattermost.dmPolicy = "pairing"(unbekannte Absender erhalten einen Pairing-Code). - Genehmigung über:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- Öffentliche DMs:
channels.mattermost.dmPolicy="open"pluschannels.mattermost.allowFrom=["*"].
Kanäle (Gruppen)
- Standard:
channels.mattermost.groupPolicy = "allowlist"(Mention-gated). - Absender auf die Allowlist setzen mit
channels.mattermost.groupAllowFrom(Benutzer-IDs empfohlen). @username-Matching ist veränderlich und nur aktiviert, wennchannels.mattermost.dangerouslyAllowNameMatching: true.- Offene Kanäle:
channels.mattermost.groupPolicy="open"(Mention-gated). - Laufzeithinweis: Wenn
channels.mattermostvollständig fehlt, fällt die Laufzeit für Gruppenprüfungen aufgroupPolicy="allowlist"zurück (auch wennchannels.defaults.groupPolicygesetzt ist).
Ziele für ausgehende Zustellung
Verwende diese Zielformate mit openclaw message send oder Cron/Webhooks:
channel:<id>für einen Kanaluser:<id>für eine DM@usernamefür eine DM (über die Mattermost-API aufgelöst)
Nackte opake IDs (wie 64ifufp...) sind in Mattermost mehrdeutig (Benutzer-ID vs. Kanal-ID).
OpenClaw löst sie Benutzer-zuerst auf:
- Wenn die ID als Benutzer existiert (
GET /api/v4/users/<id>erfolgreich), sendet OpenClaw eine DM durch Auflösen des direkten Kanals via/api/v4/channels/direct. - Andernfalls wird die ID als Kanal-ID behandelt.
Wenn du deterministisches Verhalten brauchst, verwende immer die expliziten Präfixe (user:<id> / channel:<id>).
Reaktionen (Nachrichten-Tool)
- Verwende
message action=reactmitchannel=mattermost. messageIdist die Mattermost-Beitrags-ID.emojiakzeptiert Namen wiethumbsupoder:+1:(Doppelpunkte optional).- Setze
remove=true(Boolean), um eine Reaktion zu entfernen. - Reaktions-Hinzufüge-/Entferne-Events werden als Systemereignisse an die geroutete Agent-Session weitergeleitet.
Beispiele:
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
Konfiguration:
channels.mattermost.actions.reactions: Reaktionsaktionen aktivieren/deaktivieren (Standard true).- Pro-Konto-Überschreibung:
channels.mattermost.accounts.<id>.actions.reactions.
Interaktive Buttons (Nachrichten-Tool)
Sende Nachrichten mit klickbaren Buttons. Wenn ein Benutzer auf einen Button klickt, erhält der Agent die Auswahl und kann antworten.
Aktiviere Buttons, indem du inlineButtons zu den Kanal-Capabilities hinzufügst:
{
channels: {
mattermost: {
capabilities: ["inlineButtons"],
},
},
}
Verwende message action=send mit einem buttons-Parameter. Buttons sind ein 2D-Array (Zeilen von Buttons):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
Button-Felder:
text(erforderlich): Anzeigetext.callback_data(erforderlich): Wert, der bei Klick zurückgesendet wird (als Aktions-ID verwendet).style(optional):"default","primary"oder"danger".
Wenn ein Benutzer auf einen Button klickt:
- Alle Buttons werden durch eine Bestätigungszeile ersetzt (z. B. “Yes selected by @user”).
- Der Agent erhält die Auswahl als eingehende Nachricht und antwortet.
Hinweise:
- Button-Callbacks verwenden HMAC-SHA256-Verifizierung (automatisch, keine Konfiguration nötig).
- Mattermost entfernt Callback-Daten aus seinen API-Antworten (Sicherheitsfeature), sodass alle Buttons bei Klick entfernt werden — teilweises Entfernen ist nicht möglich.
- Aktions-IDs mit Bindestrichen oder Unterstrichen werden automatisch bereinigt (Mattermost-Routing-Einschränkung).
Konfiguration:
channels.mattermost.capabilities: Array von Capability-Strings. Füge"inlineButtons"hinzu, um die Button-Tool-Beschreibung im Agent-Systemprompt zu aktivieren.channels.mattermost.interactions.callbackBaseUrl: Optionale externe Basis-URL für Button-Callbacks (z. B.https://gateway.example.com). Verwende dies, wenn Mattermost das Gateway nicht direkt am Bind-Host erreichen kann.- In Multi-Account-Setups kannst du dasselbe Feld unter
channels.mattermost.accounts.<id>.interactions.callbackBaseUrlsetzen. - Wenn
interactions.callbackBaseUrlweggelassen wird, leitet OpenClaw die Callback-URL ausgateway.customBindHost+gateway.portab, Fallback aufhttp://localhost:<port>. - Erreichbarkeitsregel: Die Button-Callback-URL muss vom Mattermost-Server erreichbar sein.
localhostfunktioniert nur, wenn Mattermost und OpenClaw auf demselben Host/Netzwerk-Namespace laufen. - Wenn dein Callback-Ziel privat/Tailnet/intern ist, füge dessen Host/Domain zu Mattermosts
ServiceSettings.AllowedUntrustedInternalConnectionshinzu.
Direkte API-Integration (externe Skripte)
Externe Skripte und Webhooks können Buttons direkt über die Mattermost REST API posten, anstatt durch das message-Tool des Agenten zu gehen. Verwende buildButtonAttachments() aus der Extension wenn möglich; beim Posten von rohem JSON beachte diese Regeln:
Payload-Struktur:
{
channel_id: "<channelId>",
message: "Choose an option:",
props: {
attachments: [
{
actions: [
{
id: "mybutton01", // nur alphanumerisch — siehe unten
type: "button", // erforderlich, sonst werden Klicks stillschweigend ignoriert
name: "Approve", // Anzeigetext
style: "primary", // optional: "default", "primary", "danger"
integration: {
url: "https://gateway.example.com/mattermost/interactions/default",
context: {
action_id: "mybutton01", // muss mit Button-ID übereinstimmen (für Namenssuche)
action: "approve",
// ... benutzerdefinierte Felder ...
_token: "<hmac>", // siehe HMAC-Abschnitt unten
},
},
},
],
},
],
},
}
Kritische Regeln:
- Attachments gehören in
props.attachments, nicht in Top-Level-attachments(wird stillschweigend ignoriert). - Jede Aktion braucht
type: "button"— ohne werden Klicks stillschweigend verschluckt. - Jede Aktion braucht ein
id-Feld — Mattermost ignoriert Aktionen ohne IDs. - Aktions-
idmuss nur alphanumerisch sein ([a-zA-Z0-9]). Bindestriche und Unterstriche brechen Mattermosts serverseitiges Action-Routing (gibt 404 zurück). Vor Verwendung entfernen. context.action_idmuss mit deriddes Buttons übereinstimmen, damit die Bestätigungsnachricht den Button-Namen (z. B. „Approve”) anstelle einer rohen ID zeigt.context.action_idist erforderlich — der Interaction-Handler gibt 400 ohne zurück.
HMAC-Token-Generierung:
Das Gateway verifiziert Button-Klicks mit HMAC-SHA256. Externe Skripte müssen Tokens generieren, die der Verifizierungslogik des Gateways entsprechen:
- Leite das Secret vom Bot-Token ab:
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken) - Baue das Context-Objekt mit allen Feldern außer
_token. - Serialisiere mit sortierten Schlüsseln und ohne Leerzeichen (das Gateway verwendet
JSON.stringifymit sortierten Schlüsseln, was kompakte Ausgabe erzeugt). - Signiere:
HMAC-SHA256(key=secret, data=serializedContext) - Füge den resultierenden Hex-Digest als
_tokenim Kontext hinzu.
Python-Beispiel:
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}
Häufige HMAC-Fallstricke:
- Pythons
json.dumpsfügt standardmäßig Leerzeichen hinzu ({"key": "val"}). Verwendeseparators=(",", ":"), um JavaScripts kompakte Ausgabe ({"key":"val"}) zu matchen. - Signiere immer alle Kontextfelder (minus
_token). Das Gateway entfernt_tokenund signiert dann alles Verbleibende. Das Signieren einer Teilmenge verursacht stillschweigendes Verifizierungsfehlen. - Verwende
sort_keys=True— das Gateway sortiert Schlüssel vor dem Signieren, und Mattermost kann Kontextfelder beim Speichern des Payloads umsortieren. - Leite das Secret vom Bot-Token ab (deterministisch), nicht von zufälligen Bytes. Das Secret muss im Prozess, der Buttons erstellt, und im Gateway, das verifiziert, identisch sein.
Verzeichnisadapter
Das Mattermost-Plugin enthält einen Verzeichnisadapter, der Kanal- und Benutzernamen über die Mattermost-API auflöst. Dies ermöglicht #channel-name- und @username-Ziele in openclaw message send und Cron-/Webhook-Zustellungen.
Keine Konfiguration erforderlich — der Adapter verwendet den Bot-Token aus der Kontokonfiguration.
Multi-Account
Mattermost unterstützt mehrere Konten unter 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" },
},
},
},
}
Fehlerbehebung
- Keine Antworten in Kanälen: Stelle sicher, dass der Bot im Kanal ist und ihn erwähnt (oncall), verwende ein Trigger-Präfix (onchar) oder setze
chatmode: "onmessage". - Auth-Fehler: Bot-Token, Basis-URL und ob das Konto aktiviert ist, prüfen.
- Multi-Account-Probleme: Umgebungsvariablen gelten nur für das
default-Konto. - Buttons erscheinen als weiße Kästchen: Der Agent sendet möglicherweise fehlerhafte Button-Daten. Prüfe, ob jeder Button sowohl
text- als auchcallback_data-Felder hat. - Buttons werden gerendert, aber Klicks bewirken nichts: Prüfe
AllowedUntrustedInternalConnectionsin der Mattermost-Serverkonfiguration auf127.0.0.1 localhost, und dassEnablePostActionIntegrationin ServiceSettingstrueist. - Buttons geben 404 bei Klick zurück: Die Button-
identhält wahrscheinlich Bindestriche oder Unterstriche. Mattermosts Action-Router bricht bei nicht-alphanumerischen IDs. Verwende nur[a-zA-Z0-9]. - Gateway protokolliert
invalid _token: HMAC-Mismatch. Prüfe, ob du alle Kontextfelder (nicht nur eine Teilmenge) signierst, sortierte Schlüssel verwendest und kompaktes JSON (ohne Leerzeichen). Siehe den HMAC-Abschnitt oben. - Gateway protokolliert
missing _token in context: Das_token-Feld fehlt im Kontext des Buttons. Stelle sicher, dass es beim Erstellen des Integration-Payloads enthalten ist. - Bestätigung zeigt rohe ID statt Button-Name:
context.action_idstimmt nicht mit deriddes Buttons überein. Setze beide auf denselben bereinigten Wert. - Agent kennt Buttons nicht: Füge
capabilities: ["inlineButtons"]zur Mattermost-Kanalkonfiguration hinzu.