@sunnoy/wecom 是 OpenClaw 企业微信渠道的社区增强插件,基于官方 @wecom/wecom-openclaw-plugin 的 WebSocket 长连接骨架,提供多账号管理、动态 Agent 隔离、Agent API / Webhook 增强出站、指令白名单、配额感知等企业级特性。
底层 SDK:@wecom/aibot-node-sdk — 企业微信智能机器人 Node.js SDK。
⚠️ 从 HTTP 回调迁移到长连接: 2.0 版本完全采用企业微信 AI 机器人 WebSocket 长连接模式。如果你之前使用 HTTP 回调(Token + EncodingAESKey + 回调 URL),需要在企业微信管理后台将机器人切换到长连接模式,然后删除旧的回调配置。切换后只需botId和secret即可接入。
2.1 新增: 在 WS 长连接之外,2.1 版本新增了企业微信自建应用"接收消息"HTTP 回调作为可选入站通道。在
channels.wecom.agent下配置callback.token、callback.encodingAESKey、callback.path即可同时启用,与 WS 通道并行运行,互不影响。
下表列出了本插件相比 官方 WeCom OpenClaw 插件(npm)额外提供的能力:
| 特性 | 官方插件 | 本插件 |
|---|---|---|
| WebSocket 长连接 + 流式回复 | ✅ | ✅ |
| 私聊 / 群聊接收 | ✅ | ✅ |
| DM 准入策略(pairing / open / allowlist / disabled) | ✅ | ✅ |
| 群聊准入策略(open / allowlist / disabled) | ✅ | ✅ |
| 按群配置发送者白名单 | ✅ | ✅ |
思考占位(<think> 占位符) |
✅ | ✅ |
| CLI 交互式配置向导 | ✅ | ✅ |
| 多账号管理(多 Bot 独立配置、共享字段继承) | ❌ | ✅ |
| 动态 Agent 路由(按用户 / 群自动隔离会话与工作区) | ❌ | ✅ |
| Workspace 模板(自动为新 Agent 复制 AGENTS.md 等引导文件) | ❌ | ✅ |
| Agent API 增强出站(自建应用主动发送文本、图片、文件) | ❌ | ✅ |
部门 / 标签目标发送(party: / tag: 寻址) |
❌ | ✅ |
| Webhook Bot 群通知(命名 webhook 映射,markdown / 图片 / 文件) | ❌ | ✅ |
| 指令白名单(限制普通用户可执行的 slash 命令) | ❌ | ✅ |
| 管理员绕过(命令白名单 + 动态 Agent 路由) | ❌ | ✅ |
| 运行时配额感知(被动回复 24h 窗口 + 主动发送额度追踪与告警) | ❌ | ✅ |
| Pending Reply 重试(WS 断连后自动通过 Agent API 补发未送达回复) | ❌ | ✅ |
| Reasoning 流式节流(800ms 节流防止 SDK 队列溢出) | ❌ | ✅ |
<think> 标签规范化(兼容 <thinking> / <thought> 等变体) |
❌ | ✅ |
Reply 媒体指令解析(自动提取 LLM 输出中的 MEDIA: / FILE: 路径) |
❌ | ✅ |
出站代理(network.egressProxyUrl) |
❌ | ✅ |
自定义 API 基础地址(network.apiBaseUrl / WECOM_API_BASE_URL) |
❌ | ✅ |
| Bindings 路由(固定绑定企业微信账号到指定 Agent) | ❌ | ✅ |
| 消息去重(reqId + msgId 去重,防止重复处理) | ❌ | ✅ |
入站图文混排(mixed 消息拆解为文本 + 图片) |
❌ | ✅ |
入站语音转写(voice.content 自动提取) |
❌ | ✅ |
入站引用消息(quote 上下文透传) |
❌ | ✅ |
| 自建应用回调入站(HTTP 回调作为独立入站通道,与 WS 并行) | ❌ | ✅ |
| Agent API Markdown 回复(回调入站回复默认 markdown 格式) | ❌ | ✅ |
| 入站/出站信息日志(WS / CB 收发日志,便于追踪消息流) | ❌ | ✅ |
- 相比官方插件的增强特性
- 前置要求
- 安装
- 从 HTTP 回调迁移
- 运行测试
- 配置
- 私聊与群聊准入策略
- 企业微信侧配置
- 消息能力与投递策略
- 动态 Agent 与路由
- 自建应用回调入站
- 常见问题
- 项目结构
- 自定义 Skills 配合沙箱使用实践
- 相关链接
- 贡献与协议
- 已安装 OpenClaw
2026.3.2+ - 企业微信管理后台权限,可创建 AI 机器人或自建应用
- 机器人已切换到长连接模式(参考官方文档)
- 运行 OpenClaw 的机器可以出站访问:
wss://openws.work.weixin.qq.comhttps://qyapi.weixin.qq.com(启用 Agent / Webhook 时)
Bot 主链路不需要企业微信反向访问你的 HTTP 回调地址。
openclaw plugins install @sunnoy/wecom从官方插件迁移: 如果之前使用
openclaw plugins install @wecom/wecom-openclaw-plugin,请先卸载官方插件再安装本插件。channels.wecom配置字段兼容,无需修改。
如果之前使用 HTTP 回调模式(Token + EncodingAESKey + 回调 URL),迁移步骤如下:
- 企业微信后台:进入「应用管理」→「智能机器人」,将机器人切换到长连接模式(参考官方文档)
- 记录凭证:切换后获取新的
BotId和Secret - 更新配置:在
~/.openclaw/openclaw.json中:- 设置
channels.wecom.botId和channels.wecom.secret - 删除旧的
token、encodingAesKey、回调 URL 相关配置
- 设置
- 安装插件:
openclaw plugins install @sunnoy/wecom - 重启 Gateway:
openclaw gateway restart
迁移后不再需要公网可达的 HTTP 回调地址,插件会主动连接企业微信 WebSocket。
npm test在 ~/.openclaw/openclaw.json 中添加:
{
"plugins": {
"entries": {
"wecom": {
"enabled": true
}
}
},
"channels": {
"wecom": {
"enabled": true,
"botId": "aibxxxxxxxxxxxxxxxx",
"secret": "xxxxxxxxxxxxxxxx",
"welcomeMessage": "你好,我是 AI 助手。",
"sendThinkingMessage": true,
"dmPolicy": "pairing",
"allowFrom": [],
"groupPolicy": "open",
"groupAllowFrom": [],
"adminUsers": ["admin-userid"],
"commands": {
"enabled": true,
"allowlist": ["/new", "/compact", "/help", "/status"]
},
"dynamicAgents": {
"enabled": true,
"adminBypass": false
},
"dm": {
"createAgentOnFirstMessage": true
},
"groupChat": {
"enabled": true,
"requireMention": true,
"mentionPatterns": ["@"]
},
"workspaceTemplate": "/path/to/template-dir",
"agent": {
"corpId": "wwxxxxxxxxxxxxxxxx",
"corpSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"agentId": 1000002
},
"webhooks": {
"ops": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx",
"dev": "yyy"
},
"network": {
"egressProxyUrl": "http://proxy.internal:8080",
"apiBaseUrl": "https://qyapi.weixin.qq.com"
}
}
}
}webhooks 的 value 既可以是完整 URL,也可以只写群机器人的 key。
| 配置项 | 类型 | 必填 | 说明 |
|---|---|---|---|
plugins.entries.wecom.enabled |
boolean | 是 | 启用插件 |
channels.wecom.enabled |
boolean | 否 | 渠道开关 |
channels.wecom.botId |
string | 是 | 企业微信 AI 机器人 Bot ID |
channels.wecom.secret |
string | 是 | 企业微信 AI 机器人 Secret |
channels.wecom.websocketUrl |
string | 否 | WS 地址,默认 wss://openws.work.weixin.qq.com |
channels.wecom.sendThinkingMessage |
boolean | 否 | 是否先发送 <think></think> 占位,默认 true |
channels.wecom.welcomeMessage |
string | 否 | 进入会话欢迎语 |
channels.wecom.adminUsers |
string[] | 否 | 管理员用户 ID,可绕过命令白名单 |
channels.wecom.defaultAccount |
string | 否 | 多账号模式默认账号 |
| 配置项 | 类型 | 必填 | 说明 |
|---|---|---|---|
channels.wecom.dmPolicy |
string | 否 | pairing、allowlist、open、disabled,默认 pairing |
channels.wecom.allowFrom |
string[] | 否 | 私聊 allowlist |
channels.wecom.groupPolicy |
string | 否 | open、allowlist、disabled,默认 open |
channels.wecom.groupAllowFrom |
string[] | 否 | 允许触发的群聊 ID 列表 |
channels.wecom.groups |
object | 否 | 按群覆盖配置,可为某个群单独设置 allowFrom |
channels.wecom.commands.enabled |
boolean | 否 | 是否启用命令白名单,默认 true |
channels.wecom.commands.allowlist |
string[] | 否 | 普通用户允许执行的命令 |
| 配置项 | 类型 | 必填 | 说明 |
|---|---|---|---|
channels.wecom.dynamicAgents.enabled |
boolean | 否 | 是否启用动态 Agent,默认 true |
channels.wecom.dynamicAgents.adminBypass |
boolean | 否 | 管理员是否绕过动态 Agent,默认 false |
channels.wecom.dm.createAgentOnFirstMessage |
boolean | 否 | 私聊是否按用户建独立 Agent,默认 true |
channels.wecom.groupChat.enabled |
boolean | 否 | 是否启用群聊处理,默认 true |
channels.wecom.groupChat.requireMention |
boolean | 否 | 群聊是否要求 @ 才响应,默认 true |
channels.wecom.groupChat.mentionPatterns |
string[] | 否 | 群聊触发前缀,默认 ["@"] |
channels.wecom.workspaceTemplate |
string | 否 | 动态 Agent 工作区模板目录 |
| 配置项 | 类型 | 必填 | 说明 |
|---|---|---|---|
channels.wecom.agent.corpId |
string | 否 | 自建应用 CorpID |
channels.wecom.agent.corpSecret |
string | 否 | 自建应用 Secret |
channels.wecom.agent.agentId |
number | 否 | 自建应用 AgentId |
channels.wecom.agent.replyFormat |
string | 否 | 回调入站回复格式,"markdown"(默认)或 "text" |
channels.wecom.agent.callback.token |
string | 否 | 回调验签 Token |
channels.wecom.agent.callback.encodingAESKey |
string | 否 | 回调消息解密密钥(43 位) |
channels.wecom.agent.callback.path |
string | 否 | 回调 HTTP 路由路径,如 "/webhooks/app" |
channels.wecom.webhooks |
object | 否 | 群机器人 webhook 映射 |
channels.wecom.network.egressProxyUrl |
string | 否 | Agent / Webhook 出站代理 |
channels.wecom.network.apiBaseUrl |
string | 否 | 企业微信 API 基础地址覆盖,默认官方地址 |
Agent 增强出站不需要 token、encodingAesKey、回调 URL;只有需要同时启用回调入站时才需配置 agent.callback.*。
{
"channels": {
"wecom": {
"defaultAccount": "open",
"adminUsers": ["admin-userid"],
"commands": {
"enabled": true,
"allowlist": ["/new", "/compact", "/help", "/status"]
},
"open": {
"botId": "aib-open-xxx",
"secret": "secret-open-xxx",
"dmPolicy": "open"
},
"support": {
"botId": "aib-support-xxx",
"secret": "secret-support-xxx",
"dmPolicy": "pairing",
"agent": {
"corpId": "wwxxxxxxxxxxxxxxxx",
"corpSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"agentId": 1000002
},
"webhooks": {
"ops": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
}
}
}
}
}多账号模式下:
- 顶层共享字段会合并到各账号
channels.wecom.<accountId>是每个账号自己的覆盖项- 动态 Agent ID 会自动带账号前缀
- 旧的 v1
token/encodingAesKey字段不再使用
| 值 | 含义 |
|---|---|
pairing |
默认模式。陌生用户首次私聊会收到配对码,管理员执行 openclaw pairing approve wecom <code> 后放行 |
allowlist |
只允许 allowFrom 中的用户私聊,不自动发配对码 |
open |
允许所有能私聊机器人的企业微信成员直接进入会话 |
disabled |
禁用私聊 |
open 的含义就是:如果机器人可见范围允许,企业内任何能私聊到这个 Bot 的成员都可以直接使用。
| 配置 | 说明 |
|---|---|
groupPolicy: "open" |
所有群可触发 |
groupPolicy: "allowlist" + groupAllowFrom |
只允许指定群 |
groupPolicy: "disabled" |
禁用群聊 |
groupChat.requireMention |
群聊是否必须 @ 才触发 |
groups.<chatId>.allowFrom |
某个群里仅允许指定成员触发 |
这是 v2 的主接入方式,使用 WebSocket 长连接。
- 登录企业微信管理后台
- 进入「应用管理」→「智能机器人」
- 创建机器人,选择长连接模式(参考官方文档)
- 创建完成后记录
BotId和Secret - 填入 OpenClaw 配置的
channels.wecom.botId和channels.wecom.secret - 启动 OpenClaw,插件会主动连接官方 WebSocket
长连接模式下不需要配置 HTTP 回调 URL、Token、EncodingAESKey。
自建应用承担两个可选职责:
增强出站(主动推送消息):
- 主动给用户 / 群 / 部门 / 标签发消息
- 上传图片和文件
- 当 WS 断连时作为回复后备通道
回调入站(可选,与 WS 并行):
- 企业微信将用户消息以 HTTP POST 推送到你的服务器
- 适合需要独立入站 URL 或不方便使用 WS 长连接的场景
创建步骤:
- 在企业微信后台创建自建应用
- 记录
CorpID、AgentId、Secret - 填入配置:
channels.wecom.agent.corpIdchannels.wecom.agent.agentIdchannels.wecom.agent.corpSecret
- 仅启用回调入站时,额外在应用的「接收消息」中配置回调 URL,并填入对应的
agent.callback.*配置(见自建应用回调入站)
Webhook 只负责群通知。
- 在目标群添加群机器人
- 复制 webhook URL 或 key
- 配置到
channels.wecom.webhooks - 发送目标使用
webhook:<name>
| 能力 | Bot(WS) | Agent API | Webhook |
|---|---|---|---|
| 私聊接收 | ✅ | ✅(回调入站) | — |
| 群聊接收(可配置 @ 触发) | ✅ | ✅(回调入站) | — |
| 被动流式回复 | ✅ | — | — |
| 被动最终帧图片 | ✅ | ✅ | ✅ |
| 主动发送文本 | ✅ | ✅ | ✅ |
| 主动发送图片 / 文件 | — | ✅ | ✅ |
| 发送到部门 / 标签 | — | ✅ | — |
思考过程 <think> |
✅ | — | — |
| 欢迎语 | ✅ | — | — |
| WS 断连补发 | — | ✅ | — |
| 类型 | 说明 |
|---|---|
text |
文本消息 |
image |
图片(AES 加密下载 + 解密) |
voice |
语音(自动提取转写文本 voice.content) |
file |
文件(AES 加密下载 + 解密) |
mixed |
图文混排(自动拆解为文本 + 图片) |
quote |
引用消息(上下文透传) |
被动回复统一走 WebSocket replyStream:
- 文本内容支持 Markdown
<thinking>、<thought>等变体会被规范化为<think>- 可先发送
<think></think>占位(配置sendThinkingMessage) - 思考流式更新采用 800ms 节流,防止 SDK 队列溢出
- 最终回复
finish=true时可附带图片msg_item - 若最终回复包含 WS 不支持的媒体(文件等),会先文本提示再通过 Agent API 补发
主动发送分层:
- 普通文本优先走 WS
sendMessage - 目标为
webhook:<name>时走 Webhook - 目标为用户 / 群 / 部门 / 标签,且配置了 Agent 时走 Agent API
- 发送图片 / 文件时,WS 侧给出文本提示,媒体交给 Agent / Webhook 通道
- 未配置 Agent / Webhook 时,只保留 WS 文本提示
当 WS 断连导致最终回复发送失败时:
- 插件自动将未送达回复加入 pending 队列(TTL 5 分钟,最多 50 条)
- WS 重连并认证成功后,自动通过 Agent API 补发所有 pending 回复
- 过期条目自动丢弃,不会无限积压
插件做本地近似记账,并把状态暴露到账号 snapshot / status:
- 连接占线:同一个
botId被其他实例接管时,标记displaced - 24h 被动回复窗口:按会话追踪 reply quota(限额 30,告警 24)
- 每会话每日主动发送额度:按会话追踪 active send quota(限额 10,告警 8)
- 接近上限或触顶时输出 warning
当前策略是"感知 + 告警",不做硬阻断。
| 格式 | 示例 | 说明 |
|---|---|---|
wecom:<userId> |
wecom:zhangsan |
发给企业微信用户 |
group:<chatId> |
group:wr123456 |
发给群聊 |
party:<id> |
party:2 |
发给部门 |
tag:<name> |
tag:Developers |
发给标签 |
webhook:<name> |
webhook:ops |
发给 webhook 群 |
<chatId> |
wr123456 |
直接写群 ID 也可识别 |
默认路由规则:
- 私聊:
wecom-dm-<userId> - 群聊:
wecom-group-<chatId> - 多账号私聊:
wecom-<accountId>-dm-<userId> - 多账号群聊:
wecom-<accountId>-group-<chatId>
好处:
- 每个用户 / 群聊独立上下文
- 每个动态 Agent 独立工作区
- 可以按账号进一步隔离
workspaceTemplate 目录中的 bootstrap 文件会在动态 Agent 首次创建时复制到工作区:
AGENTS.md、BOOTSTRAP.md、CLAUDE.md、SOUL.md、TOOLS.md、IDENTITY.md、USER.md、HEARTBEAT.md、system-prompt.md
模板支持 mtime 变更检测 — 当模板文件更新后,下次 Agent 启动会增量同步。
如果 OpenClaw 配置了 bindings,则优先按 binding 路由,不会被动态 Agent 覆盖。
自建应用的「接收消息」HTTP 回调可作为额外的入站通道,与 WS 长连接并行运行,互不干扰。适合已有自建应用的场景,或需要独立回调 URL 的情况。
在 channels.wecom.agent 下增加 callback 子对象:
{
"channels": {
"wecom": {
"botId": "aib-xxx",
"secret": "bot-secret-xxx",
"agent": {
"corpId": "wwxxxxxxxxxxxx",
"corpSecret": "app-secret-xxx",
"agentId": 1000002,
"replyFormat": "markdown",
"callback": {
"token": "YourToken",
"encodingAESKey": "43位密钥",
"path": "/webhooks/app"
}
}
}
}
}| 字段 | 说明 |
|---|---|
agent.callback.token |
企业微信「接收消息」里配置的 Token |
agent.callback.encodingAESKey |
43 位 EncodingAESKey |
agent.callback.path |
Gateway 监听的 HTTP 路径,需与企业微信后台填写的 URL 一致 |
agent.replyFormat |
回复格式,"markdown"(默认)或 "text" |
- 进入自建应用 → 「接收消息」
- 填写 URL:
https://<your-gateway-host>:<port><path>(例如https://example.com:18789/webhooks/app) - 填写 Token 和 EncodingAESKey(与配置保持一致)
- 点击「保存」,企业微信将发送 GET 请求验证(gateway 会自动回复 echostr)
- 验证通过后,用户发给自建应用的消息将通过 HTTP POST 推送到 gateway
| 类型 | 说明 |
|---|---|
text |
文本消息 |
image |
图片(通过 Agent API 下载) |
voice |
语音文件 |
file |
文件 |
video |
视频文件 |
事件类消息(关注、进入会话等)会被静默忽略。
2.0 完全采用 WebSocket 长连接,不再使用 HTTP 回调。需要在企业微信后台将机器人切换到长连接模式。
# 卸载官方插件
openclaw plugins uninstall wecom-openclaw-plugin
# 安装本插件
openclaw plugins install @sunnoy/wecom
# 重启
openclaw gateway restartchannels.wecom 配置字段兼容,无需修改。
是。前提是该成员对这个机器人可见,并且能在企业微信里私聊到它。
用户第一次私聊会收到配对码。管理员执行:
openclaw pairing approve wecom <code>不需要。Agent 只做增强出站,保留 corpId、corpSecret、agentId 即可。
不依赖。WS 消息体里的图片 / 文件自带独立 aeskey,插件按 image.aeskey 或 file.aeskey 下载与解密。
通常表示同一个 botId 被另一个实例接管了。企业微信同一时刻只允许一个活跃长连接。
webhook:<name>目标固定走 Webhook- 发送部门 / 标签 / 媒体消息时优先走 Agent
- WS 断连后的 pending 回复通过 Agent API 补发
- WS 文本主动发送失败时,尝试回退到 Agent
企业微信自建应用 API 的可信 IP 限制。把当前服务器出口 IP 加入企业微信应用的可信 IP 白名单即可。
openclaw-plugin-wecom/
├── index.js # 插件入口、生命周期、onboarding
├── dynamic-agent.js # 动态 Agent 路由判断
├── image-processor.js # 图片格式检测、MD5、Base64
├── logger.js # 结构化日志
├── think-parser.js # <think> 标签规范化
├── utils.js # 工具函数
├── openclaw.plugin.json # 插件元数据
├── wecom/
│ ├── accounts.js # 多账号管理与配置继承
│ ├── agent-api.js # Agent API(Token、发送、上传)
│ ├── allow-from.js # allowlist 规范化与匹配
│ ├── callback-crypto.js # 回调 AES 解密与签名验证
│ ├── callback-inbound.js # 自建应用回调入站处理
│ ├── callback-media.js # 回调媒体下载
│ ├── channel-plugin.js # 核心通道(sendNotice / sendMedia)
│ ├── commands.js # 指令白名单与命令拦截
│ ├── constants.js # 常量定义
│ ├── dm-policy.js # 私聊准入策略
│ ├── group-policy.js # 群聊准入策略
│ ├── http.js # HTTP 请求 + 代理
│ ├── onboarding.js # CLI 交互式配置向导
│ ├── runtime-telemetry.js # 运行时配额追踪
│ ├── sandbox.js # 沙箱集成
│ ├── state.js # 插件状态管理
│ ├── target.js # 目标解析(user / group / party / tag / webhook)
│ ├── webhook-bot.js # Webhook Bot 发送
│ ├── workspace-template.js # 工作区模板同步
│ ├── ws-monitor.js # WS 消息处理、流式回复、节流、重试
│ └── ws-state.js # WS 状态 + pending reply 队列
└── tests/
├── accounts-reserved-keys.test.js
├── api-base-url.test.js
├── callback-crypto.test.js
├── callback-inbound.test.js
├── channel-plugin.media-type.test.js
├── channel-plugin.notice.test.js
├── dynamic-agent.test.js
├── image-processor.test.js
├── issue-fixes.test.js
├── reply-media-directive.test.js
├── runtime-telemetry.test.js
├── target.test.js
├── think-parser.test.js
├── workspace-template.test.js
├── ws-monitor.quote-mixed.test.js
└── ws.e2e.test.js
OpenClaw 支持自定义 Skills 并通过沙箱(Docker)隔离执行,下面保留一份生产环境常见配置示例:
{
"agents": {
"defaults": {
"sandbox": {
"mode": "all",
"workspaceAccess": "rw",
"scope": "agent",
"docker": {
"image": "your-registry.com/openclaw-agent:v2026.x.x",
"readOnlyRoot": false,
"network": "bridge",
"extraHosts": [
"your-domain.internal:xxx.xxx.xxx.xxx"
],
"binds": [
"/path/to/skills:/workspace/skills:ro"
],
"dangerouslyAllowReservedContainerTargets": true,
"dangerouslyAllowExternalBindSources": true
},
"prune": {
"idleHours": 87600,
"maxAgeDays": 3650
}
}
}
},
"skills": {
"allowBundled": ["_none_"],
"load": {
"extraDirs": ["/path/to/skills"],
"watch": true,
"watchDebounceMs": 250
}
}
}关键点:
sandbox.mode: "all"表示所有操作都走沙箱sandbox.workspaceAccess: "rw"允许 Agent 读写工作区sandbox.scope: "agent"表示每个 Agent 独立沙箱sandbox.docker.binds可把宿主机技能目录映射到容器内/workspace/skillsskills.load.extraDirs用于声明自定义 Skills 加载目录skills.load.watch改动 Skill 后自动热加载
- OpenClaw — 开源 AI Agent 运行时
- 官方 WeCom OpenClaw 插件(npm)
@wecom/aibot-node-sdk— 企业微信智能机器人 Node.js SDK- 企业微信 AI 机器人官方文档
- 贡献说明见
CONTRIBUTING.md - 许可证为
ISC