Developer and self-hosted
Mattermost
Status: Plugin baixável (token de bot + eventos WebSocket). Há suporte a canais, grupos e DMs. Mattermost é uma plataforma de mensagens em equipe auto-hospedável; consulte o site oficial em mattermost.com para detalhes do produto e downloads.
Instalar
Instale o Mattermost antes de configurar o canal:
npm registry
openclaw plugins install @openclaw/mattermostLocal checkout
openclaw plugins install ./path/to/local/mattermost-pluginDetalhes: Plugins
Configuração rápida
Garantir que o Plugin esteja disponível
As versões empacotadas atuais do OpenClaw já o incluem. Instalações mais antigas/personalizadas podem adicioná-lo manualmente com os comandos acima.
Criar um bot do Mattermost
Crie uma conta de bot do Mattermost e copie o token do bot.
Copiar a URL base
Copie a URL base do Mattermost (por exemplo, https://chat.example.com).
Configurar o OpenClaw e iniciar o Gateway
Configuração mínima:
{ channels: { mattermost: { enabled: true, botToken: "mm-token", baseUrl: "https://chat.example.com", dmPolicy: "pairing", }, },}Comandos de barra nativos
Comandos de barra nativos são opcionais. Quando habilitados, o OpenClaw registra comandos de barra oc_* pela API do Mattermost e recebe POSTs de callback no servidor HTTP do Gateway.
{ 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", }, }, },}Observações de comportamento
native: "auto"usa desabilitado por padrão para Mattermost. Definanative: truepara habilitar.- Se
callbackUrlfor omitido, o OpenClaw deriva uma a partir do host/porta do Gateway +callbackPath. - Para configurações com várias contas,
commandspode ser definido no nível superior ou emchannels.mattermost.accounts.<id>.commands(valores da conta substituem campos do nível superior). - Callbacks de comando são validados com os tokens por comando retornados pelo Mattermost quando o OpenClaw registra comandos
oc_*. - O OpenClaw atualiza o registro de comandos atual do Mattermost antes de aceitar cada callback, para que tokens obsoletos de comandos de barra excluídos ou regenerados deixem de ser aceitos sem reiniciar o Gateway.
- A validação de callback falha de modo fechado se a API do Mattermost não puder confirmar que o comando ainda é atual; validações com falha são armazenadas brevemente em cache, consultas simultâneas são coalescidas, e inícios de novas consultas têm limite de taxa por comando para conter pressão de repetição.
- Callbacks de barra falham de modo fechado quando o registro falhou, a inicialização foi parcial, ou o token de callback não corresponde ao token registrado do comando resolvido (um token válido para um comando não pode chegar à validação upstream de outro comando).
Requisito de alcançabilidade
O endpoint de callback deve ser alcançável a partir do servidor Mattermost.
- Não defina
callbackUrlcomolocalhosta menos que o Mattermost rode no mesmo host/namespace de rede que o OpenClaw. - Não defina
callbackUrlcomo sua URL base do Mattermost a menos que essa URL faça proxy reverso de/api/channels/mattermost/commandpara o OpenClaw. - Uma verificação rápida é
curl https://<gateway-host>/api/channels/mattermost/command; um GET deve retornar405 Method Not Alloweddo OpenClaw, não404.
Lista de permissões de egresso do Mattermost
Se o seu callback apontar para endereços privados/tailnet/internos, defina ServiceSettings.AllowedUntrustedInternalConnections do Mattermost para incluir o host/domínio do callback.
Use entradas de host/domínio, não URLs completas.
- Bom:
gateway.tailnet-name.ts.net - Ruim:
https://gateway.tailnet-name.ts.net
Variáveis de ambiente (conta padrão)
Defina estas no host do Gateway se preferir variáveis de ambiente:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Modos de chat
Mattermost responde automaticamente a DMs. O comportamento de canal é controlado por chatmode:
oncall (padrão)
Responde somente quando @mencionado em canais.
onmessage
Responde a toda mensagem de canal.
onchar
Responde quando uma mensagem começa com um prefixo de acionamento.
Exemplo de configuração:
{ channels: { mattermost: { chatmode: "onchar", oncharPrefixes: [">", "!"], }, },}Observações:
oncharainda responde a @menções explícitas.channels.mattermost.requireMentioné respeitado para configurações legadas, maschatmodeé preferido.
Threads e sessões
Use channels.mattermost.replyToMode para controlar se respostas em canais e grupos permanecem no canal principal ou iniciam uma thread sob a publicação acionadora.
off(padrão): só responde em uma thread quando a publicação recebida já está em uma.first: para publicações de nível superior em canal/grupo, inicia uma thread sob essa publicação e roteia a conversa para uma sessão com escopo de thread.all: mesmo comportamento quefirstpara Mattermost hoje.- Mensagens diretas ignoram esta configuração e permanecem sem thread.
Exemplo de configuração:
{ channels: { mattermost: { replyToMode: "all", }, },}Observações:
- Sessões com escopo de thread usam o ID da publicação acionadora como raiz da thread.
firsteallsão atualmente equivalentes porque, depois que o Mattermost tem uma raiz de thread, blocos de acompanhamento e mídia continuam nessa mesma thread.
Controle de acesso (DMs)
- Padrão:
channels.mattermost.dmPolicy = "pairing"(remetentes desconhecidos recebem um código de pareamento). - Aprove por:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- DMs públicas:
channels.mattermost.dmPolicy="open"maischannels.mattermost.allowFrom=["*"]. channels.mattermost.allowFromaceita entradasaccessGroup:<name>. Consulte Grupos de acesso.
Canais (grupos)
- Padrão:
channels.mattermost.groupPolicy = "allowlist"(controlado por menção). - Coloque remetentes na lista de permissões com
channels.mattermost.groupAllowFrom(IDs de usuário recomendados). channels.mattermost.groupAllowFromaceita entradasaccessGroup:<name>. Consulte Grupos de acesso.- Substituições de menção por canal ficam em
channels.mattermost.groups.<channelId>.requireMentionouchannels.mattermost.groups["*"].requireMentionpara um padrão. - Correspondência de
@usernameé mutável e só é habilitada quandochannels.mattermost.dangerouslyAllowNameMatching: true. - Canais abertos:
channels.mattermost.groupPolicy="open"(controlado por menção). - Observação de runtime: se
channels.mattermostestiver completamente ausente, o runtime volta paragroupPolicy="allowlist"nas verificações de grupo (mesmo quechannels.defaults.groupPolicyesteja definido).
Exemplo:
{ channels: { mattermost: { groupPolicy: "open", groups: { "*": { requireMention: true }, "team-channel-id": { requireMention: false }, }, }, },}Alvos para entrega de saída
Use estes formatos de alvo com openclaw message send ou cron/Webhooks:
channel:<id>para um canaluser:<id>para uma DM@usernamepara uma DM (resolvido pela API do Mattermost)
Nova tentativa de canal de DM
Quando o OpenClaw envia para um alvo de DM do Mattermost e precisa resolver o canal direto primeiro, ele tenta novamente por padrão falhas transitórias de criação de canal direto.
Use channels.mattermost.dmChannelRetry para ajustar esse comportamento globalmente para o Plugin do Mattermost, ou channels.mattermost.accounts.<id>.dmChannelRetry para uma conta.
{ channels: { mattermost: { dmChannelRetry: { maxRetries: 3, initialDelayMs: 1000, maxDelayMs: 10000, timeoutMs: 30000, }, }, },}Observações:
- Isso se aplica apenas à criação de canal de DM (
/api/v4/channels/direct), não a toda chamada da API do Mattermost. - Novas tentativas se aplicam a falhas transitórias, como limites de taxa, respostas 5xx e erros de rede ou timeout.
- Erros de cliente 4xx diferentes de
429são tratados como permanentes e não são repetidos.
Streaming de pré-visualização
O Mattermost transmite pensamento, atividade de ferramentas e texto parcial de resposta para uma única publicação de pré-visualização de rascunho que é finalizada no lugar quando a resposta final está segura para envio. A pré-visualização é atualizada no mesmo ID de publicação em vez de inundar o canal com mensagens por bloco. Finais com mídia/erro cancelam edições de pré-visualização pendentes e usam entrega normal em vez de descarregar uma publicação de pré-visualização descartável.
Habilite via channels.mattermost.streaming:
{ channels: { mattermost: { streaming: "partial", // off | partial | block | progress }, },}Modos de streaming
partialé a escolha usual: uma publicação de pré-visualização que é editada conforme a resposta cresce e depois finalizada com a resposta completa.blockusa blocos de rascunho em estilo de anexação dentro da publicação de pré-visualização.progressmostra uma pré-visualização de status durante a geração e só publica a resposta final na conclusão.offdesabilita o streaming de pré-visualização.
Observações de comportamento de streaming
- Se o stream não puder ser finalizado no lugar (por exemplo, a publicação foi excluída no meio do stream), o OpenClaw volta para o envio de uma nova publicação final para que a resposta nunca seja perdida.
- Payloads apenas de raciocínio são suprimidos de publicações de canal, incluindo texto que chega como uma citação em bloco
> Reasoning:. Defina/reasoning onpara ver o pensamento em outras superfícies; a publicação final do Mattermost mantém apenas a resposta. - Consulte Streaming para a matriz de mapeamento de canais.
Reações (ferramenta de mensagem)
- Use
message action=reactcomchannel=mattermost. messageIdé o ID da publicação do Mattermost.emojiaceita nomes comothumbsupou:+1:(dois-pontos são opcionais).- Defina
remove=true(booleano) para remover uma reação. - Eventos de adicionar/remover reação são encaminhados como eventos de sistema para a sessão do agente roteada.
Exemplos:
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsupmessage action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=trueConfiguração:
channels.mattermost.actions.reactions: habilita/desabilita ações de reação (padrão true).- Substituição por conta:
channels.mattermost.accounts.<id>.actions.reactions.
Botões interativos (ferramenta de mensagem)
Envie mensagens com botões clicáveis. Quando um usuário clica em um botão, o agente recebe a seleção e pode responder.
Habilite botões adicionando inlineButtons às capacidades do canal:
{ channels: { mattermost: { capabilities: ["inlineButtons"], }, },}Use message action=send com um parâmetro buttons. Botões são uma matriz 2D (linhas de botões):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]Campos de botão:
textstringrequiredRótulo de exibição.
callback_datastringrequiredValor enviado de volta no clique (usado como ID da ação).
style"default" | "primary" | "danger"Estilo do botão.
Quando um usuário clica em um botão:
Botões substituídos por confirmação
Todos os botões são substituídos por uma linha de confirmação (por exemplo, "✓ Yes selected by @user").
O agente recebe a seleção
O agente recebe a seleção como uma mensagem de entrada e responde.
Notas de implementação
- Os callbacks de botão usam verificação HMAC-SHA256 (automática, sem necessidade de configuração).
- O Mattermost remove dados de callback das respostas da API dele (recurso de segurança), então todos os botões são removidos no clique - a remoção parcial não é possível.
- IDs de ação que contêm hífens ou sublinhados são higienizados automaticamente (limitação de roteamento do Mattermost).
Configuração e acessibilidade
channels.mattermost.capabilities: array de strings de capacidade. Adicione"inlineButtons"para habilitar a descrição da ferramenta de botões no prompt de sistema do agente.channels.mattermost.interactions.callbackBaseUrl: URL base externa opcional para callbacks de botão (por exemplohttps://gateway.example.com). Use isso quando o Mattermost não conseguir alcançar o Gateway diretamente no host de vinculação dele.- Em configurações com várias contas, você também pode definir o mesmo campo em
channels.mattermost.accounts.<id>.interactions.callbackBaseUrl. - Se
interactions.callbackBaseUrlfor omitido, o OpenClaw deriva a URL de callback degateway.customBindHost+gateway.porte depois recorre ahttp://localhost:<port>. - Regra de acessibilidade: a URL de callback do botão precisa estar acessível a partir do servidor Mattermost.
localhostsó funciona quando Mattermost e OpenClaw são executados no mesmo host/namespace de rede. - Se o destino do seu callback for privado/tailnet/interno, adicione o host/domínio dele a
ServiceSettings.AllowedUntrustedInternalConnectionsdo Mattermost.
Integração direta com a API (scripts externos)
Scripts externos e webhooks podem publicar botões diretamente pela API REST do Mattermost em vez de passar pela ferramenta message do agente. Use buildButtonAttachments() do Plugin quando possível; se publicar JSON bruto, siga estas regras:
Estrutura do payload:
{ 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 }, }, }, ], }, ], },}Geração de token HMAC
O Gateway verifica cliques de botão com HMAC-SHA256. Scripts externos devem gerar tokens que correspondam à lógica de verificação do Gateway:
Derive o segredo do token do bot
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)
Monte o objeto de contexto
Monte o objeto de contexto com todos os campos exceto _token.
Serialize com chaves ordenadas
Serialize com chaves ordenadas e sem espaços (o Gateway usa JSON.stringify com chaves ordenadas, o que produz saída compacta).
Assine o payload
HMAC-SHA256(key=secret, data=serializedContext)
Adicione o token
Adicione o digest hexadecimal resultante como _token no contexto.
Exemplo em 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}Armadilhas comuns de HMAC
- O
json.dumpsdo Python adiciona espaços por padrão ({"key": "val"}). Useseparators=(",", ":")para corresponder à saída compacta do JavaScript ({"key":"val"}). - Sempre assine todos os campos de contexto (menos
_token). O Gateway remove_tokene então assina tudo o que resta. Assinar um subconjunto causa falha silenciosa de verificação. - Use
sort_keys=True- o Gateway ordena as chaves antes de assinar, e o Mattermost pode reordenar campos de contexto ao armazenar o payload. - Derive o segredo do token do bot (determinístico), não de bytes aleatórios. O segredo deve ser o mesmo entre o processo que cria os botões e o Gateway que verifica.
Adaptador de diretório
O Plugin Mattermost inclui um adaptador de diretório que resolve nomes de canais e usuários por meio da API do Mattermost. Isso habilita destinos #channel-name e @username em openclaw message send e entregas de cron/webhook.
Nenhuma configuração é necessária - o adaptador usa o token do bot da configuração da conta.
Várias contas
O Mattermost é compatível com várias contas em 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" }, }, }, },}Solução de problemas
Sem respostas em canais
Garanta que o bot esteja no canal e mencione-o (oncall), use um prefixo de gatilho (onchar) ou defina chatmode: "onmessage".
Erros de autenticação ou várias contas
- Verifique o token do bot, a URL base e se a conta está habilitada.
- Problemas com várias contas: variáveis de ambiente se aplicam somente à conta
default.
Comandos de barra nativos falham
Unauthorized: invalid command token.: o OpenClaw não aceitou o token de callback. Causas típicas:- o registro de comando de barra falhou ou foi concluído apenas parcialmente na inicialização
- o callback está atingindo o Gateway/conta errado
- o Mattermost ainda tem comandos antigos apontando para um destino de callback anterior
- o Gateway reiniciou sem reativar comandos de barra
- Se os comandos de barra nativos pararem de funcionar, verifique os logs para
mattermost: failed to register slash commandsoumattermost: native slash commands enabled but no commands could be registered. - Se
callbackUrlfor omitido e os logs avisarem que o callback foi resolvido parahttp://127.0.0.1:18789/..., essa URL provavelmente só será acessível quando o Mattermost for executado no mesmo host/namespace de rede que o OpenClaw. Defina umacommands.callbackUrlexplícita e acessível externamente em vez disso.
Problemas com botões
- Os botões aparecem como caixas brancas: o agente pode estar enviando dados de botão malformados. Verifique se cada botão tem os campos
textecallback_data. - Os botões são renderizados, mas os cliques não fazem nada: verifique se
AllowedUntrustedInternalConnectionsna configuração do servidor Mattermost inclui127.0.0.1 localhoste seEnablePostActionIntegrationétrueem ServiceSettings. - Os botões retornam 404 no clique: o
iddo botão provavelmente contém hífens ou sublinhados. O roteador de ações do Mattermost quebra em IDs não alfanuméricos. Use somente[a-zA-Z0-9]. - Logs do Gateway mostram
invalid _token: incompatibilidade de HMAC. Verifique se você assina todos os campos de contexto (não um subconjunto), usa chaves ordenadas e usa JSON compacto (sem espaços). Consulte a seção HMAC acima. - Logs do Gateway mostram
missing _token in context: o campo_tokennão está no contexto do botão. Garanta que ele esteja incluído ao montar o payload de integração. - A confirmação mostra ID bruto em vez do nome do botão:
context.action_idnão corresponde aoiddo botão. Defina ambos para o mesmo valor higienizado. - O agente não sabe sobre botões: adicione
capabilities: ["inlineButtons"]à configuração do canal Mattermost.
Relacionado
- Roteamento de canais - roteamento de sessão para mensagens
- Visão geral dos canais - todos os canais compatíveis
- Grupos - comportamento de chat em grupo e bloqueio por menção
- Pareamento - autenticação por DM e fluxo de pareamento
- Segurança - modelo de acesso e proteção