Developer and self-hosted
Mattermost
Status: herunterladbares Plugin (Bot-Token + WebSocket-Ereignisse). Kanäle, private Kanäle, Gruppen-DMs und DMs werden unterstützt. Mattermost ist eine selbst hostbare Team-Messaging-Plattform (mattermost.com).
Installation
npm-Registry
openclaw plugins install @openclaw/mattermostLokaler Checkout
openclaw plugins install ./path/to/local/mattermost-pluginDetails: Plugins
Schnelleinrichtung
Verfügbarkeit des Plugins sicherstellen
Installieren Sie @openclaw/mattermost mit dem obigen Befehl und starten Sie anschließend den Gateway neu, falls er bereits ausgeführt wird.
Mattermost-Bot erstellen
Erstellen Sie ein Mattermost-Bot-Konto, kopieren Sie das Bot-Token und fügen Sie den Bot den Teams und Kanälen hinzu, die er lesen soll.
Basis-URL kopieren
Kopieren Sie die Mattermost-Basis-URL (z. B. https://chat.example.com). Ein nachgestelltes /api/v4 wird automatisch entfernt.
OpenClaw konfigurieren und Gateway starten
Minimalkonfiguration:
{ channels: { mattermost: { enabled: true, botToken: "mm-token", baseUrl: "https://chat.example.com", dmPolicy: "pairing", }, },}Nicht interaktive Alternative:
openclaw channels add --channel mattermost --bot-token <token> --http-url https://chat.example.comNative Slash-Befehle
Native Slash-Befehle müssen explizit aktiviert werden. Wenn sie aktiviert sind, registriert OpenClaw oc_* Slash-Befehle in jedem Team, dem der Bot angehört, und empfängt Callback-POST-Anfragen auf dem HTTP-Server des Gateways.
{ channels: { mattermost: { commands: { native: true, nativeSkills: true, callbackPath: "/api/channels/mattermost/command", // Verwenden, wenn Mattermost den Gateway nicht direkt erreichen kann (Reverse-Proxy/öffentliche URL). callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, }, },}Registrierte Befehle: /oc_status, /oc_model, /oc_models, /oc_new, /oc_help, /oc_think, /oc_reasoning, /oc_verbose, /oc_queue. Mit nativeSkills: true werden Skill-Befehle ebenfalls als /oc_<skill> registriert.
Hinweise zum Verhalten
nativeundnativeSkillsverwenden standardmäßig"auto", was für Mattermost als deaktiviert aufgelöst wird. Setzen Sie sie ausdrücklich auftrue.callbackPathverwendet standardmäßig/api/channels/mattermost/command.- Wenn
callbackUrlweggelassen wird, leitet OpenClawhttp://<gateway.customBindHost or localhost>:<gateway.port, default 18789><callbackPath>ab. Bei Platzhalter-Bind-Hosts (0.0.0.0,::) wird auflocalhostzurückgegriffen. - Bei Konfigurationen mit mehreren Konten kann
commandsauf der obersten Ebene oder unterchannels.mattermost.accounts.<id>.commandsfestgelegt werden (Kontowerte überschreiben Felder der obersten Ebene). - Vorhandene Slash-Befehle mit demselben Auslöser, die von anderen Integrationen erstellt wurden, bleiben unverändert (sie werden bei der Registrierung übersprungen); vom Bot erstellte Befehle werden aktualisiert oder neu erstellt, wenn sich die Callback-URL geändert hat.
- Befehls-Callbacks werden anhand der befehlsspezifischen Token validiert, die Mattermost zurückgibt, wenn OpenClaw
oc_*Befehle registriert. - OpenClaw aktualisiert die aktuelle Mattermost-Befehlsregistrierung, bevor jeder Callback akzeptiert wird. Dadurch werden veraltete Token gelöschter oder neu generierter Slash-Befehle ohne Neustart des Gateways nicht mehr akzeptiert.
- Die Callback-Validierung schlägt sicher fehl, wenn die Mattermost-API nicht bestätigen kann, dass der Befehl noch aktuell ist; fehlgeschlagene Validierungen werden kurzzeitig zwischengespeichert, gleichzeitige Abfragen werden zusammengeführt und der Start neuer Abfragen wird pro Befehl ratenbegrenzt, um die Belastung durch Wiederholungsangriffe zu begrenzen.
- Slash-Callbacks schlagen sicher fehl, wenn die Registrierung fehlgeschlagen ist, der Start nur teilweise abgeschlossen wurde oder das Callback-Token nicht mit dem registrierten Token des aufgelösten Befehls übereinstimmt (ein für einen Befehl gültiges Token kann die vorgelagerte Validierung für einen anderen Befehl nicht erreichen).
- Akzeptierte Callbacks werden mit einer flüchtigen Antwort „Verarbeitung läuft …“ bestätigt; die eigentliche Antwort trifft als normale Nachricht ein.
Erreichbarkeitsanforderung
Der Callback-Endpunkt muss vom Mattermost-Server aus erreichbar sein.
- Setzen Sie
callbackUrlnicht auflocalhost, es sei denn, Mattermost wird auf demselben Host bzw. im selben Netzwerk-Namespace wie OpenClaw ausgeführt. - Setzen Sie
callbackUrlnicht auf Ihre Mattermost-Basis-URL, es sei denn, diese URL leitet/api/channels/mattermost/commandper Reverse-Proxy an OpenClaw weiter. - Eine schnelle Prüfung ist
curl https://<gateway-host>/api/channels/mattermost/command; eine GET-Anfrage sollte405 Method Not Allowedvon OpenClaw zurückgeben, nicht404.
Mattermost-Ausgangs-Allowlist
Wenn Ihre Callback-Ziele private, Tailnet- oder interne Adressen sind, setzen Sie Mattermost ServiceSettings.AllowedUntrustedInternalConnections so, dass der Callback-Host bzw. die Callback-Domain enthalten ist.
Verwenden Sie Host-/Domain-Einträge, keine vollständigen URLs.
- Richtig:
gateway.tailnet-name.ts.net - Falsch:
https://gateway.tailnet-name.ts.net
Umgebungsvariablen (Standardkonto)
Legen Sie diese auf dem Gateway-Host fest, wenn Sie Umgebungsvariablen bevorzugen:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Chatmodi
Mattermost antwortet automatisch auf Direktnachrichten. Das Kanalverhalten wird durch chatmode gesteuert:
oncall (default)
Nur antworten, wenn in Kanälen eine @Erwähnung erfolgt.
onmessage
Auf jede Kanalnachricht antworten.
onchar
Antworten, wenn eine Nachricht mit einem Auslösepräfix beginnt.
Konfigurationsbeispiel:
{ channels: { mattermost: { chatmode: "onchar", oncharPrefixes: [">", "!"], // Standard }, },}Hinweise:
oncharreagiert weiterhin auf ausdrückliche @Erwähnungen.channels.mattermost.requireMentionwird weiterhin berücksichtigt,chatmodewird jedoch bevorzugt. Kanalspezifischegroups.<channelId>.requireMention-Einstellungen haben Vorrang vor beiden.- Nachdem der Bot in einem Kanal-Thread eine sichtbare Antwort gesendet hat, werden spätere Nachrichten im selben Thread ohne erneute @Erwähnung oder ein
onchar-Präfix beantwortet, sodass mehrstufige Thread-Unterhaltungen fortgesetzt werden. Die Teilnahme wird nach der letzten Antwort des Bots in diesem Thread 7 Tage lang gespeichert und bleibt über Gateway-Neustarts hinweg bestehen. Threads, die der Bot lediglich beobachtet hat, sind davon nicht betroffen; beginnen Sie eine neue Nachricht auf oberster Ebene, damit wieder eine ausdrückliche Erwähnung erforderlich ist. - Setzen Sie
channels.mattermost.implicitMentions.threadParticipation: false, damit Folgenachrichten in Threads mit Bot-Beteiligung die Erwähnungsprüfung nicht umgehen. Kontospezifische Überschreibungen verwendenchannels.mattermost.accounts.<id>.implicitMentions. Mattermost erzeugt derzeit keinereplyToBot- oderquotedBot-Fakten, daher haben diese Flags hier keine Wirkung.
Threads und Sitzungen
Verwenden Sie channels.mattermost.replyToMode, um festzulegen, ob Kanal- und Gruppenantworten im Hauptkanal verbleiben oder einen Thread unter dem auslösenden Beitrag beginnen.
off(Standard): Nur in einem Thread antworten, wenn sich der eingehende Beitrag bereits in einem Thread befindet.first: Für Kanal- oder Gruppenbeiträge auf oberster Ebene einen Thread unter diesem Beitrag beginnen und die Unterhaltung an eine Thread-spezifische Sitzung weiterleiten.allundbatched: Derzeit dasselbe Verhalten wiefirstfür Mattermost, da nach dem Vorhandensein eines Thread-Stammbeitrags in Mattermost nachfolgende Abschnitte und Medien im selben Thread verbleiben.- Direktnachrichten verwenden standardmäßig
off, selbst wennreplyToModefestgelegt ist.
Verwenden Sie channels.mattermost.replyToModeByChatType, um den Modus für Chats des Typs direct, group oder channel zu überschreiben. Setzen Sie direct, um Threads für Direktnachrichten zu aktivieren:
off(Standard): Direktnachrichten bleiben ohne Threads in einer fortlaufenden Sitzung.first,alloderbatched: Jede Direktnachricht auf oberster Ebene beginnt einen Mattermost-Thread, dem eine neue, unabhängige Sitzung zugrunde liegt.
{ channels: { mattermost: { replyToMode: "all", replyToModeByChatType: { direct: "first", }, }, },}Hinweise:
- Thread-spezifische Sitzungen verwenden die ID des auslösenden Beitrags als Thread-Stamm.
firstundallsind derzeit gleichwertig, da nach dem Vorhandensein eines Thread-Stamms in Mattermost nachfolgende Abschnitte und Medien im selben Thread verbleiben.- Überschreibungen pro Chattyp haben Vorrang vor
replyToMode. Ohne einedirect-Überschreibung behalten bestehende Bereitstellungen flache Direktnachrichten ohne Threads bei.
Zugriffskontrolle (Direktnachrichten)
- Standard:
channels.mattermost.dmPolicy = "pairing"(unbekannte Absender erhalten einen Kopplungscode). Weitere Werte:allowlist,open,disabled. - Genehmigung über:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- Öffentliche Direktnachrichten:
channels.mattermost.dmPolicy="open"pluschannels.mattermost.allowFrom=["*"](das Konfigurationsschema erzwingt den Platzhalter). channels.mattermost.allowFromakzeptiert Benutzer-IDs (empfohlen) undaccessGroup:<name>-Einträge. Siehe Zugriffsgruppen.
Kanäle (Gruppen)
- Standard:
channels.mattermost.groupPolicy = "allowlist"(Erwähnung erforderlich). - Lassen Sie Absender mit
channels.mattermost.groupAllowFromzu (Benutzer-IDs empfohlen). channels.mattermost.groupAllowFromakzeptiertaccessGroup:<name>-Einträge. Siehe Zugriffsgruppen.- Kanalspezifische Überschreibungen der Erwähnungseinstellung befinden sich unter
channels.mattermost.groups.<channelId>.requireMentionoder standardmäßig unterchannels.mattermost.groups["*"].requireMention. - Der Abgleich von
@usernameist veränderlich und nur aktiviert, wennchannels.mattermost.dangerouslyAllowNameMatching: true. - Offene Kanäle:
channels.mattermost.groupPolicy="open"(Erwähnung erforderlich). - Auflösungsreihenfolge:
channels.mattermost.groupPolicy, dannchannels.defaults.groupPolicy, dann"allowlist". - Laufzeithinweis: Wenn der Abschnitt
channels.mattermostvollständig fehlt, verwendet die Laufzeit für Gruppenprüfungen standardmäßig restriktivgroupPolicy="allowlist"(selbst wennchannels.defaults.groupPolicyfestgelegt ist) und protokolliert einmalig eine Warnung.
Beispiel:
{ channels: { mattermost: { groupPolicy: "open", groups: { "*": { requireMention: true }, "team-channel-id": { requireMention: false }, }, }, },}Ziele für ausgehende Zustellung
Verwenden Sie diese Zielformate mit openclaw message send oder Cron/Webhooks:
| Ziel | Zustellung an |
|---|---|
channel:<id> |
Kanal anhand der ID |
channel:<name> oder #channel-name |
Kanal anhand des Namens; Suche in allen Teams des Bots |
user:<id> oder mattermost:<id> |
Direktnachricht an diesen Benutzer |
@username |
Direktnachricht (Benutzername wird über die Mattermost-API aufgelöst) |
Ausgehende Nachrichten unterstützen höchstens einen Anhang pro Nachricht; teilen Sie mehrere Dateien auf separate Sendevorgänge auf.
Wiederholungsversuche für Direktnachrichtenkanäle
Wenn OpenClaw an ein Mattermost-Direktnachrichtenziel sendet und zuerst den direkten Kanal auflösen muss, wiederholt es standardmäßig vorübergehend fehlgeschlagene Erstellungsversuche für direkte Kanäle.
Verwenden Sie channels.mattermost.dmChannelRetry, um dieses Verhalten global für das Mattermost-Plugin anzupassen, oder channels.mattermost.accounts.<id>.dmChannelRetry für ein einzelnes Konto. Standardwerte:
{ channels: { mattermost: { dmChannelRetry: { maxRetries: 3, initialDelayMs: 1000, maxDelayMs: 10000, timeoutMs: 30000, }, }, },}Hinweise:
- Dies gilt nur für die Erstellung von Direktnachrichtenkanälen (
/api/v4/channels/direct), nicht für jeden Mattermost-API-Aufruf. - Wiederholungsversuche verwenden exponentielles Backoff mit Jitter und gelten für vorübergehende Fehler wie Ratenbegrenzungen, 5xx-Antworten sowie Netzwerk- oder Zeitüberschreitungsfehler.
- Andere 4xx-Clientfehler als
429werden als dauerhaft behandelt und nicht erneut versucht.
Vorschau-Streaming
Mattermost streamt Gedankengänge, Tool-Aktivitäten und Teile des Antworttexts in einen Vorschauentwurf, der an Ort und Stelle finalisiert wird, sobald die endgültige Antwort sicher gesendet werden kann. Im Modus partial wird die Vorschau unter derselben Beitrags-ID aktualisiert, statt den Kanal mit Nachrichten für jedes Fragment zu überfluten. Im Modus block wechselt die Vorschau zwischen abgeschlossenen Text- und Tool-Aktivitätsblöcken, sodass frühere Blöcke als eigene Beiträge sichtbar bleiben, statt vom nächsten überschrieben zu werden. Endgültige Medien-/Fehlerantworten brechen ausstehende Vorschauänderungen ab und verwenden die normale Zustellung, statt einen überflüssigen Vorschauentwurf zu veröffentlichen.
Vorschau-Streaming ist im Modus partial standardmäßig aktiviert. Konfigurieren Sie es über channels.mattermost.streaming.mode (veraltete skalare/boolesche streaming-Werte werden durch openclaw doctor --fix migriert):
{ channels: { mattermost: { streaming: { mode: "partial" }, // off | partial | block | progress }, },}Streaming-Modi
partial(Standard): ein Vorschauentwurf, der mit zunehmendem Antwortumfang bearbeitet und anschließend mit der vollständigen Antwort finalisiert wird.blockwechselt die Vorschau zwischen abgeschlossenen Text- und Tool-Aktivitätsblöcken, sodass jeder Block als eigener Beitrag sichtbar bleibt, statt an Ort und Stelle überschrieben zu werden. Parallele und aufeinanderfolgende Tool-Aktualisierungen verwenden gemeinsam den aktuellen Tool-Aktivitätsbeitrag.progresszeigt während der Generierung eine Statusvorschau und veröffentlicht die endgültige Antwort erst nach Abschluss.offdeaktiviert das Vorschau-Streaming. Mitstreaming.block.enabled: truewerden abgeschlossene Assistentenblöcke weiterhin als normale Blockantworten (separate Beiträge) statt als einzelner zusammengeführter endgültiger Beitrag zugestellt.
Hinweise zum Streaming-Verhalten
- Wenn der Stream nicht an Ort und Stelle finalisiert werden kann (beispielsweise weil der Beitrag während des Streamings gelöscht wurde), sendet OpenClaw ersatzweise einen neuen endgültigen Beitrag, damit die Antwort niemals verloren geht.
- Nutzdaten, die ausschließlich Gedankengänge enthalten, werden in Kanalbeiträgen unterdrückt, einschließlich Text, der als
> Thinking-Blockzitat eingeht. Setzen Sie/reasoning on, um Gedankengänge auf anderen Oberflächen anzuzeigen; der endgültige Mattermost-Beitrag enthält nur die Antwort. - Die Kanalzuordnungsmatrix finden Sie unter Streaming.
Reaktionen (Nachrichten-Tool)
- Verwenden Sie
message action=reactmitchannel=mattermost. messageIdist die Mattermost-Beitrags-ID.emojiakzeptiert Namen wiethumbsupoder:+1:(Doppelpunkte sind optional).- Setzen Sie
remove=true(boolesch), um eine Reaktion zu entfernen. - Ereignisse zum Hinzufügen/Entfernen von Reaktionen werden als Systemereignisse an die zugeordnete Agentensitzung weitergeleitet und unterliegen denselben Richtlinienprüfungen für Direktnachrichten/Gruppen wie Nachrichten.
Beispiele:
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsupmessage action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=trueKonfiguration:
channels.mattermost.actions.reactions: Reaktionsaktionen aktivieren/deaktivieren (standardmäßig true).- Kontospezifische Überschreibung:
channels.mattermost.accounts.<id>.actions.reactions.
Interaktive Schaltflächen (Nachrichten-Tool)
Senden Sie Nachrichten mit anklickbaren Schaltflächen. Wenn ein Benutzer auf eine Schaltfläche klickt, erhält der Agent die Auswahl und kann antworten.
Schaltflächen stammen aus der semantischen presentation-Nutzlast (in normalen Agentenantworten und in message action=send). OpenClaw stellt Werteschaltflächen als interaktive Mattermost-Schaltflächen dar, lässt URL-Schaltflächen im Nachrichtentext sichtbar und stuft Auswahlmenüs zu lesbarem Text herab.
message action=send channel=mattermost target=channel:<channelId> presentation={"blocks":[{"type":"buttons","buttons":[{"label":"Yes","value":"yes"},{"label":"No","value":"no"}]}]}Felder für Darstellungsschaltflächen:
labelstringrequiredAnzeigebeschriftung (Alias: text).
valuestringBeim Klicken zurückgesendeter Wert, der als Aktions-ID verwendet wird (Aliasse: callback_data, callbackData). Für eine anklickbare Schaltfläche erforderlich, sofern url nicht gesetzt ist.
urlstringLink-Schaltfläche; wird als label: url-Text im Nachrichtentext statt als interaktive Schaltfläche dargestellt.
style"primary" | "secondary" | "success" | "danger"Schaltflächenstil. Mattermost verwendet für nicht unterstützte Werte den Standardstil.
Um die Unterstützung für Schaltflächen im Agenten-Systemprompt anzugeben, fügen Sie inlineButtons zu den Kanalfunktionen hinzu:
{ channels: { mattermost: { capabilities: ["inlineButtons"], }, },}Wenn ein Benutzer auf eine Schaltfläche klickt:
Zugriffsprüfung
Die klickende Person muss dieselben Richtlinienprüfungen für Direktnachrichten/Gruppen wie ein Nachrichtenabsender bestehen; bei nicht autorisierten Klicks wird ein flüchtiger Hinweis angezeigt und der Klick ignoriert.
Schaltflächen durch Bestätigung ersetzt
Alle Schaltflächen werden durch eine Bestätigungszeile ersetzt (z. B. „✓ Yes ausgewählt von @user“).
Agent erhält die Auswahl
Der Agent erhält die Auswahl als eingehende Nachricht (zusätzlich zu einem Systemereignis) und antwortet.
Implementierungshinweise
- Schaltflächen-Callbacks verwenden eine HMAC-SHA256-Verifizierung (automatisch, keine Konfiguration erforderlich).
- Beim Klicken wird der gesamte Anhangsblock ersetzt, sodass alle Schaltflächen gemeinsam entfernt werden – eine teilweise Entfernung ist nicht möglich.
- Aktions-IDs mit Bindestrichen oder Unterstrichen werden automatisch bereinigt (Mattermost-Routing-Beschränkung).
- Klicks, deren
action_idmit keiner Aktion des ursprünglichen Beitrags übereinstimmt, werden mit403(„Unbekannte Aktion“) abgelehnt.
Konfiguration und Erreichbarkeit
channels.mattermost.capabilities: Array von Funktionszeichenfolgen. Fügen Sie"inlineButtons"hinzu, um die Beschreibung des Schaltflächen-Tools im Agenten-Systemprompt zu aktivieren.channels.mattermost.interactions.callbackBaseUrl: optionale externe Basis-URL für Schaltflächen-Callbacks (beispielsweisehttps://gateway.example.com). Verwenden Sie diese, wenn Mattermost den Gateway unter dessen Bind-Host nicht direkt erreichen kann.- Bei Konfigurationen mit mehreren Konten können Sie dasselbe Feld auch unter
channels.mattermost.accounts.<id>.interactions.callbackBaseUrlfestlegen. - Wenn
interactions.callbackBaseUrlweggelassen wird, leitet OpenClaw die Callback-URL ausgateway.customBindHost+gateway.port(Standard 18789) ab und greift anschließend aufhttp://localhost:<port>zurück. Der Callback-Pfad lautet/mattermost/interactions/<accountId>. - Erreichbarkeitsregel: Die Schaltflächen-Callback-URL muss vom Mattermost-Server aus erreichbar sein.
localhostfunktioniert nur, wenn Mattermost und OpenClaw auf demselben Host/im selben Netzwerk-Namespace ausgeführt werden. channels.mattermost.interactions.allowedSourceIps: Quell-IP-Zulassungsliste für Schaltflächen-Callbacks. Ohne diese werden nur Loopback-Quellen (127.0.0.1,::1) akzeptiert. Daher muss ein entfernter Mattermost-Server hier in die Zulassungsliste aufgenommen werden, andernfalls werden seine Klicks mit403abgelehnt. Legen Sie hinter einem Reverse-Proxy außerdemgateway.trustedProxiesfest, damit die tatsächliche Client-IP aus weitergeleiteten Headern ermittelt wird.- Wenn Ihr Callback-Ziel privat/im Tailnet/intern ist, fügen Sie dessen Host/Domain zu Mattermost
ServiceSettings.AllowedUntrustedInternalConnectionshinzu.
Direkte API-Integration (externe Skripte)
Externe Skripte und Webhooks können Schaltflächen direkt über die Mattermost-REST-API veröffentlichen, statt das message-Tool des Agenten zu verwenden. Bevorzugen Sie das message-Tool von OpenClaw. Importieren Sie für direkte Integrationen buildButtonAttachments aus @openclaw/mattermost/api.js; wenn Sie unverarbeitetes JSON veröffentlichen, befolgen Sie diese Regeln:
Nutzlaststruktur:
{ 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 action: "approve", // ... any custom fields ... _token: "<hmac>", // see HMAC section below }, }, }, ], }, ], },}HMAC-Token-Generierung
Der Gateway verifiziert Schaltflächenklicks mit HMAC-SHA256. Externe Skripte müssen Token generieren, die der Verifizierungslogik des Gateways entsprechen:
Geheimnis aus dem Bot-Token ableiten
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken), hexadezimal codiert.
Kontextobjekt erstellen
Erstellen Sie das Kontextobjekt mit allen Feldern außer _token.
Mit sortierten Schlüsseln serialisieren
Serialisieren Sie mit rekursiv sortierten Schlüsseln und ohne Leerzeichen (der Gateway kanonisiert auch verschachtelte Objekte und erzeugt kompaktes JSON).
Nutzlast signieren
HMAC-SHA256(key=secret, data=serializedContext)
Token hinzufügen
Fügen Sie den resultierenden hexadezimalen Digest als _token zum Kontext hinzu.
Python-Beispiel:
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"}). Verwenden Sieseparators=(",", ":"), damit die Ausgabe dem kompakten Format von JavaScript entspricht ({"key":"val"}). - Signieren Sie stets alle Kontextfelder (mit Ausnahme von
_token). Der Gateway entfernt_tokenund signiert anschließend alle verbleibenden Felder. Das Signieren einer Teilmenge führt zu einem stillen Verifizierungsfehler. - Verwenden Sie
sort_keys=True– der Gateway sortiert die Schlüssel vor dem Signieren, und Mattermost kann die Kontextfelder beim Speichern der Nutzlast neu anordnen. - Leiten Sie das Geheimnis aus dem Bot-Token ab (deterministisch), nicht aus zufälligen Bytes. Das Geheimnis muss in dem Prozess, der die Schaltflächen erstellt, und im Gateway, der sie 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 sowie bei Cron-/Webhook-Zustellungen.
Es ist keine Konfiguration erforderlich – der Adapter verwendet das Bot-Token aus der Kontokonfiguration.
Mehrere Konten
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" }, }, }, },}Kontowerte überschreiben Felder der obersten Ebene; channels.mattermost.defaultAccount bestimmt, welches Konto verwendet wird, wenn keines angegeben ist.
Fehlerbehebung
Keine Antworten in Kanälen
Stellen Sie sicher, dass sich der Bot im Kanal befindet, und erwähnen Sie ihn (oncall), verwenden Sie ein Auslösepräfix (onchar) oder setzen Sie chatmode: "onmessage".
Authentifizierungs- oder Mehrkontenfehler
- Überprüfen Sie das Bot-Token, die Basis-URL und ob das Konto aktiviert ist.
- Probleme mit mehreren Konten: Umgebungsvariablen gelten nur für das Konto
default. - Private/LAN-Mattermost-Hosts benötigen
network.dangerouslyAllowPrivateNetwork: true(der SSRF-Schutz blockiert standardmäßig private IP-Adressen).
Native Slash-Befehle schlagen fehl
Unauthorized: invalid command token.: OpenClaw hat das Callback-Token nicht akzeptiert. Typische Ursachen:- Die Registrierung des Slash-Befehls ist fehlgeschlagen oder wurde beim Start nur teilweise abgeschlossen.
- Der Callback erreicht den falschen Gateway bzw. das falsche Konto.
- Mattermost verfügt noch über alte Befehle, die auf ein vorheriges Callback-Ziel verweisen.
- Der Gateway wurde neu gestartet, ohne die Slash-Befehle erneut zu aktivieren.
- Wenn native Slash-Befehle nicht mehr funktionieren, prüfen Sie die Protokolle auf
mattermost: failed to register slash commandsodermattermost: native slash commands enabled but no commands could be registered. - Wenn
callbackUrlweggelassen wird und die Protokolle davor warnen, dass der Callback zu einer Loopback-URL wiehttp://localhost:18789/...aufgelöst wurde, ist diese URL wahrscheinlich nur erreichbar, wenn Mattermost im selben Host-/Netzwerk-Namespace wie OpenClaw ausgeführt wird. Legen Sie stattdessen explizit eine extern erreichbarecommands.callbackUrlfest.
Probleme mit Schaltflächen
- Schaltflächen erscheinen als weiße Kästchen oder überhaupt nicht: Die Schaltflächendaten sind fehlerhaft. Jede Präsentationsschaltfläche benötigt
labelundvalue(Schaltflächen, bei denen eines davon fehlt, werden verworfen). - Schaltflächen werden dargestellt, aber Klicks haben keine Wirkung: Stellen Sie sicher, dass der Gateway vom Mattermost-Server aus erreichbar ist, die IP-Adresse des Mattermost-Servers in
channels.mattermost.interactions.allowedSourceIpsenthalten ist (ohne diese Angabe wird nur Loopback akzeptiert) undServiceSettings.AllowedUntrustedInternalConnectionsbei privaten Zielen den Callback-Host enthält. - Schaltflächen geben beim Klicken 404 zurück: Die
idder Schaltfläche enthält wahrscheinlich Bindestriche oder Unterstriche. Der Aktionsrouter von Mattermost funktioniert nicht mit nicht alphanumerischen IDs. Verwenden Sie ausschließlich[a-zA-Z0-9]. - Der Gateway protokolliert
rejected callback source: Der Klick kam von einer IP-Adresse außerhalb voninteractions.allowedSourceIps. Nehmen Sie den Mattermost-Server oder Ihren Ingress in die Positivliste auf und setzen Siegateway.trustedProxies, wenn Sie einen Reverse-Proxy verwenden. - Der Gateway protokolliert
invalid _token: HMAC stimmt nicht überein. Prüfen Sie, ob Sie alle Kontextfelder (nicht nur eine Teilmenge) signieren, sortierte Schlüssel und kompaktes JSON (ohne Leerzeichen) verwenden. Weitere Informationen finden Sie im HMAC-Abschnitt oben. - Der Gateway protokolliert
missing _token in context: Das Feld_tokenist nicht im Kontext der Schaltfläche enthalten. Stellen Sie sicher, dass es beim Erstellen der Integrationsnutzlast einbezogen wird. - Der Gateway lehnt den Klick mit
Unknown actionab:context.action_idstimmt mit keinerid-Aktion des Beitrags überein. Setzen Sie beide auf denselben bereinigten Wert. - Der Agent bietet keine Schaltflächen an: Fügen Sie
capabilities: ["inlineButtons"]zur Mattermost-Kanalkonfiguration hinzu.
Verwandte Themen
- Kanalrouting – Sitzungsrouting für Nachrichten
- Kanalübersicht – alle unterstützten Kanäle
- Gruppen – Verhalten von Gruppenchats und Steuerung durch Erwähnungen
- Kopplung – DM-Authentifizierung und Kopplungsablauf
- Sicherheit – Zugriffsmodell und Absicherung