Mattermost
Cliente REST v4 de sondeo y WebSocket. Por defecto, el bot sondea los canales cada 3 segundos en busca de nuevas publicaciones; establece listen_mode = "websocket" para la entrega de eventos en tiempo casi real a través de una conexión WebSocket persistente. Las publicaciones de respuesta siempre se envían mediante POST /api/v4/posts independientemente del modo de escucha.
Quién puede hablar con el agente
Los remitentes entrantes se filtran contra el conjunto de pares resuelto para el agente vinculado, obtenido de la configuración peer_groups a la que pertenece el agente. La coincidencia elimina el @ inicial y no distingue mayúsculas de minúsculas frente al identificador nativo de remitente del canal. Un conjunto vacío deniega a todos; un conjunto que contiene "*" acepta a cualquiera; en caso contrario, solo se aceptan los pares externos listados (y los agentes pares). Esto es independiente del emparejamiento de la puerta de enlace (gateway.require_pairing), que autentica clientes HTTP/WebSocket, no remitentes de canales de chat.
Un grupo de pares para mattermost establece channel en mattermost, enumera los remitentes permitidos en external_peers (para mattermost, el UUID de usuario de Mattermost (no un nombre de usuario); ["*"] acepta a cualquiera), opcionalmente nombra agents pares para el despacho entre agentes, una lista de bloqueo ignore y un output_modality (mirror, voice o text). Consulta Grupos de Pares para la referencia de campos.
Dónde configurar esto:
Panel de control del gateway
Abra /config/peer_groups en el panel de control web.
zerocode
En el panel Config, en Peer groups.
Para incluir en la lista de permitidos a una persona específica, copie su ID de usuario desde System Console → User Management. Mattermost compara el UUID del usuario, no un nombre de usuario, y no resuelve nombres de usuario en el momento de recibir el mensaje.
Inicio rápido
Configura un canal de Mattermost (url más un secreto bot_token, consulta Autenticación) a través de una de las superficies a continuación. Solo con eso obtienes:
- Detección automática de cada canal que el bot puede leer en todos los equipos a los que pertenece.
- Los canales de MD y de MD grupales se descubren automáticamente y se sondean junto con los canales del equipo.
- Los nuevos mensajes directos (creados después de que el bot se inicia) se detectan en la siguiente actualización de descubrimiento de 60 segundos.
mention_onlyse omite dentro de los canales de DM y group-DM (para que las conversaciones 1:1 no necesiten que se mencione al bot con @).
Para restringir el bot, acote con channel_ids, team_ids o discover_dms.
Configuración
bot_token y password son secretos:
channels.mattermost.<alias>.bot_tokenes un secreto. Se almacena cifrado, nunca en texto plano enconfig.toml. Configúralo mediante una de estas opciones, que cifran al escribir:
Panel de control del gateway
Abre /config/channels/mattermost y configura allí el campo channels.mattermost.<alias>.bot_token.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.bot_token (la entrada está enmascarada).
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.bot_token # solicita entrada enmascarada, almacena cifrado
Referencia de campos
bot_token 🔑
Token de acceso del bot de Mattermost. Cuando no está configurado, el canal recurre al flujo de inicio de sesión usando login_id + password.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.bot_token.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.bot_token.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.bot_token # entrada enmascarada, almacenada cifrada
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__bot_token=
channel_ids
IDs de canales a los que restringir el bot. Vacío o ["*"] = descubrir automáticamente todos los canales que el bot puede leer (públicos, privados, DMs, DMs grupales) y sondearlos todos. Los IDs explícitos desactivan el descubrimiento y fijan el bot únicamente a los canales listados. Migrado desde el campo singular heredado channel_id.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.channel_ids.
zerocode
En el panel de Config, configure el campo channels.mattermost.<alias>.channel_ids.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.channel_ids <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__channel_ids=
discover_dms
Cuando es true (predeterminado), el descubrimiento automático incluye canales de DM (type=D) y de DM grupal (type=G). Establézcalo en false para restringir el bot solo a canales de equipo públicos y privados. No tiene efecto cuando channel_ids enumera IDs explícitos. El valor predeterminado es true en el punto de llamada mediante discover_dms.unwrap_or(true).
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.discover_dms.
zerocode
En el panel Config, configure el campo channels.mattermost.<alias>.discover_dms.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.discover_dms <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__discover_dms=
excluded_tools
Herramientas excluidas de la especificación de herramientas de este canal. Cuando se establece, estas herramientas no se exponen al modelo al responder a través de este canal.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.excluded_tools.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.excluded_tools.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.excluded_tools <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__excluded_tools=
interrupt_on_new_message
Cuando es true, un mensaje de Mattermost más reciente del mismo remitente en el mismo canal cancela la solicitud en curso e inicia una respuesta nueva conservando el historial.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.interrupt_on_new_message.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.interrupt_on_new_message.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.interrupt_on_new_message <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__interrupt_on_new_message=
listen_mode
Modo de escucha: "polling" (API REST cada 3s, predeterminado) o "websocket" (conexión WebSocket persistente a /api/v4/websocket para entrega de eventos en tiempo casi real). El modo WebSocket reduce la carga del servidor y entrega eventos más rápido, pero requiere un servidor Mattermost compatible con WebSocket (v4.0+).
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y establece el campo channels.mattermost.<alias>.listen_mode.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.listen_mode.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.listen_mode <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__listen_mode=
login_id
ID de inicio de sesión (correo electrónico o nombre de usuario) para el flujo de inicio de sesión con contraseña. Se usa solo cuando bot_token no está configurado; tanto login_id como password deben configurarse juntos.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.login_id.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.login_id.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.login_id <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__login_id=
mention_only
Cuando es true, solo responde a los mensajes que @-mencionan al bot. Los demás mensajes del canal se ignoran silenciosamente. Los canales de DM y DM grupales siempre omiten este filtro: una conversación directa 1:1 (o de grupo pequeño) no tiene ruido ambiental que filtrar, por lo que cada mensaje se trata como dirigido al bot.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.mention_only.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.mention_only.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.mention_only <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__mention_only=
password 🔑
Contraseña de la cuenta para el flujo de inicio de sesión. Se usa solo cuando bot_token no está configurado; tanto login_id como password deben configurarse juntos.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.password.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.password.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.password # entrada enmascarada, almacenada cifrada
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__password=
proxy_url
URL de proxy por canal (http, https, socks5, socks5h). Anula la configuración global [proxy] solo para este canal.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.proxy_url.
zerocode
En el panel Config, configura el campo channels.mattermost.<alias>.proxy_url.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.proxy_url <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__proxy_url=
reply_min_interval_secs
Límite mínimo de ritmo de salida por (canal, destinatario) en segundos. Rango: 0..=REPLY_MIN_INTERVAL_MAX_SECS (0 lo desactiva).
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.reply_min_interval_secs.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.reply_min_interval_secs.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.reply_min_interval_secs <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__reply_min_interval_secs=
reply_queue_depth_max
Profundidad de la cola de regulación de salida por (canal, destinatario). Rango: 0..=REPLY_QUEUE_DEPTH_CEILING. Cuando reply_min_interval_secs > 0 y este valor es 0, el envoltorio de regulación sustituye DEFAULT_REPLY_QUEUE_DEPTH (16). Cuando la cola está llena, se descarta el envío más reciente y se registra un WARN.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.reply_queue_depth_max.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.reply_queue_depth_max.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.reply_queue_depth_max <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__reply_queue_depth_max=
team_ids
IDs de equipo para restringir el descubrimiento automático. Vacío = descubrir en todos los equipos a los que pertenece el bot. No vacío = solo descubrir canales públicos/privados cuyo team_id esté en esta lista. Los DMs y DMs grupales (que no tienen equipo) se rigen por discover_dms en su lugar.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.team_ids.
zerocode
En el panel Config, configure el campo channels.mattermost.<alias>.team_ids.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.team_ids <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__team_ids=
thread_replies
Cuando es true (predeterminado), las respuestas se agrupan en hilo en la publicación original. Cuando es false, las respuestas van a la raíz del canal.
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.thread_replies.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.thread_replies.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.thread_replies <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__thread_replies=
url*
URL del servidor de Mattermost (p. ej., "https://mattermost.example.com").
Colócalo sobre cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y configura el campo channels.mattermost.<alias>.url.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.url.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.url <value>
Variable de entorno
Exporte la anulación (shells POSIX; colóquelo en ~/.bashrc, ~/.zshrc, .env o un Dockerfile). Reemplace <alias> con el alias literal:
export ZEROCLAW_channels__mattermost__<alias>__url=
Descubrimiento de canales
Hay dos modos de alcance.
- Detección automática (cuando
channel_idsestá vacío o es["*"]). Al iniciar y cada 60 segundos a partir de entonces, el bot llama aGET /api/v4/users/me/channels, filtra el resultado porteam_ids(canales públicos/privados) ydiscover_dms(DMs/DMs grupales), y sondea cada canal restante. Los nuevos DMs creados durante la ejecución aparecen en la siguiente actualización. - Explícito (cuando
channel_idses una lista no vacía de IDs distintos de*). Al iniciarse, el bot llama aGET /api/v4/channels/{id}para cada entrada con el fin de conocer sutype(de modo que sepa cuáles son DMs para la excepción demention_only), y luego sondea exactamente esos canales de forma indefinida. Sin redescubrimiento periódico.
En ambos modos cada canal tiene su propio cursor since: el bot rastrea el create_at más alto que ha procesado por canal y lo pasa como since=<ms> en la siguiente llamada GET /api/v4/channels/{id}/posts. Los cursores no se filtran entre canales, por lo que un canal de movimiento lento no suprime las publicaciones en uno activo.
Modo WebSocket
Establece listen_mode = "websocket" para cambiar del sondeo REST a una conexión WebSocket persistente (wss://<server>/api/v4/websocket). El modo WebSocket:
- Entrega nuevas publicaciones en tiempo casi real (sin retraso de sondeo de 3 segundos).
- Reduce la carga HTTP en el servidor Mattermost (una conexión frente a N sondeos/3s).
- Devuelve las sesiones fallidas al supervisor de canales compartido, que se reconecta mediante un retroceso exponencial acotado usando los valores configurados de
reliability.channel_initial_backoff_secsyreliability.channel_max_backoff_secs. - Requiere Mattermost v4.0+ (el endpoint
/api/v4/websocket).
El descubrimiento de canales, mention_only, thread_replies, la transcripción de audio y la autorización de grupos de pares funcionan de manera idéntica en ambos modos.
Compromisos:
- El modo WebSocket debe mantener una conexión TCP+TLS persistente.
- Durante una ventana de reconexión, pueden perderse mensajes publicados en un canal porque este listener aún no solicita la reanudación/repetición de la conexión de Mattermost. El sondeo se pone al día mediante cursores
since=. - El modo de sondeo es más resistente a las interrupciones transitorias de red, a costa de un tráfico HTTP constante.
Para revertir, establece listen_mode = "polling" (o elimina el campo; polling es el valor predeterminado).
Mensajes directos
Mattermost clasifica los canales por type:
type | significado |
|---|---|
O | Canal de equipo público. |
P | Canal privado del equipo. |
G | Mensaje directo de grupo (MD multiusuario). |
D | Mensaje directo (1:1). |
G y D reciben el mismo tratamiento por parte de ZeroClaw: ninguno de los dos lleva team_id, ambos están controlados por discover_dms y ambos omiten implícitamente mention_only (una conversación privada no tiene ruido ambiental contra el que filtrar).
La autorización para los remitentes de DM sigue pasando por el resolutor de grupos de pares del canal, igual que cualquier otro canal. discover_dms es un ajuste, no un límite de seguridad; los grupos de pares deciden quién está autorizado a dirigirse al agente.
Hilo
- La publicación entrante está dentro de un hilo existente (
root_idestá definido) → la respuesta siempre se ubica en ese hilo, independientemente dethread_replies. - La publicación entrante es de nivel superior y
thread_replies = true(predeterminado) → la respuesta abre un hilo basado en la publicación entrante. - La publicación entrante es de nivel superior y
thread_replies = false→ la respuesta se publica en la raíz del canal.
Gestión de contexto
Cuando una conversación de Mattermost ocurre en un hilo, ese hilo es su propia conversación. ZeroClaw deriva una clave de sesión distinta por hilo, de modo que cada hilo tiene una ventana de contexto y un historial independientes: los mensajes de un hilo nunca se filtran a otro, y el agente no ve los turnos anteriores de un hilo hermano. En Mattermost esto se controla con thread_replies: cuando está activado, los mensajes de nivel superior abren un hilo y cada hilo es una conversación separada; cuando está desactivado, las respuestas se publican en la raíz del canal y el historial se indexa por remitente y destino en lugar de por hilo.
- El aislamiento es el objetivo. El contexto de cada hilo es autónomo: no se filtra fuera del hilo, y nada de fuera del hilo se filtra hacia dentro. Los hilos paralelos mantienen estados conversacionales separados, por lo que las tareas no relacionadas nunca se contaminan entre sí.
- Los hilos largos hacen crecer el contexto. Un hilo acumula historial mientras permanece activo, por lo que un hilo muy largo eventualmente llena la ventana de contexto del modelo como cualquier otra conversación larga. Inicia un nuevo hilo para restablecer.
- El trabajo en curso está delimitado por hilo. Un mensaje nuevo en un hilo no cancela una respuesta en curso en otro; la tarea de cada hilo es independiente.
Establece el comportamiento del hilo en cualquier superficie:
Panel de control del gateway
Abre /config/channels/mattermost y activa o desactiva el campo channels.mattermost.<alias>.thread_replies.
zerocode
En el panel Config, establece el campo channels.mattermost.<alias>.thread_replies.
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.thread_replies true # respuestas de hilo activadas
zeroclaw config set channels.mattermost.<alias>.thread_replies false # de respuestas en la raíz del canal
Autenticación
Dos rutas:
- Token de bot (recomendado). Créalo en System Console → Integrations → Bot Accounts, copia el token de acceso y guárdalo en
bot_token. Los tokens sobreviven a los cambios de contraseña y son más fáciles de revocar. - Flujo de inicio de sesión. Configura
login_id(email o nombre de usuario) ypassword. El bot llama aPOST /api/v4/users/loginal iniciar y almacena en caché el token de sesión devuelto en memoria. Sin persistencia en disco.
bot_token tiene prioridad cuando ambos están configurados.
Mensajes de voz
Cuando [transcription] está configurado y una publicación entrante tiene un adjunto de audio (tipo MIME audio/* o extensión ogg/mp3/m4a/wav/opus/flac) sin cuerpo de texto, el audio se descarga mediante GET /api/v4/files/{file_id} y se enruta a través del proveedor de transcripción configurado. La transcripción se prefija con [Voice] y se convierte en el contenido del mensaje. Los adjuntos de más de 25 MB o con una duración superior a transcription.max_duration_secs se descartan con una advertencia WARN.
Configuración
- En Mattermost: System Console → Integrations → Bot Accounts → Add Bot Account. Define un nombre de usuario (p. ej.
zeroclaw), habilita los scopes que quieras. - Copia el token de acceso. Almacénalo en tu backend de secretos de ZeroClaw.
- Invita al bot a los equipos en los que quieras que esté activo. Para la detección automática de mensajes directos, no se necesitan invitaciones adicionales: cualquier usuario puede enviar un mensaje directo al bot.
- Crea el canal
mattermost.<alias>haciendo referencia al token a través del gateway, zerocode ozeroclaw config set. - Vincula el canal a un agente en
[agents.<alias>]mediantechannels = ["mattermost.<alias>"].
Notas operativas
- La cadencia de sondeo es de 3 segundos por canal. N canales descubiertos = N llamadas HTTP cada 3 segundos contra el servidor de Mattermost. Las configuraciones predeterminadas autoalojadas manejan esto fácilmente; si estás en un tenant de nube compartido con límites de tasa estrictos, considera acotar el alcance con
channel_idsoteam_ids. - La identidad del bot se obtiene una vez mediante
GET /api/v4/users/mey se almacena en caché durante toda la vida del proceso. Los cambios de nombre de usuario requieren reiniciar. - El token de sesión del flujo de inicio de sesión con contraseña solo se mantiene en memoria. Un reinicio vuelve a iniciar sesión.