新增 Mattermost 渠道完整实现,包含适配器核心、消息处理、交互回调、命令支持、安全校验、多账号管理等功能,支持机器人消息发送、交互按钮、命令注册、投票功能以及配置动态修改等特性。
220 lines
7.3 KiB
Python
220 lines
7.3 KiB
Python
from __future__ import annotations
|
||
|
||
MATTERMOST_CONFIG_SCHEMA = {
|
||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||
"type": "object",
|
||
"title": "Mattermost Channel Configuration",
|
||
"properties": {
|
||
"server_url": {
|
||
"type": "string",
|
||
"format": "uri",
|
||
"description": "Mattermost 服务器 URL",
|
||
"examples": ["https://mattermost.example.com"],
|
||
},
|
||
"bot_token": {
|
||
"type": "string",
|
||
"description": "Bot Personal Access Token",
|
||
"writeOnly": True,
|
||
},
|
||
"dm_policy": {
|
||
"type": "string",
|
||
"enum": ["open", "allowlist", "pairing", "disabled"],
|
||
"default": "open",
|
||
"description": "DM 安全策略",
|
||
},
|
||
"group_policy": {
|
||
"type": "string",
|
||
"enum": ["open", "allowlist", "disabled"],
|
||
"default": "open",
|
||
"description": "群组安全策略",
|
||
},
|
||
"allow_from": {
|
||
"type": "array",
|
||
"items": {"type": "string"},
|
||
"description": "DM 白名单(用户 ID 或 @username)",
|
||
},
|
||
"group_allow_from": {
|
||
"type": "array",
|
||
"items": {"type": "string"},
|
||
"description": "群组白名单",
|
||
},
|
||
"chatmode": {
|
||
"type": "string",
|
||
"enum": ["oncall", "onmessage", "onchar"],
|
||
"default": "onmessage",
|
||
"description": "消息响应模式",
|
||
},
|
||
"require_mention": {
|
||
"type": "boolean",
|
||
"default": True,
|
||
"description": "群组消息是否需要 @提及",
|
||
},
|
||
"onchar_prefixes": {
|
||
"type": "array",
|
||
"items": {"type": "string"},
|
||
"default": [">", "!"],
|
||
"description": "onchar 模式触发前缀",
|
||
},
|
||
"reply_to_mode": {
|
||
"type": "string",
|
||
"enum": ["off", "first", "all", "batched"],
|
||
"default": "off",
|
||
"description": "回复线程绑定模式",
|
||
},
|
||
"text_chunk_limit": {
|
||
"type": "integer",
|
||
"minimum": 1000,
|
||
"maximum": 16383,
|
||
"default": 4000,
|
||
"description": "消息分块大小上限",
|
||
},
|
||
"media_filename": {
|
||
"type": "string",
|
||
"default": "file",
|
||
"description": "媒体文件默认文件名",
|
||
},
|
||
"max_media_size_mb": {
|
||
"type": "integer",
|
||
"minimum": 1,
|
||
"maximum": 100,
|
||
"default": 100,
|
||
"description": "最大媒体文件大小 (MB)",
|
||
},
|
||
"dangerously_allow_name_matching": {
|
||
"type": "boolean",
|
||
"default": False,
|
||
"description": "允许白名单名称匹配(安全风险)",
|
||
},
|
||
"auto_register_commands": {
|
||
"type": "boolean",
|
||
"default": False,
|
||
"description": "自动注册 Slash Commands",
|
||
},
|
||
"commands": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"command": {"type": "string"},
|
||
"description": {"type": "string"},
|
||
},
|
||
},
|
||
"description": "自定义 Slash Commands",
|
||
},
|
||
"silence_send": {
|
||
"type": "boolean",
|
||
"default": False,
|
||
"description": "静默发送模式 — 发送 message 时不连带任何 props/attachments",
|
||
},
|
||
"block_streaming": {
|
||
"type": "boolean",
|
||
"default": True,
|
||
"description": "启用/禁用块流式输出",
|
||
},
|
||
"stream_min_chars": {
|
||
"type": "integer",
|
||
"minimum": 1,
|
||
"maximum": 16383,
|
||
"default": 50,
|
||
"description": "partial/block 流式模式下缓冲区最小字符数,达到后刷新",
|
||
},
|
||
"stream_idle_ms": {
|
||
"type": "integer",
|
||
"minimum": 100,
|
||
"maximum": 30000,
|
||
"default": 1000,
|
||
"description": "partial/block 流式模式下最大空闲等待 (ms),超时后刷新缓冲",
|
||
},
|
||
"blockStreamingCoalesce": {
|
||
"type": "object",
|
||
"properties": {
|
||
"minChars": {"type": "integer", "default": 1500},
|
||
"idleMs": {"type": "integer", "default": 1000},
|
||
},
|
||
"description": "block 流式合并配置",
|
||
},
|
||
"dmChannelRetry": {
|
||
"type": "object",
|
||
"properties": {
|
||
"baseDelayMs": {"type": "integer", "default": 1000},
|
||
"maxRetries": {"type": "integer", "default": 3},
|
||
},
|
||
"description": "DM 频道创建重试配置",
|
||
},
|
||
"responsePrefix": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "所有回复前添加的前缀",
|
||
},
|
||
"network": {
|
||
"type": "object",
|
||
"properties": {
|
||
"dangerouslyAllowPrivateNetwork": {
|
||
"type": "boolean",
|
||
"default": False,
|
||
},
|
||
},
|
||
"description": "网络配置",
|
||
},
|
||
"configWrites": {
|
||
"type": "boolean",
|
||
"default": False,
|
||
"description": "允许通过命令写入配置",
|
||
},
|
||
"agent_routes": {
|
||
"type": "object",
|
||
"description": "Per-channel/Per-team Agent 路由配置",
|
||
},
|
||
"default_agent_id": {
|
||
"type": "string",
|
||
"description": "默认 Agent ID",
|
||
},
|
||
"groups": {
|
||
"type": "object",
|
||
"description": "Per-Group 配置,支持 requireMention 覆盖",
|
||
"additionalProperties": {
|
||
"type": "object",
|
||
"properties": {
|
||
"requireMention": {"type": "boolean"},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
"required": ["server_url", "bot_token"],
|
||
"additionalProperties": True,
|
||
}
|
||
|
||
|
||
def validate_config_schema(config: dict) -> list[str]:
|
||
"""基于 JSON Schema 验证配置。返回错误列表。"""
|
||
errors = []
|
||
for req in MATTERMOST_CONFIG_SCHEMA.get("required", []):
|
||
if not config.get(req):
|
||
errors.append(f"Missing required field: {req}")
|
||
|
||
dm_policy = config.get("dm_policy", "")
|
||
allowed_dm = MATTERMOST_CONFIG_SCHEMA["properties"]["dm_policy"]["enum"]
|
||
if dm_policy and dm_policy not in allowed_dm:
|
||
errors.append(f"dm_policy must be one of {allowed_dm}")
|
||
|
||
group_policy = config.get("group_policy", "")
|
||
allowed_gp = MATTERMOST_CONFIG_SCHEMA["properties"]["group_policy"]["enum"]
|
||
if group_policy and group_policy not in allowed_gp:
|
||
errors.append(f"group_policy must be one of {allowed_gp}")
|
||
|
||
chatmode = config.get("chatmode", "")
|
||
allowed_cm = MATTERMOST_CONFIG_SCHEMA["properties"]["chatmode"]["enum"]
|
||
if chatmode and chatmode not in allowed_cm:
|
||
errors.append(f"chatmode must be one of {allowed_cm}")
|
||
|
||
text_chunk_limit = config.get("text_chunk_limit", 0)
|
||
if text_chunk_limit and (text_chunk_limit < 1000 or text_chunk_limit > 16383):
|
||
errors.append("text_chunk_limit must be between 1000 and 16383")
|
||
|
||
return errors
|
||
|
||
|
||
def get_config_schema() -> dict:
|
||
"""返回配置 JSON Schema。"""
|
||
return MATTERMOST_CONFIG_SCHEMA
|