Mattermost
REST v4 轮询和 WebSocket 客户端。默认情况下,机器人每 3 秒轮询一次频道以获取新帖子;设置 listen_mode = "websocket" 可通过持久 WebSocket 连接实现近实时事件推送。无论采用哪种监听模式,回复帖子始终通过 POST /api/v4/posts 发送。
谁可以与代理通信
入站发送方会根据为绑定代理解析出的对等集合进行限制,该集合来自代理所属的 peer_groups 配置。匹配时会去除开头的 @,并对通道的原生发送方标识符执行不区分大小写的比对。空集合会拒绝所有人;包含 "*" 的集合会接受所有人;否则仅接受列出的外部对等方(以及对等代理)。这与网关配对(gateway.require_pairing)不同,后者验证的是 HTTP/WebSocket 客户端,而非聊天通道的发送方。
mattermost 的对等组将 channel 设置为 mattermost,在 external_peers 中列出允许的发送者(对于 mattermost,使用 Mattermost 用户 UUID(而非用户名);["*"] 接受任何人),可选择性地命名对等 agents 以进行跨代理调度、一个 ignore 屏蔽列表,以及一个 output_modality(mirror、voice 或 text)。字段参考请参见 Peer Groups。
在何处设置:
如需将特定用户加入允许列表,请从 System Console → User Management 中复制其用户 ID。Mattermost 匹配的是用户 UUID,而非用户名,并且不会在接收消息时解析用户名。
快速开始
通过下面的某个界面配置 Mattermost 频道(url 加上 bot_token 密钥,参见身份验证)。仅此一项即可为你提供:
- 自动发现机器人在其所属的每个团队中可读取的所有频道。
- DM 和群组 DM 频道会与团队频道一起自动发现并轮询。
- 新私信(在机器人启动后创建)将在下一次 60 秒发现刷新时被识别。
mention_only在私信和群组私信频道中被忽略(因此一对一对话无需 @ 提及机器人)。
如需限制此机器人,可使用 channel_ids、team_ids 或 discover_dms 进行范围缩小。
配置
bot_token 和 password 是机密信息:
channels.mattermost.<alias>.bot_token是一项机密信息。 以加密形式存储,绝不会以明文形式出现在config.toml中。请通过以下方式之一进行设置,这些方式会在写入时加密:
网关仪表板
打开 /config/channels/mattermost 并在其中设置 channels.mattermost.<alias>.bot_token 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.bot_token 字段(输入内容会被遮蔽)。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.bot_token # 提示输入掩码内容,以加密形式存储
字段参考
bot_token 🔑
Mattermost 机器人访问令牌。未设置时,该通道将回退到使用 login_id + password 的登录流程。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.bot_token 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.bot_token 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.bot_token # 掩码输入,加密存储
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__bot_token=
channel_ids
用于限制机器人的频道 ID。留空或 ["*"] = 自动发现机器人可读取的每个频道(公开、私密、私信、群组私信)并轮询所有频道。指定明确的 ID 将禁用自动发现,并将机器人锁定到列出的频道。从旧版 channel_id 单数字段迁移而来。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.channel_ids 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.channel_ids 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.channel_ids <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__channel_ids=
discover_dms
当为 true(默认值)时,自动发现包括私信(type=D)和群组私信(type=G)频道。设为 false 可将该机器人限制为仅访问公开和私有团队频道。当 channel_ids 中列出了明确的 ID 时,此项无效。在调用处通过 discover_dms.unwrap_or(true) 默认为 true。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost,并设置 channels.mattermost.<alias>.discover_dms 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.discover_dms 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.discover_dms <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__discover_dms=
excluded_tools
从此通道的工具规范中排除的工具。设置后,通过此通道响应时不会向模型公开这些工具。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.excluded_tools 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.excluded_tools 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.excluded_tools <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__excluded_tools=
interrupt_on_new_message
为 true 时,来自同一频道中同一发送者的较新 Mattermost 消息会取消正在处理的请求,并在保留历史记录的情况下重新开始响应。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.interrupt_on_new_message 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.interrupt_on_new_message 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.interrupt_on_new_message <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__interrupt_on_new_message=
listen_mode
监听模式:"polling"(REST API 每 3 秒一次,默认)或 "websocket"(到 /api/v4/websocket 的持久 WebSocket 连接,用于近实时事件传递)。WebSocket 模式可降低服务器负载并更快传递事件,但需要支持 WebSocket 的 Mattermost 服务器 (v4.0+)。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.listen_mode 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.listen_mode 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.listen_mode <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__listen_mode=
login_id
用于密码登录流程的登录 ID(邮箱或用户名)。仅在未设置 bot_token 时使用;login_id 和 password 必须同时设置。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.login_id 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.login_id 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.login_id <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__login_id=
mention_only
为 true 时,仅回应 @ 提及该机器人的消息。频道中的其他消息将被静默忽略。私信和群组私信频道始终绕过此过滤器:一对一(或小群组)的直接对话没有需要过滤的环境噪音,因此每条消息都被视为是发给机器人的。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.mention_only 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.mention_only 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.mention_only <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__mention_only=
password 🔑
登录流程的账户密码。仅在未设置 bot_token 时使用;login_id 和 password 必须同时设置。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.password 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.password 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.password # 掩码输入,加密存储
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__password=
proxy_url
每个通道的代理 URL(http、https、socks5、socks5h)。仅为此通道覆盖全局 [proxy] 设置。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.proxy_url 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.proxy_url 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.proxy_url <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__proxy_url=
reply_min_interval_secs
每个(通道,接收方)出站节流下限(秒)。范围:0..=REPLY_MIN_INTERVAL_MAX_SECS(0 表示禁用)。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.reply_min_interval_secs 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.reply_min_interval_secs 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.reply_min_interval_secs <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__reply_min_interval_secs=
reply_queue_depth_max
每个(channel, recipient)出站节流队列的深度。取值范围:0..=REPLY_QUEUE_DEPTH_CEILING。当 reply_min_interval_secs > 0 且此值为 0 时,节流封装器会使用 DEFAULT_REPLY_QUEUE_DEPTH(16)作为替代值。当队列已满时,最新的发送会被丢弃,并记录一条 WARN 日志。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.reply_queue_depth_max 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.reply_queue_depth_max 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.reply_queue_depth_max <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__reply_queue_depth_max=
team_ids
限制自动发现范围的团队 ID。留空 = 在机器人所属的每个团队中进行发现。非空 = 仅发现 team_id 在此列表中的公开/私有频道。私信和群组私信(没有所属团队)则由 discover_dms 控制。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.team_ids 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.team_ids 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.team_ids <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__team_ids=
thread_replies
为 true 时(默认),回复以原帖为线程展开。为 false 时,回复将发送到频道根目录。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.thread_replies 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.thread_replies 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.thread_replies <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__thread_replies=
url*
Mattermost 服务器 URL(例如 "https://mattermost.example.com")。
将它放置在任何表面上:
网关仪表板
打开 /config/channels/mattermost 并设置 channels.mattermost.<alias>.url 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.url 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.url <value>
环境变量
导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:
export ZEROCLAW_channels__mattermost__<alias>__url=
频道发现
有两种作用域模式。
- 自动发现(当
channel_ids为空或为["*"]时)。在启动时以及之后每隔 60 秒,机器人会调用GET /api/v4/users/me/channels,按team_ids(公共/私有频道)和discover_dms(私信/群组私信)过滤结果,并轮询每个保留下来的频道。运行期间新建的私信会在下一次刷新时出现。 - 显式模式(当
channel_ids是一个非空的 ID 列表,且不为*时)。启动时,机器人会为每个条目调用GET /api/v4/channels/{id}以获取其type(以便识别哪些是用于mention_only绕过的私信),然后持续轮询这些指定的频道。不会进行周期性的重新发现。
在两种模式下,每个频道都有自己的 since 游标:机器人会跟踪每个频道已处理的最大 create_at,并在下一次 GET /api/v4/channels/{id}/posts 调用中将其作为 since=<ms> 传入。游标不会在频道之间泄漏,因此低速频道不会抑制繁忙频道中的帖子。
WebSocket 模式
将 listen_mode = "websocket" 设置为从 REST 轮询切换到持久化 WebSocket 连接(wss://<server>/api/v4/websocket)。WebSocket 模式:
- 以近实时方式推送新帖子(无需 3 秒轮询延迟)。
- 降低 Mattermost 服务器的 HTTP 负载(一个连接,而非每 3 秒进行 N 次轮询)。
- 将失败的会话返回给共享通道管理器,由其使用配置的
reliability.channel_initial_backoff_secs和reliability.channel_max_backoff_secs值以有界指数退避方式重新连接。 - 需要 Mattermost v4.0+(
/api/v4/websocket端点)。
频道发现、mention_only、thread_replies、音频转录和对等组授权在两种模式下的工作方式完全相同。
权衡取舍:
- WebSocket 模式必须维持一个持久的 TCP+TLS 连接。
- 在重连窗口期间,发布到频道的消息可能会被漏掉,因为此监听器尚未请求 Mattermost 连接恢复/重放。轮询会通过
since=游标补上遗漏。 - 轮询模式对短暂的网络中断更具弹性,但代价是持续的 HTTP 流量。
如需回滚,请设置 listen_mode = "polling"(或删除该字段;polling 为默认值)。
私信
Mattermost 按 type 对频道进行分类:
type | 含义 |
|---|---|
O | 公共团队频道。 |
P | 私人团队频道。 |
G | 群组私信(多人私信)。 |
D | 私信(一对一)。 |
G 和 D 在 ZeroClaw 中被同等对待:两者都不携带 team_id,都受 discover_dms 控制,且都隐式绕过 mention_only(私密会话不存在需要过滤的环境噪声)。
DM 发送者的授权仍通过频道的对等组解析器处理,与其他任何频道相同。discover_dms 只是一个调节开关,而非安全边界;对等组决定谁有权向该智能体发送消息。
线程
- 入站消息位于现有话题内(已设置
root_id)→ 无论thread_replies如何设置,回复始终发送到该话题中。 - 入站帖子为顶层帖子且
thread_replies = true(默认)→ 回复将开启一个以该入站帖子为根的话题串。 - 入站帖子为顶层消息且
thread_replies = false→ 回复将发布到频道根级别。
上下文管理
当 Mattermost 中的对话发生在某个话题串(thread)中时,该话题串就是一个独立的对话。ZeroClaw 会为每个话题串派生出不同的会话键(session key),因此每个话题串都拥有各自独立的上下文窗口和历史记录:一个话题串中的消息绝不会渗入另一个话题串,代理也不会看到同级话题串中较早的对话轮次。在 Mattermost 中,这一行为由 thread_replies 控制:当其开启时,顶层消息会开启一个话题串,且每个话题串都是一个独立的对话;当其关闭时,回复会发布在频道根部,历史记录则按发送者和目标(target)而非按话题串进行索引。
- 隔离正是关键所在。 每个线程的上下文都是自包含的:它不会泄漏到线程之外,线程之外的任何内容也不会泄漏进来。并行线程持有各自独立的对话状态,因此互不相关的任务永远不会相互干扰。
- 长线程会增大上下文。 线程在保持活动状态期间会累积历史记录,因此与其他长对话一样,过长的线程最终会填满模型的上下文窗口。开始新线程即可重置。
- 进行中的工作以线程为单位进行隔离。 在某个线程中发送新消息不会取消另一个线程中进行中的响应;每个线程的任务都是独立的。
为任意 surface 设置线程行为:
网关仪表板
打开 /config/channels/mattermost 并切换 channels.mattermost.<alias>.thread_replies 字段。
zerocode
在 Config 窗格中,设置 channels.mattermost.<alias>.thread_replies 字段。
zeroclaw config
zeroclaw config set channels.mattermost.<alias>.thread_replies true 线程回复开启
zeroclaw config set channels.mattermost.<alias>.thread_replies false # 频道根目录的回复
身份验证
两条路径:
- Bot 令牌(推荐)。在 System Console → Integrations → Bot Accounts 中创建,复制访问令牌,并将其存储在
bot_token中。令牌在密码轮换后依然有效,且更易于吊销。 - 登录流程。设置
login_id(邮箱或用户名)和password。机器人启动时会调用POST /api/v4/users/login,并将返回的会话令牌缓存在内存中。不会持久化到磁盘。
同时设置时,bot_token 优先。
语音消息
当配置了 [transcription] 且入站帖子包含音频附件(MIME 类型为 audio/* 或扩展名为 ogg/mp3/m4a/wav/opus/flac)且无文本正文时,系统将通过 GET /api/v4/files/{file_id} 下载该音频,并路由至已配置的转录提供程序。转录结果以 [Voice] 为前缀,并作为消息内容。大于 25 MB 或超过 transcription.max_duration_secs 的附件将被丢弃并记录 WARN 日志。
设置
- 在 Mattermost 中:系统控制台 → 集成 → 机器人账号 → 添加机器人账号。设置用户名(例如
zeroclaw),并启用你需要的权限范围。 - 复制访问令牌。将其存储在 ZeroClaw 密钥后端中。
- 邀请机器人加入你希望它在其中运行的任意团队。对于私信自动发现功能,无需额外邀请:任何用户都可以私信该机器人。
- 通过网关、zerocode 或
zeroclaw config set创建引用该令牌的mattermost.<alias>频道。 - 通过
channels = ["mattermost.<alias>"]将该通道绑定到[agents.<alias>]中的代理。
操作说明
- 轮询频率为每个频道 3 秒。发现 N 个频道意味着每 3 秒对 Mattermost 服务器发起 N 次 HTTP 调用。自托管默认配置可轻松应对;如果你使用的是速率限制较严格的共享云租户,建议通过
channel_ids或team_ids缩小范围。 - Bot 身份通过
GET /api/v4/users/me获取一次,并在进程生命周期内缓存。用户名变更需要重启。 - 密码登录流程的会话令牌仅保存在内存中。重启后会重新登录。