Developer and self-hosted

Mattermost

Stato: plugin scaricabile (token del bot + eventi WebSocket). Sono supportati canali, gruppi e DM. Mattermost è una piattaforma di messaggistica per team self-hostable; consulta il sito ufficiale su mattermost.com per dettagli sul prodotto e download.

Installazione

Installa Mattermost prima di configurare il canale:

registro npm

bash
openclaw plugins install @openclaw/mattermost

Checkout locale

bash
openclaw plugins install ./path/to/local/mattermost-plugin

Dettagli: Plugin

Configurazione rapida

  • Assicurati che il plugin sia disponibile

    Installa @openclaw/mattermost con il comando sopra, quindi riavvia il Gateway se è già in esecuzione.

  • Crea un bot Mattermost

    Crea un account bot Mattermost e copia il token del bot.

  • Copia l'URL di base

    Copia l'URL di base di Mattermost (ad esempio, https://chat.example.com).

  • Configura OpenClaw e avvia il gateway

    Configurazione minima:

    json5
    {  channels: {    mattermost: {      enabled: true,      botToken: "mm-token",      baseUrl: "https://chat.example.com",      dmPolicy: "pairing",    },  },}
  • Comandi slash nativi

    I comandi slash nativi sono opt-in. Quando sono abilitati, OpenClaw registra i comandi slash oc_* tramite l'API Mattermost e riceve i POST di callback sul server HTTP del gateway.

    json5
    {  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",      },    },  },}
    Note sul comportamento
    • native: "auto" è disabilitato per impostazione predefinita per Mattermost. Imposta native: true per abilitarlo.
    • Se callbackUrl viene omesso, OpenClaw ne deriva uno da host/porta del gateway + callbackPath.
    • Per configurazioni con più account, commands può essere impostato al livello superiore o sotto channels.mattermost.accounts.<id>.commands (i valori dell'account sovrascrivono i campi di livello superiore).
    • Le callback dei comandi vengono convalidate con i token per comando restituiti da Mattermost quando OpenClaw registra i comandi oc_*.
    • OpenClaw aggiorna la registrazione corrente dei comandi Mattermost prima di accettare ogni callback, così i token obsoleti di comandi slash eliminati o rigenerati smettono di essere accettati senza riavviare il gateway.
    • La convalida della callback fallisce in modo chiuso se l'API Mattermost non può confermare che il comando sia ancora corrente; le convalide non riuscite vengono memorizzate brevemente nella cache, le ricerche concorrenti vengono accorpate e gli avvii di nuove ricerche sono limitati per frequenza per comando per contenere la pressione da replay.
    • Le callback slash falliscono in modo chiuso quando la registrazione non è riuscita, l'avvio è stato parziale o il token della callback non corrisponde al token registrato del comando risolto (un token valido per un comando non può raggiungere la convalida upstream per un comando diverso).
    Requisito di raggiungibilità

    L'endpoint di callback deve essere raggiungibile dal server Mattermost.

    • Non impostare callbackUrl su localhost a meno che Mattermost non sia in esecuzione nello stesso host/namespace di rete di OpenClaw.
    • Non impostare callbackUrl sull'URL di base di Mattermost a meno che quell'URL non inoltri tramite reverse proxy /api/channels/mattermost/command a OpenClaw.
    • Un controllo rapido è curl https://<gateway-host>/api/channels/mattermost/command; una GET dovrebbe restituire 405 Method Not Allowed da OpenClaw, non 404.
    Allowlist di egress Mattermost

    Se la callback punta a indirizzi privati/tailnet/interni, imposta ServiceSettings.AllowedUntrustedInternalConnections di Mattermost in modo da includere l'host/dominio della callback.

    Usa voci host/dominio, non URL completi.

    • Corretto: gateway.tailnet-name.ts.net
    • Errato: https://gateway.tailnet-name.ts.net

    Variabili d'ambiente (account predefinito)

    Impostale sull'host del gateway se preferisci le variabili d'ambiente:

    • MATTERMOST_BOT_TOKEN=...
    • MATTERMOST_URL=https://chat.example.com

    Modalità chat

    Mattermost risponde automaticamente ai DM. Il comportamento del canale è controllato da chatmode:

    oncall (predefinita)

    Rispondi solo quando ricevi una @menzione nei canali.

    onmessage

    Rispondi a ogni messaggio del canale.

    onchar

    Rispondi quando un messaggio inizia con un prefisso di attivazione.

    Esempio di configurazione:

    json5
    {  channels: {    mattermost: {      chatmode: "onchar",      oncharPrefixes: [">", "!"],    },  },}

    Note:

    • onchar risponde comunque alle @menzioni esplicite.
    • channels.mattermost.requireMention è rispettato per le configurazioni legacy, ma chatmode è preferito.
    • Dopo che il bot invia una risposta visibile in un thread di canale, i messaggi successivi nello stesso thread ricevono risposta senza una nuova @menzione o prefisso onchar, quindi le conversazioni multi-turno nei thread continuano a fluire. La partecipazione viene ricordata per 7 giorni di inattività del thread (aggiornati a ogni risposta) e persiste tra i riavvii del gateway. I thread che il bot ha solo osservato non sono interessati; avvia un nuovo messaggio di livello superiore per richiedere di nuovo una menzione esplicita.

    Thread e sessioni

    Usa channels.mattermost.replyToMode per controllare se le risposte di canale e gruppo restano nel canale principale o avviano un thread sotto il post di attivazione.

    • off (predefinito): rispondi in un thread solo quando il post in ingresso è già in un thread.
    • first: per i post di livello superiore di canale/gruppo, avvia un thread sotto quel post e instrada la conversazione a una sessione con ambito thread.
    • all: stesso comportamento di first per Mattermost oggi.
    • I messaggi diretti ignorano questa impostazione e restano senza thread.

    Esempio di configurazione:

    json5
    {  channels: {    mattermost: {      replyToMode: "all",    },  },}

    Note:

    • Le sessioni con ambito thread usano l'ID del post di attivazione come radice del thread.
    • first e all sono attualmente equivalenti perché, una volta che Mattermost ha una radice del thread, i blocchi successivi e i media continuano nello stesso thread.

    Controllo degli accessi (DM)

    • Predefinito: channels.mattermost.dmPolicy = "pairing" (i mittenti sconosciuti ricevono un codice di pairing).
    • Approva tramite:
      • openclaw pairing list mattermost
      • openclaw pairing approve mattermost &lt;CODE&gt;
    • DM pubblici: channels.mattermost.dmPolicy="open" più channels.mattermost.allowFrom=["*"].
    • channels.mattermost.allowFrom accetta voci accessGroup:<name>. Vedi Gruppi di accesso.

    Canali (gruppi)

    • Predefinito: channels.mattermost.groupPolicy = "allowlist" (con gate tramite menzione).
    • Inserisci i mittenti nella allowlist con channels.mattermost.groupAllowFrom (ID utente consigliati).
    • channels.mattermost.groupAllowFrom accetta voci accessGroup:<name>. Vedi Gruppi di accesso.
    • Gli override delle menzioni per canale si trovano sotto channels.mattermost.groups.<channelId>.requireMention o channels.mattermost.groups["*"].requireMention per un valore predefinito.
    • La corrispondenza @username è mutabile e viene abilitata solo quando channels.mattermost.dangerouslyAllowNameMatching: true.
    • Canali aperti: channels.mattermost.groupPolicy="open" (con gate tramite menzione).
    • Nota di runtime: se channels.mattermost manca completamente, il runtime ripiega su groupPolicy="allowlist" per i controlli sui gruppi (anche se channels.defaults.groupPolicy è impostato).

    Esempio:

    json5
    {  channels: {    mattermost: {      groupPolicy: "open",      groups: {        "*": { requireMention: true },        "team-channel-id": { requireMention: false },      },    },  },}

    Target per la consegna in uscita

    Usa questi formati di target con openclaw message send o cron/webhook:

    • channel:<id> per un canale
    • user:<id> per un DM
    • @username per un DM (risolto tramite l'API Mattermost)

    Nuovo tentativo per il canale DM

    Quando OpenClaw invia a un target DM Mattermost e deve prima risolvere il canale diretto, per impostazione predefinita riprova gli errori transitori di creazione del canale diretto.

    Usa channels.mattermost.dmChannelRetry per regolare questo comportamento globalmente per il Plugin Mattermost, oppure channels.mattermost.accounts.<id>.dmChannelRetry per un account.

    json5
    {  channels: {    mattermost: {      dmChannelRetry: {        maxRetries: 3,        initialDelayMs: 1000,        maxDelayMs: 10000,        timeoutMs: 30000,      },    },  },}

    Note:

    • Questo si applica solo alla creazione del canale DM (/api/v4/channels/direct), non a ogni chiamata API Mattermost.
    • I nuovi tentativi si applicano a errori transitori come limiti di frequenza, risposte 5xx ed errori di rete o timeout.
    • Gli errori client 4xx diversi da 429 sono trattati come permanenti e non vengono ritentati.

    Streaming dell'anteprima

    Mattermost trasmette pensiero, attività degli strumenti e testo parziale della risposta in un singolo post di anteprima bozza che viene finalizzato sul posto quando la risposta finale è sicura da inviare. L'anteprima si aggiorna sullo stesso ID post invece di intasare il canale con messaggi per ogni blocco. Le finalizzazioni con media/errori annullano le modifiche dell'anteprima in sospeso e usano la consegna normale invece di svuotare un post di anteprima usa e getta.

    Abilita tramite channels.mattermost.streaming:

    json5
    {  channels: {    mattermost: {      streaming: "partial", // off | partial | block | progress    },  },}
    Modalità di streaming
    • partial è la scelta abituale: un post di anteprima che viene modificato man mano che la risposta cresce, poi finalizzato con la risposta completa.
    • block usa blocchi bozza in stile append all'interno del post di anteprima.
    • progress mostra un'anteprima di stato durante la generazione e pubblica solo la risposta finale al completamento.
    • off disabilita lo streaming dell'anteprima.
    Note sul comportamento dello streaming
    • Se lo stream non può essere finalizzato sul posto (per esempio il post è stato eliminato a metà stream), OpenClaw ripiega sull'invio di un nuovo post finale, così la risposta non viene mai persa.
    • I payload solo di pensiero vengono soppressi dai post del canale, incluso il testo che arriva come blockquote > Thinking. Imposta /reasoning on per vedere il pensiero in altre superfici; il post finale di Mattermost mantiene solo la risposta.
    • Vedi Streaming per la matrice di mapping dei canali.

    Reazioni (strumento messaggi)

    • Usa message action=react con channel=mattermost.
    • messageId è l'ID del post Mattermost.
    • emoji accetta nomi come thumbsup o :+1: (i due punti sono facoltativi).
    • Imposta remove=true (booleano) per rimuovere una reazione.
    • Gli eventi di aggiunta/rimozione delle reazioni vengono inoltrati come eventi di sistema alla sessione agente instradata.

    Esempi:

    Code
    message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsupmessage action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true

    Configurazione:

    • channels.mattermost.actions.reactions: abilita/disabilita le azioni di reazione (predefinito true).
    • Override per account: channels.mattermost.accounts.<id>.actions.reactions.

    Pulsanti interattivi (strumento messaggi)

    Invia messaggi con pulsanti cliccabili. Quando un utente fa clic su un pulsante, l'agente riceve la selezione e può rispondere.

    Le normali risposte dell'agente possono includere anche payload semantici presentation. OpenClaw rende i pulsanti con valore come pulsanti interattivi di Mattermost, mantiene i pulsanti URL visibili nel testo del messaggio e declassa i menu di selezione a testo leggibile.

    Abilita i pulsanti aggiungendo inlineButtons alle funzionalità del canale:

    json5
    {  channels: {    mattermost: {      capabilities: ["inlineButtons"],    },  },}

    Usa message action=send con un parametro buttons. I pulsanti sono un array 2D (righe di pulsanti):

    Code
    message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]

    Campi dei pulsanti:

    textstringrequired

    Etichetta visualizzata.

    callback_datastringrequired

    Valore reinviato al clic (usato come ID dell'azione).

    style"default" | "primary" | "danger"

    Stile del pulsante.

    Quando un utente fa clic su un pulsante:

  • Pulsanti sostituiti con una conferma

    Tutti i pulsanti vengono sostituiti con una riga di conferma (ad esempio, "✓ Yes selected by @user").

  • L'agente riceve la selezione

    L'agente riceve la selezione come messaggio in ingresso e risponde.

  • Note di implementazione
    • I callback dei pulsanti usano la verifica HMAC-SHA256 (automatica, non richiede configurazione).
    • Mattermost rimuove i dati di callback dalle sue risposte API (funzionalità di sicurezza), quindi tutti i pulsanti vengono rimossi al clic: la rimozione parziale non è possibile.
    • Gli ID azione che contengono trattini o underscore vengono sanificati automaticamente (limitazione del routing di Mattermost).
    Configurazione e raggiungibilità
    • channels.mattermost.capabilities: array di stringhe di funzionalità. Aggiungi "inlineButtons" per abilitare la descrizione dello strumento dei pulsanti nel prompt di sistema dell'agente.
    • channels.mattermost.interactions.callbackBaseUrl: URL base esterno facoltativo per i callback dei pulsanti (ad esempio https://gateway.example.com). Usalo quando Mattermost non può raggiungere direttamente il gateway al suo host di bind.
    • Nelle configurazioni multi-account, puoi impostare lo stesso campo anche sotto channels.mattermost.accounts.<id>.interactions.callbackBaseUrl.
    • Se interactions.callbackBaseUrl viene omesso, OpenClaw deriva l'URL di callback da gateway.customBindHost + gateway.port, poi ripiega su http://localhost:<port>.
    • Regola di raggiungibilità: l'URL di callback del pulsante deve essere raggiungibile dal server Mattermost. localhost funziona solo quando Mattermost e OpenClaw sono in esecuzione sullo stesso host/spazio dei nomi di rete.
    • Se la destinazione del callback è privata/tailnet/interna, aggiungi il suo host/dominio a ServiceSettings.AllowedUntrustedInternalConnections di Mattermost.

    Integrazione API diretta (script esterni)

    Script esterni e webhook possono pubblicare pulsanti direttamente tramite l'API REST di Mattermost invece di passare dallo strumento message dell'agente. Usa buildButtonAttachments() dal Plugin quando possibile; se pubblichi JSON grezzo, segui queste regole:

    Struttura del payload:

    json5
    {  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              },            },          },        ],      },    ],  },}

    Generazione del token HMAC

    Il gateway verifica i clic sui pulsanti con HMAC-SHA256. Gli script esterni devono generare token che corrispondano alla logica di verifica del gateway:

  • Deriva il segreto dal token del bot

    HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)

  • Costruisci l'oggetto context

    Costruisci l'oggetto context con tutti i campi tranne _token.

  • Serializza con chiavi ordinate

    Serializza con chiavi ordinate e senza spazi (il gateway usa JSON.stringify con chiavi ordinate, che produce output compatto).

  • Firma il payload

    HMAC-SHA256(key=secret, data=serializedContext)

  • Aggiungi il token

    Aggiungi il digest esadecimale risultante come _token nel context.

  • Esempio Python:

    python
     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}
    Errori comuni con HMAC
    • json.dumps di Python aggiunge spazi per impostazione predefinita ({"key": "val"}). Usa separators=(",", ":") per corrispondere all'output compatto di JavaScript ({"key":"val"}).
    • Firma sempre tutti i campi del context (meno _token). Il gateway rimuove _token e poi firma tutto ciò che rimane. Firmare un sottoinsieme causa un errore di verifica silenzioso.
    • Usa sort_keys=True: il gateway ordina le chiavi prima della firma e Mattermost potrebbe riordinare i campi del context durante la memorizzazione del payload.
    • Deriva il segreto dal token del bot (deterministico), non da byte casuali. Il segreto deve essere lo stesso tra il processo che crea i pulsanti e il gateway che verifica.

    Adattatore di directory

    Il Plugin Mattermost include un adattatore di directory che risolve nomi di canali e utenti tramite l'API di Mattermost. Questo abilita destinazioni #channel-name e @username in openclaw message send e nelle consegne cron/webhook.

    Non è necessaria alcuna configurazione: l'adattatore usa il token del bot dalla configurazione dell'account.

    Multi-account

    Mattermost supporta più account sotto channels.mattermost.accounts:

    json5
    {  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" },      },    },  },}

    Risoluzione dei problemi

    Nessuna risposta nei canali

    Assicurati che il bot sia nel canale e menzionalo (oncall), usa un prefisso trigger (onchar) oppure imposta chatmode: "onmessage".

    Errori di autenticazione o multi-account
    • Controlla il token del bot, l'URL base e se l'account è abilitato.
    • Problemi multi-account: le variabili d'ambiente si applicano solo all'account default.
    I comandi slash nativi non funzionano
    • Unauthorized: invalid command token.: OpenClaw non ha accettato il token di callback. Cause tipiche:
      • la registrazione del comando slash non è riuscita o è stata completata solo parzialmente all'avvio
      • il callback sta raggiungendo il gateway/account sbagliato
      • Mattermost ha ancora vecchi comandi che puntano a una destinazione di callback precedente
      • il gateway è stato riavviato senza riattivare i comandi slash
    • Se i comandi slash nativi smettono di funzionare, controlla nei log mattermost: failed to register slash commands o mattermost: native slash commands enabled but no commands could be registered.
    • Se callbackUrl viene omesso e i log avvisano che il callback è stato risolto in http://127.0.0.1:18789/..., quell'URL è probabilmente raggiungibile solo quando Mattermost è in esecuzione sullo stesso host/spazio dei nomi di rete di OpenClaw. Imposta invece un commands.callbackUrl esplicito e raggiungibile dall'esterno.
    Problemi con i pulsanti
    • I pulsanti appaiono come riquadri bianchi: l'agente potrebbe inviare dati dei pulsanti non validi. Controlla che ogni pulsante abbia entrambi i campi text e callback_data.
    • I pulsanti vengono renderizzati ma i clic non producono effetti: verifica che AllowedUntrustedInternalConnections nella configurazione del server Mattermost includa 127.0.0.1 localhost e che EnablePostActionIntegration sia true in ServiceSettings.
    • I pulsanti restituiscono 404 al clic: l'id del pulsante probabilmente contiene trattini o underscore. Il router delle azioni di Mattermost si interrompe con ID non alfanumerici. Usa solo [a-zA-Z0-9].
    • I log del gateway mostrano invalid _token: mancata corrispondenza HMAC. Controlla di firmare tutti i campi del context (non un sottoinsieme), di usare chiavi ordinate e JSON compatto (senza spazi). Vedi la sezione HMAC sopra.
    • I log del gateway mostrano missing _token in context: il campo _token non è nel context del pulsante. Assicurati che sia incluso quando costruisci il payload di integrazione.
    • La conferma mostra l'ID grezzo invece del nome del pulsante: context.action_id non corrisponde all'id del pulsante. Impostali entrambi allo stesso valore sanificato.
    • L'agente non sa dei pulsanti: aggiungi capabilities: ["inlineButtons"] alla configurazione del canale Mattermost.

    Correlati

    Was this useful?
    On this page

    On this page