Developer and self-hosted
Mattermost
Status: Plugin baixável (token de bot + eventos WebSocket). Canais, grupos e DMs são compatíveis. Mattermost é uma plataforma auto-hospedável de mensagens para equipes; consulte o site oficial em mattermost.com para detalhes do produto e downloads.
Instalar
Instale o Mattermost antes de configurar o canal:
registro npm
openclaw plugins install @openclaw/mattermost
Checkout local
openclaw plugins install ./path/to/local/mattermost-plugin
Detalhes: Plugins
Configuração rápida
Garanta 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.
Crie um bot do Mattermost
Crie uma conta de bot do Mattermost e copie o token do bot.
Copie a URL base
Copie a URL base do Mattermost (por exemplo, https://chat.example.com).
Configure o OpenClaw e inicie o Gateway
Configuração mínima:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
Comandos slash nativos
Comandos slash nativos são opcionais. Quando ativados, o OpenClaw registra comandos slash oc_* por meio da 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",
},
},
},
}
Notas de comportamento
native: "auto"fica desativado por padrão para Mattermost. Definanative: truepara ativar.- 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(os valores da conta substituem os campos de 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 atual de comandos do Mattermost antes de aceitar cada callback, de modo que tokens obsoletos de comandos slash excluídos ou regenerados deixem de ser aceitos sem reiniciar o Gateway.
- A validação de callback falha fechada se a API do Mattermost não puder confirmar que o comando ainda é atual; validações com falha são armazenadas em cache brevemente, buscas simultâneas são combinadas, e inícios de novas buscas têm limite de taxa por comando para limitar a pressão de replay.
- Callbacks slash falham fechados 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 consegue alcançar a validação upstream de um comando diferente).
Requisito de acessibilidade
O endpoint de callback deve estar acessível pelo servidor Mattermost.
- Não defina
callbackUrlcomolocalhost, a 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 callback apontar para endereços privados/tailnet/internos, defina ServiceSettings.AllowedUntrustedInternalConnections do Mattermost para incluir o host/domínio de 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 a DMs automaticamente. O comportamento em canais é controlado por chatmode:
oncall (padrão)
Responde somente quando @mencionado em canais.
onmessage
Responde a todas as mensagens do canal.
onchar
Responde quando uma mensagem começa com um prefixo de acionamento.
Exemplo de configuração:
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
Notas:
oncharainda responde a @menções explícitas.channels.mattermost.requireMentioné respeitado para configurações legadas, maschatmodeé preferível.
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 postagem acionadora.
off(padrão): responde em uma thread somente quando a postagem de entrada já estiver em uma.first: para postagens de canal/grupo no nível superior, inicia uma thread sob essa postagem e encaminha a conversa para uma sessão com escopo de thread.all: mesmo comportamento quefirstpara Mattermost atualmente.- Mensagens diretas ignoram esta configuração e permanecem sem thread.
Exemplo de configuração:
{
channels: {
mattermost: {
replyToMode: "all",
},
},
}
Notas:
- Sessões com escopo de thread usam o id da postagem acionadora como raiz da thread.
firsteallsão atualmente equivalentes porque, quando o Mattermost tem uma raiz de thread, chunks 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 via:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- DMs públicas:
channels.mattermost.dmPolicy="open"maischannels.mattermost.allowFrom=["*"].
Canais (grupos)
- Padrão:
channels.mattermost.groupPolicy = "allowlist"(controlado por menção). - Permita remetentes com
channels.mattermost.groupAllowFrom(IDs de usuário recomendados). - Substituições de menção por canal ficam em
channels.mattermost.groups.<channelId>.requireMentionouchannels.mattermost.groups["*"].requireMentionpara um padrão. - A correspondência de
@usernameé mutável e só é ativada quandochannels.mattermost.dangerouslyAllowNameMatching: true. - Canais abertos:
channels.mattermost.groupPolicy="open"(controlado por menção). - Nota de runtime: se
channels.mattermostestiver completamente ausente, o runtime volta paragroupPolicy="allowlist"em verificações de grupo (mesmo quechannels.defaults.groupPolicyesteja definido).
Exemplo:
{
channels: {
mattermost: {
groupPolicy: "open",
groups: {
"*": { requireMention: true },
"team-channel-id": { requireMention: false },
},
},
},
}
Destinos para entrega de saída
Use estes formatos de destino 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 destino de DM do Mattermost e precisa resolver o canal direto primeiro, ele tenta novamente falhas transitórias de criação de canal direto por padrão.
Use channels.mattermost.dmChannelRetry para ajustar esse comportamento globalmente para o Plugin Mattermost, ou channels.mattermost.accounts.<id>.dmChannelRetry para uma conta.
{
channels: {
mattermost: {
dmChannelRetry: {
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 10000,
timeoutMs: 30000,
},
},
},
}
Notas:
- Isso se aplica apenas à criação de canal de DM (
/api/v4/channels/direct), não a todas as chamadas 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 tentados novamente.
Streaming de pré-visualização
Mattermost transmite raciocínio, atividade de ferramentas e texto parcial de resposta para uma única postagem de pré-visualização de rascunho, que é finalizada no lugar quando a resposta final é segura para enviar. A pré-visualização é atualizada no mesmo id de postagem em vez de encher o canal com mensagens por chunk. Finais de mídia/erro cancelam edições de pré-visualização pendentes e usam entrega normal em vez de descarregar uma postagem de pré-visualização descartável.
Ative via channels.mattermost.streaming:
{
channels: {
mattermost: {
streaming: "partial", // off | partial | block | progress
},
},
}
Modos de streaming
partialé a escolha usual: uma postagem de pré-visualização que é editada conforme a resposta cresce, depois finalizada com a resposta completa.blockusa chunks de rascunho em estilo de acréscimo dentro da postagem de pré-visualização.progressmostra uma pré-visualização de status durante a geração e só publica a resposta final na conclusão.offdesativa o streaming de pré-visualização.
Notas de comportamento de streaming
- Se o stream não puder ser finalizado no lugar (por exemplo, se a postagem foi excluída no meio do stream), o OpenClaw recorre ao envio de uma nova postagem final para que a resposta nunca seja perdida.
- Payloads somente de raciocínio são suprimidos das postagens do canal, incluindo texto que chega como uma citação em bloco
> Reasoning:. Defina/reasoning onpara ver o raciocínio em outras superfícies; a postagem 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 postagem do Mattermost.emojiaceita nomes comothumbsupou:+1:(dois-pontos são opcionais).- Defina
remove=true(booleano) para remover uma reação. - Eventos de adição/remoção de 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=thumbsup
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true
Configuração:
channels.mattermost.actions.reactions: ativa/desativa 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.
Ative 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 um array 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 ao clicar (usado como ID da ação).
style"default" | "primary" | "danger"Estilo do botão.
Quando um usuário clica em um botão:
Buttons replaced with confirmation
Todos os botões são substituídos por uma linha de confirmação (por exemplo, "✓ Sim selecionado por @user").
Agent receives the selection
O agente recebe a seleção como uma mensagem de entrada e responde.
Implementation notes
- Os callbacks de botão usam verificação HMAC-SHA256 (automática, nenhuma configuração necessária).
- O Mattermost remove dados de callback de suas respostas de API (recurso de segurança), então todos os botões são removidos ao clicar - a remoção parcial não é possível.
- IDs de ação que contêm hifens ou underscores são sanitizados automaticamente (limitação de roteamento do Mattermost).
Config and reachability
channels.mattermost.capabilities: array de strings de capacidade. Adicione"inlineButtons"para habilitar a descrição da ferramenta de botões no prompt do sistema do agente.channels.mattermost.interactions.callbackBaseUrl: URL base externa opcional para callbacks de botão (por exemplo,https://gateway.example.com). Use isso quando o Mattermost não conseguir alcançar o Gateway diretamente no host de bind 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 então usahttp://localhost:<port>como fallback. - Regra de alcançabilidade: a URL de callback do botão deve ser alcançá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 callback for privado/tailnet/interno, adicione seu host/domínio a
ServiceSettings.AllowedUntrustedInternalConnectionsdo Mattermost.
Integração direta com 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 em botões com HMAC-SHA256. Scripts externos devem gerar tokens que correspondam à lógica de verificação do Gateway:
Derive the secret from the bot token
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)
Build the context object
Crie o objeto de contexto com todos os campos exceto _token.
Serialize with sorted keys
Serialize com chaves ordenadas e sem espaços (o Gateway usa JSON.stringify com chaves ordenadas, o que produz saída compacta).
Sign the payload
HMAC-SHA256(key=secret, data=serializedContext)
Add the 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}
Common HMAC pitfalls
- 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 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 no processo que cria botões e no Gateway que verifica.
Adaptador de diretório
O Plugin do Mattermost inclui um adaptador de diretório que resolve nomes de canais e usuários pela 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 oferece suporte a 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
No replies in channels
Verifique se o bot está no canal e mencione-o (oncall), use um prefixo de acionamento (onchar) ou defina chatmode: "onmessage".
Auth or multi-account errors
- Verifique o token do bot, a URL base e se a conta está habilitada.
- Problemas com várias contas: variáveis de ambiente só se aplicam à conta
default.
Native slash commands fail
Unauthorized: invalid command token.: o OpenClaw não aceitou o token de callback. Causas típicas:- o registro do comando de barra falhou ou foi concluído apenas parcialmente na inicialização
- o callback está chegando ao Gateway/conta errado
- o Mattermost ainda tem comandos antigos apontando para um destino de callback anterior
- o Gateway foi reiniciado sem reativar comandos de barra
- Se comandos de barra nativos pararem de funcionar, verifique os logs por
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ó é alcançável quando o Mattermost é executado no mesmo host/namespace de rede que o OpenClaw. Defina umcommands.callbackUrlexplicitamente alcançável externamente em vez disso.
Buttons issues
- 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. - Botões renderizam, mas cliques não fazem nada: verifique se
AllowedUntrustedInternalConnectionsna configuração do servidor Mattermost inclui127.0.0.1 localhost, e seEnablePostActionIntegrationétrueem ServiceSettings. - Botões retornam 404 ao clicar: o
iddo botão provavelmente contém hifens ou underscores. O roteador de ações do Mattermost quebra com IDs não alfanuméricos. Use apenas[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). Veja a seção de HMAC acima. - Logs do Gateway mostram
missing _token in context: o campo_tokennão está no contexto do botão. Verifique se ele está incluído ao criar o payload de integração. - A confirmação mostra o ID bruto em vez do nome do botão:
context.action_idnão corresponde aoiddo botão. Defina ambos para o mesmo valor sanitizado. - O agente não sabe sobre botões: adicione
capabilities: ["inlineButtons"]à configuração do canal Mattermost.
Relacionado
- Roteamento de canais - roteamento de sessões 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 de DM e fluxo de pareamento
- Segurança - modelo de acesso e hardening