Developer and self-hosted
Mattermost
Estado: plugin descargable (token de bot + eventos WebSocket). Se admiten canales, grupos y MD. Mattermost es una plataforma de mensajería de equipo autohospedable; consulta el sitio oficial en mattermost.com para ver detalles del producto y descargas.
Instalar
Instala Mattermost antes de configurar el canal:
registro npm
openclaw plugins install @openclaw/mattermost
Checkout local
openclaw plugins install ./path/to/local/mattermost-plugin
Detalles: Plugins
Configuración rápida
Asegura que el plugin esté disponible
Las versiones empaquetadas actuales de OpenClaw ya lo incluyen. Las instalaciones antiguas/personalizadas pueden añadirlo manualmente con los comandos anteriores.
Crea un bot de Mattermost
Crea una cuenta de bot de Mattermost y copia el token del bot.
Copia la URL base
Copia la URL base de Mattermost (p. ej., https://chat.example.com).
Configura OpenClaw e inicia el gateway
Configuración mínima:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
Comandos slash nativos
Los comandos slash nativos son opcionales. Cuando están habilitados, OpenClaw registra comandos slash oc_* mediante la API de Mattermost y recibe POSTs de callback en el servidor HTTP del 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 comportamiento
native: "auto"se deshabilita de forma predeterminada para Mattermost. Establecenative: truepara habilitarlo.- Si se omite
callbackUrl, OpenClaw deriva una desde el host/puerto del gateway +callbackPath. - Para configuraciones de varias cuentas,
commandspuede definirse en el nivel superior o bajochannels.mattermost.accounts.<id>.commands(los valores de la cuenta reemplazan los campos de nivel superior). - Los callbacks de comandos se validan con los tokens por comando devueltos por Mattermost cuando OpenClaw registra comandos
oc_*. - OpenClaw actualiza el registro actual de comandos de Mattermost antes de aceptar cada callback, de modo que los tokens obsoletos de comandos slash eliminados o regenerados dejan de aceptarse sin reiniciar el gateway.
- La validación del callback falla de forma cerrada si la API de Mattermost no puede confirmar que el comando sigue siendo actual; las validaciones fallidas se almacenan brevemente en caché, las búsquedas concurrentes se fusionan y los inicios de búsquedas nuevas se limitan por frecuencia por comando para acotar la presión de replay.
- Los callbacks slash fallan de forma cerrada cuando el registro falló, el inicio fue parcial o el token del callback no coincide con el token registrado del comando resuelto (un token válido para un comando no puede llegar a la validación upstream para otro comando).
Requisito de accesibilidad
El endpoint de callback debe ser accesible desde el servidor Mattermost.
- No establezcas
callbackUrlenlocalhosta menos que Mattermost se ejecute en el mismo host/espacio de nombres de red que OpenClaw. - No establezcas
callbackUrlen tu URL base de Mattermost a menos que esa URL haga proxy inverso de/api/channels/mattermost/commandhacia OpenClaw. - Una comprobación rápida es
curl https://<gateway-host>/api/channels/mattermost/command; un GET debe devolver405 Method Not Alloweddesde OpenClaw, no404.
Lista de permitidos de egreso de Mattermost
Si tu callback apunta a direcciones privadas/tailnet/internas, configura ServiceSettings.AllowedUntrustedInternalConnections de Mattermost para incluir el host/dominio del callback.
Usa entradas de host/dominio, no URLs completas.
- Correcto:
gateway.tailnet-name.ts.net - Incorrecto:
https://gateway.tailnet-name.ts.net
Variables de entorno (cuenta predeterminada)
Configúralas en el host del gateway si prefieres variables de entorno:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
Modos de chat
Mattermost responde a los MD automáticamente. El comportamiento de canal lo controla chatmode:
oncall (predeterminado)
Responde solo cuando se menciona con @ en canales.
onmessage
Responde a cada mensaje de canal.
onchar
Responde cuando un mensaje empieza con un prefijo disparador.
Ejemplo de configuración:
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
Notas:
oncharsigue respondiendo a menciones @ explícitas.channels.mattermost.requireMentionse respeta para configuraciones heredadas, pero se prefierechatmode.
Hilos y sesiones
Usa channels.mattermost.replyToMode para controlar si las respuestas de canales y grupos permanecen en el canal principal o inician un hilo bajo la publicación que las disparó.
off(predeterminado): responde en un hilo solo cuando la publicación entrante ya está en uno.first: para publicaciones de nivel superior de canal/grupo, inicia un hilo bajo esa publicación y enruta la conversación a una sesión con ámbito de hilo.all: el mismo comportamiento quefirstpara Mattermost hoy.- Los mensajes directos ignoran este ajuste y permanecen sin hilo.
Ejemplo de configuración:
{
channels: {
mattermost: {
replyToMode: "all",
},
},
}
Notas:
- Las sesiones con ámbito de hilo usan el id de la publicación disparadora como raíz del hilo.
firstyallson actualmente equivalentes porque, una vez que Mattermost tiene una raíz de hilo, los fragmentos de seguimiento y los medios continúan en ese mismo hilo.
Control de acceso (MD)
- Predeterminado:
channels.mattermost.dmPolicy = "pairing"(los remitentes desconocidos reciben un código de emparejamiento). - Aprueba mediante:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- MD públicos:
channels.mattermost.dmPolicy="open"máschannels.mattermost.allowFrom=["*"].
Canales (grupos)
- Predeterminado:
channels.mattermost.groupPolicy = "allowlist"(controlado por mención). - Permite remitentes con
channels.mattermost.groupAllowFrom(se recomiendan IDs de usuario). - Las anulaciones de mención por canal están bajo
channels.mattermost.groups.<channelId>.requireMentionochannels.mattermost.groups["*"].requireMentionpara un valor predeterminado. - La coincidencia de
@usernamees mutable y solo se habilita cuandochannels.mattermost.dangerouslyAllowNameMatching: true. - Canales abiertos:
channels.mattermost.groupPolicy="open"(controlados por mención). - Nota de runtime: si falta por completo
channels.mattermost, el runtime recurre agroupPolicy="allowlist"para las comprobaciones de grupo (aunquechannels.defaults.groupPolicyesté definido).
Ejemplo:
{
channels: {
mattermost: {
groupPolicy: "open",
groups: {
"*": { requireMention: true },
"team-channel-id": { requireMention: false },
},
},
},
}
Destinos para entrega saliente
Usa estos formatos de destino con openclaw message send o cron/webhooks:
channel:<id>para un canaluser:<id>para un MD@usernamepara un MD (resuelto mediante la API de Mattermost)
Reintento de canal de MD
Cuando OpenClaw envía a un destino de MD de Mattermost y primero necesita resolver el canal directo, reintenta de forma predeterminada los fallos transitorios de creación de canal directo.
Usa channels.mattermost.dmChannelRetry para ajustar ese comportamiento globalmente para el plugin de Mattermost, o channels.mattermost.accounts.<id>.dmChannelRetry para una cuenta.
{
channels: {
mattermost: {
dmChannelRetry: {
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 10000,
timeoutMs: 30000,
},
},
},
}
Notas:
- Esto se aplica solo a la creación de canales de MD (
/api/v4/channels/direct), no a cada llamada a la API de Mattermost. - Los reintentos se aplican a fallos transitorios como límites de frecuencia, respuestas 5xx y errores de red o timeout.
- Los errores de cliente 4xx distintos de
429se tratan como permanentes y no se reintentan.
Streaming de vista previa
Mattermost transmite el razonamiento, la actividad de herramientas y el texto parcial de la respuesta en una única publicación de vista previa de borrador que se finaliza en su lugar cuando la respuesta final es segura para enviar. La vista previa se actualiza en el mismo id de publicación en lugar de saturar el canal con mensajes por fragmento. Los finales de medios/error cancelan las ediciones de vista previa pendientes y usan la entrega normal en lugar de vaciar una publicación de vista previa descartable.
Habilítalo mediante channels.mattermost.streaming:
{
channels: {
mattermost: {
streaming: "partial", // off | partial | block | progress
},
},
}
Modos de streaming
partiales la opción habitual: una publicación de vista previa que se edita a medida que crece la respuesta y luego se finaliza con la respuesta completa.blockusa fragmentos de borrador de estilo append dentro de la publicación de vista previa.progressmuestra una vista previa de estado mientras se genera y solo publica la respuesta final al completarse.offdeshabilita el streaming de vista previa.
Notas de comportamiento del streaming
- Si el stream no puede finalizarse en su lugar (por ejemplo, si la publicación se eliminó a mitad del stream), OpenClaw recurre a enviar una publicación final nueva para que la respuesta nunca se pierda.
- Las cargas útiles solo de razonamiento se suprimen de las publicaciones de canal, incluido el texto que llega como una cita en bloque
> Reasoning:. Establece/reasoning onpara ver el razonamiento en otras superficies; la publicación final de Mattermost conserva solo la respuesta. - Consulta Streaming para ver la matriz de asignación de canales.
Reacciones (herramienta de mensajes)
- Usa
message action=reactconchannel=mattermost. messageIdes el id de publicación de Mattermost.emojiacepta nombres comothumbsupo:+1:(los dos puntos son opcionales).- Establece
remove=true(booleano) para eliminar una reacción. - Los eventos de añadir/eliminar reacción se reenvían como eventos del sistema a la sesión de agente enrutada.
Ejemplos:
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
Configuración:
channels.mattermost.actions.reactions: habilita/deshabilita acciones de reacción (predeterminado true).- Anulación por cuenta:
channels.mattermost.accounts.<id>.actions.reactions.
Botones interactivos (herramienta de mensajes)
Envía mensajes con botones clicables. Cuando un usuario hace clic en un botón, el agente recibe la selección y puede responder.
Habilita los botones añadiendo inlineButtons a las capacidades del canal:
{
channels: {
mattermost: {
capabilities: ["inlineButtons"],
},
},
}
Usa message action=send con un parámetro buttons. Los botones son un array 2D (filas de botones):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
Campos de botón:
textstringrequiredEtiqueta visible.
callback_datastringrequiredValor enviado de vuelta al hacer clic (se usa como ID de acción).
style"default" | "primary" | "danger"Estilo del botón.
Cuando un usuario hace clic en un botón:
Buttons replaced with confirmation
Todos los botones se sustituyen por una línea de confirmación (por ejemplo, "✓ Sí seleccionado por @user").
Agent receives the selection
El agente recibe la selección como un mensaje entrante y responde.
Implementation notes
- Las devoluciones de llamada de los botones usan verificación HMAC-SHA256 (automática, no requiere configuración).
- Mattermost elimina los datos de devolución de llamada de sus respuestas de API (función de seguridad), por lo que todos los botones se eliminan al hacer clic; la eliminación parcial no es posible.
- Los ID de acción que contienen guiones o guiones bajos se sanea automáticamente (limitación de enrutamiento de Mattermost).
Config and reachability
channels.mattermost.capabilities: arreglo de cadenas de capacidad. Agrega"inlineButtons"para habilitar la descripción de la herramienta de botones en el prompt del sistema del agente.channels.mattermost.interactions.callbackBaseUrl: URL base externa opcional para devoluciones de llamada de botones (por ejemplo,https://gateway.example.com). Usa esto cuando Mattermost no pueda alcanzar el Gateway directamente en su host de enlace.- En configuraciones con varias cuentas, también puedes definir el mismo campo en
channels.mattermost.accounts.<id>.interactions.callbackBaseUrl. - Si se omite
interactions.callbackBaseUrl, OpenClaw deriva la URL de devolución de llamada a partir degateway.customBindHost+gateway.porty luego recurre ahttp://localhost:<port>. - Regla de accesibilidad: la URL de devolución de llamada del botón debe ser accesible desde el servidor Mattermost.
localhostsolo funciona cuando Mattermost y OpenClaw se ejecutan en el mismo host/espacio de nombres de red. - Si tu destino de devolución de llamada es privado/tailnet/interno, agrega su host/dominio a
ServiceSettings.AllowedUntrustedInternalConnectionsde Mattermost.
Integración directa con API (scripts externos)
Los scripts externos y Webhooks pueden publicar botones directamente mediante la API REST de Mattermost en lugar de pasar por la herramienta message del agente. Usa buildButtonAttachments() del Plugin cuando sea posible; si publicas JSON sin procesar, sigue estas reglas:
Estructura de la carga útil:
{
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
},
},
},
],
},
],
},
}
Generación de tokens HMAC
El Gateway verifica los clics de botones con HMAC-SHA256. Los scripts externos deben generar tokens que coincidan con la lógica de verificación del Gateway:
Derive the secret from the bot token
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)
Build the context object
Construye el objeto de contexto con todos los campos excepto _token.
Serialize with sorted keys
Serializa con claves ordenadas y sin espacios (el Gateway usa JSON.stringify con claves ordenadas, lo que produce salida compacta).
Sign the payload
HMAC-SHA256(key=secret, data=serializedContext)
Add the token
Agrega el resumen hexadecimal resultante como _token en el contexto.
Ejemplo en 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
json.dumpsde Python agrega espacios de forma predeterminada ({"key": "val"}). Usaseparators=(",", ":")para coincidir con la salida compacta de JavaScript ({"key":"val"}).- Firma siempre todos los campos de contexto (menos
_token). El Gateway elimina_tokeny luego firma todo lo restante. Firmar un subconjunto provoca un fallo de verificación silencioso. - Usa
sort_keys=True; el Gateway ordena las claves antes de firmar, y Mattermost puede reordenar los campos de contexto al almacenar la carga útil. - Deriva el secreto del token del bot (determinístico), no de bytes aleatorios. El secreto debe ser el mismo en el proceso que crea los botones y en el Gateway que verifica.
Adaptador de directorio
El Plugin de Mattermost incluye un adaptador de directorio que resuelve nombres de canales y usuarios mediante la API de Mattermost. Esto habilita destinos #channel-name y @username en openclaw message send y entregas por Cron/Webhook.
No se necesita configuración; el adaptador usa el token del bot de la configuración de la cuenta.
Varias cuentas
Mattermost admite varias cuentas en 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" },
},
},
},
}
Solución de problemas
No replies in channels
Asegúrate de que el bot esté en el canal y menciónalo (oncall), usa un prefijo disparador (onchar) o define chatmode: "onmessage".
Auth or multi-account errors
- Comprueba el token del bot, la URL base y si la cuenta está habilitada.
- Problemas con varias cuentas: las variables de entorno solo se aplican a la cuenta
default.
Native slash commands fail
Unauthorized: invalid command token.: OpenClaw no aceptó el token de devolución de llamada. Causas habituales:- el registro del comando slash falló o solo se completó parcialmente durante el inicio
- la devolución de llamada está llegando al Gateway/cuenta incorrectos
- Mattermost todavía tiene comandos antiguos que apuntan a un destino de devolución de llamada anterior
- el Gateway se reinició sin reactivar los comandos slash
- Si los comandos slash nativos dejan de funcionar, revisa los registros para buscar
mattermost: failed to register slash commandsomattermost: native slash commands enabled but no commands could be registered. - Si se omite
callbackUrly los registros advierten que la devolución de llamada se resolvió comohttp://127.0.0.1:18789/..., esa URL probablemente solo sea accesible cuando Mattermost se ejecuta en el mismo host/espacio de nombres de red que OpenClaw. Define en su lugar uncommands.callbackUrlexplícito que sea accesible externamente.
Buttons issues
- Los botones aparecen como cuadros blancos: puede que el agente esté enviando datos de botón con formato incorrecto. Comprueba que cada botón tenga los campos
textycallback_data. - Los botones se renderizan, pero los clics no hacen nada: verifica que
AllowedUntrustedInternalConnectionsen la configuración del servidor Mattermost incluya127.0.0.1 localhost, y queEnablePostActionIntegrationseatrueen ServiceSettings. - Los botones devuelven 404 al hacer clic: probablemente el
iddel botón contiene guiones o guiones bajos. El enrutador de acciones de Mattermost falla con ID no alfanuméricos. Usa solo[a-zA-Z0-9]. - Los registros del Gateway muestran
invalid _token: discrepancia HMAC. Comprueba que firmes todos los campos de contexto (no un subconjunto), uses claves ordenadas y JSON compacto (sin espacios). Consulta la sección HMAC anterior. - Los registros del Gateway muestran
missing _token in context: el campo_tokenno está en el contexto del botón. Asegúrate de incluirlo al crear la carga útil de integración. - La confirmación muestra un ID sin procesar en lugar del nombre del botón:
context.action_idno coincide con eliddel botón. Define ambos con el mismo valor saneado. - El agente no conoce los botones: agrega
capabilities: ["inlineButtons"]a la configuración del canal Mattermost.
Relacionado
- Enrutamiento de canales - enrutamiento de sesiones para mensajes
- Resumen de canales - todos los canales admitidos
- Grupos - comportamiento de chat grupal y control por menciones
- Emparejamiento - autenticación por DM y flujo de emparejamiento
- Seguridad - modelo de acceso y endurecimiento