Smart Message Plus
Cross-platform IM messaging CLI for DingTalk, Feishu (Lark) enterprise apps and WeCom (WeChat Work) group robot webhooks. Send P2P / group messages with text...
Evan Song
@songhonglei
What This Skill Does
Cross-platform CLI for sending messages via DingTalk, Feishu (Lark), and WeCom (WeChat Work). Supports text, Markdown, images, files, @mentions, message recall, templates, contact aliases, multi-account management, department broadcast, and a configurable safety gate with admin approval codes.
Replaces manually switching between multiple enterprise IM platforms and writing custom API integrations by providing a single unified command-line interface for all three services.
When to Use It
- Send a notification to a DingTalk group when a deployment completes
- Broadcast an urgent message to all members of a Feishu department
- Send a Markdown-formatted daily report to a WeCom group robot webhook
- Recall a mistakenly sent message across DingTalk or Feishu
- Send an image or file attachment to a specific contact via their alias
- Create a new DingTalk or Feishu group with predefined members from the CLI
Install
$ openclaw skills install @songhonglei/smart-message-plussmart-message-plus
- Version: 2.1.0
- License: MIT
- Author: Evan Song · github.com/Songhonglei
- Repository: https://github.com/Songhonglei/smart-message-plus
Unified CLI to send messages via DingTalk (钉钉), Feishu (飞书) enterprise apps and WeCom (企业微信) group robot webhooks — with contact aliases, templates, media, recall, department broadcast, and a configurable safety gate with admin approval codes.
⚠️ 消息内容红线(必读)
--msg 的内容必须由用户明确提供。AI/Agent 禁止代拟、补全、润色后直接发送。
唯一例外:用户明确授权的自测场景,且收件人仅为用户本人。
快速开始
SCRIPT="python3 <SKILL_DIR>/scripts/send.py"
# 🚀 推荐:交互式配置向导(选渠道→录凭证→自动验证→设默认账号,内嵌各平台权限清单)
$SCRIPT --onboard # 已配置且有效的渠道自动跳过;--onboard --force 全部重配
$SCRIPT --onboard-status # 查看配置完整度(渠道/凭证有效性/别名/门控)
# 非交互环境(Agent/管道)下 --onboard 不会卡死,自动改为输出状态+分步命令手册
# 或手动逐项配置:
# 1. 保存账号(钉钉企业内部应用)
$SCRIPT --save-account my-dingtalk dingtalk "钉钉Bot" \
--app-key <AppKey/ClientID> --app-secret <AppSecret> [--robot-code <robotCode>]
# 飞书自建应用
$SCRIPT --save-account my-feishu feishu "飞书Bot" \
--app-id <App ID> --app-secret <App Secret>
# 企业微信(webhook 模式:无需企业凭证,群机器人 webhook 即用即发)
$SCRIPT --save-account my-wecom wecom "企微Bot" # 账号可选,仅作 provider 占位
$SCRIPT --save-group 告警群 wecom "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx"
$SCRIPT --provider wecom --chat-id 告警群 --msg "内容"
# 2. 验证凭证
$SCRIPT --test-account my-dingtalk
# 3. 发送
$SCRIPT --provider dingtalk --to 13800000000 --msg "内容"
$SCRIPT --provider feishu --to user@example.com --msg "内容"
收件人写法(三级解析)
- 联系人别名(推荐):
--to 张三— 一个别名可存双平台 ID - 平台原生标识:钉钉=手机号/userId;飞书=邮箱/手机号/open_id
- 解析失败时会给出维护别名的具体命令
# 维护别名(single: 一人多平台;members: 多人组)
$SCRIPT --save-contact 张三 single "dingtalk:0144xxx,feishu:ou_xxx"
$SCRIPT --save-contact 核心组 members "张三,李四"
$SCRIPT --save-group 项目群 dingtalk cidXXXX==
$SCRIPT --list-contacts
钉钉不支持邮箱直发(无邮箱查询接口);飞书账号需绑定邮箱/手机号才能反查, 查不到时用别名兜底。
常用命令
# 单聊 / 批量单聊
$SCRIPT --to 张三 --msg "内容"
$SCRIPT --to 张三 李四 13800000000 --msg "内容"
# 群聊(群别名或原生群ID)+ @
$SCRIPT --chat-id 项目群 --msg "通知" --mention 张三
$SCRIPT --chat-id 项目群 --msg "通知" --mention-all
# Markdown(飞书自动走卡片 lark_md 渲染)
$SCRIPT --to 张三 --markdown --msg "**加粗** [链接](https://example.com)"
# 图片 / 文件
$SCRIPT --to 张三 --image /path/a.png /path/b.png
$SCRIPT --chat-id 项目群 --file /path/report.xlsx
# 模板(templates/<name>.txt,{{var}} 占位)
$SCRIPT --to 张三 --template notice --vars "title=标题" "date=今天"
# 卡片消息(v1.1:标题 + 正文 + 跳转按钮)
$SCRIPT --to 张三 --card --card-title "发布通知" \
--button "查看详情|https://example.com" --button "审批|https://example.com/ok" \
--msg "**v2.0 已发布**\n\n请及时验收"
# 钉钉=ActionCard(最多5按钮,无按钮时降级带标题MD);飞书=interactive卡片(header+lark_md+按钮)
# 部门广播(builtin=平台通讯录,custom=自定义接口)
$SCRIPT --broadcast --department "技术部" --msg "通知" --dry-run # 先预览
$SCRIPT --broadcast --department "技术部" --msg "通知"
# 建群(v2.0)
$SCRIPT --provider feishu --create-group "项目群" --members 张三 李四 # 飞书(机器人自动入群,全能力)
$SCRIPT --provider dingtalk --create-group "项目群" --owner 张三 --members 李四 # 钉钉必须给群主
$SCRIPT --provider feishu --list-groups # 机器人所在群列表(仅飞书)
# 建群成功自动保存群别名,之后直接 --chat-id 项目群 发消息
#
# 钉钉建群后会输出「添加机器人」提醒:说明补加机器人可解锁按钮卡片/撤回/@机器人,
# 并给出手动添加步骤(群设置→机器人→添加)和切换 cid 通道的命令。
# 高级:已有场景群模板ID时可 --with-bot --scene-template <ID>(机器人建群即在群内)
# 撤回 / 日志
$SCRIPT --list-log
$SCRIPT --recall <MSG_ID> # 钉钉不限时;飞书 24h 内
# 账号管理
$SCRIPT --list-accounts / --set-default-account <slug> / --remove-account <slug>
# 通用
--dry-run # 只预览不发送
--account <slug> # 指定账号
--provider dingtalk|feishu|wecom
安全门控(可配置)
| 人数 | 行为 |
|---|---|
| ≤50 | 直接发送 |
| 51-100 | ⚠️ 需 --force-send |
| >100 | 🔐 通知管理员,需 --approve-code <码> |
- 审核码:一次性、30 分钟有效、绑定收件人+内容(改内容作废)
- 管理员通知通过钉钉/飞书 DM 送达(配置见下)
- 数据目录
config.json:
{
"safety_gate": {
"enabled": true,
"warn_threshold": 50,
"review_threshold": 100,
"admins": [{"provider": "dingtalk", "user_id": "<直接userId,不允许别名>"}],
"notify_provider": "dingtalk"
}
}
- 关闭门控:
safety_gate.enabled = false - 群发审计日志:数据目录
broadcast_log.jsonl - 退出码:
0成功 /1一般错误 /3触发警告线(需--force-send)/4触发审核线(需--approve-code)
数据与安全
- 数据目录:
$SMP_DATA_DIR><workspace>/.smart-message/>~/.smart-message/ - 凭证文件 600 权限、原子写入、永不进 git;日志和回显自动脱敏
- 所有 HTTP 显式 timeout + 429/5xx 退避重试;token 缓存提前 5 分钟刷新
平台差异速查
| 钉钉 | 飞书 | 企业微信(webhook) | |
|---|---|---|---|
| 单聊收件人 | 手机号/userId | 邮箱/手机号/open_id | ❌ 仅群聊 |
| Markdown | 原生 | 卡片 lark_md 渲染 | 原生 |
| 图片上限 | 20MB | 10MB | 2MB |
| 文件上限 | 20MB | 30MB | 20MB |
| 撤回时限 | 不限 | 24 小时 | ❌ 不支持 |
| 群聊前提 | 机器人先进群 | 机器人先进群 | 群里添加机器人拿 webhook |
企业微信的两种模式(重要)
| webhook 模式(当前已实现) | wecom-app 模式(预留,未实现) | |
|---|---|---|
| 接入成本 | 群里加机器人复制 webhook,30 秒 | 自建应用 + 企业可信 IP |
| 群消息 | ✅ 文本/MD/图片/文件/news卡片/@人/@所有人 | ✅ |
| 单聊 / 通讯录查人 | ❌ | ✅ |
| 建群 / 撤回 / 部门广播 | ❌ | ✅ |
为什么先做 webhook:自建应用的 API 调用要求来源 IP 在「企业可信 IP」白名单内,且企业微信拒绝将第三方云服务商 IP 加白(实测 errcode=60020,腾讯云出口 IP 被拒)。托管容器/云环境没有企业自有出口 IP 时,全能力模式客观走不通。webhook 模式无 IP 校验,即用即发。 未来若有企业自有服务器出口 IP,可升级 wecom-app 模式解锁全能力(账号字段 corp_id/corp_secret/agent_id 已预留)。
webhook 细节:一个 webhook = 一个群;
--chat-id可传群别名、完整 webhook URL 或裸 key;markdown 不支持 @所有人(文本消息支持);news 卡片仅支持一个跳转按钮(多按钮自动取第一个);频率限制每机器人 20 条/分钟。
详细:references/provider-matrix.md(能力矩阵)、references/console-setup.md(后台配置+权限清单)、references/org-lookup-contract.md(自定义组织架构接口契约)。
部门广播的组织架构来源
- builtin(默认):钉钉/飞书通讯录 API(需通讯录读权限)
- custom:
config.json配org_lookup.mode=custom+custom_url,按契约实现自己的查询服务(鉴权头走环境变量,见契约文档)
依赖
- 零第三方依赖:仅 Python ≥ 3.9 标准库(urllib/json/argparse/hashlib/secrets),无需 pip install
scripts/core/、scripts/providers/为本 skill 内部本地包(经 sys.path 导入),不是 PyPI 包config.json/contacts.json/accounts.json等均为运行时在数据目录自动生成的文件,不随 skill 分发- 可选环境变量:
SMP_DATA_DIR(覆盖数据目录)、SMP_ORG_AUTH(自定义组织架构接口的鉴权头)
内部模块清单
| 文件 | 职责 |
|---|---|
scripts/send.py | CLI 主入口(参数解析/流程编排) |
scripts/core/config.py | 数据目录/配置读写(原子写+600) |
scripts/core/accounts.py | 多账号管理 + token 缓存 |
scripts/core/contacts.py | 联系人/群别名 |
scripts/core/http.py | stdlib HTTP(超时+退避重试+multipart) |
scripts/core/safety.py | 安全门控 + 审核码 |
scripts/core/sendlog.py | 发送日志(撤回路由) |
scripts/core/templates.py | 消息模板渲染 |
scripts/core/onboard.py | 配置向导(--onboard/--onboard-status) |
scripts/providers/base.py | Provider 抽象基类 + 能力矩阵 |
scripts/providers/dingtalk.py | 钉钉适配器 |
scripts/providers/feishu.py | 飞书适配器 |
scripts/providers/wecom.py | 企业微信适配器(webhook 模式) |
scripts/providers/org_lookup.py | 部门查询分发(builtin/custom) |
版本
- v1.0.0:钉钉+飞书;文本/MD/图片/文件/卡片/@/撤回/单聊/群聊/建群/部门广播;多账号;别名;模板;dry-run;门控+审核码
- v2.1.0:企业微信 wecom provider(webhook 模式:群文本/MD/图片/文件/news卡片/@人;wecom-app 全能力模式预留);onboard 配置向导(
--onboard/--onboard-status,增量补缺 + 内嵌权限清单 + 非TTY自动降级) - 规划:wecom-app 全能力模式(需企业自有出口 IP)、Slack provider
钉钉建群的通道差异(重要)
钉钉普通群无法通过 API 把机器人加进群(平台限制),且场景群模板的控制台配置页在钉钉客户端外无法正常使用(实测 JSAPI 4040 报错)。因此钉钉 --create-group 策略为:
- 直接建普通群(chatId)——建群即可发消息,走「应用消息通道」(chat/send):文本/MD/图片/文件,不支持按钮卡片和撤回
- 建群后自动输出提醒:列出补加机器人可解锁的能力(按钮卡片/撤回/@提醒/@机器人触发),附手动添加步骤(群设置→机器人→添加,约30秒)和切换命令
--save-group <别名> dingtalk <cid> - 高级路径:已有可用场景群模板ID时
--with-bot --scene-template <ID>可让机器人建群即在群内(全能力)
飞书无此差异:建群时机器人自动入群,全能力可用。
Top skills in this category
gmail
@byungkyuGmail API integration with managed OAuth. Read, send, and manage emails, threads, labels, and drafts. Use this skill when users want to interact with Gmail. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Calls run through the `maton` CLI with OAuth login; default to read and list calls, and confirm every write or new connection with the user.
WeChat MP CN
@guohongbin-git微信公众号监控 - 文章监控、阅读量追踪、舆情分析(WeChat Official Account)
Wechat Article Search
@wuchubuzai2018搜索微信公众号文章技能。通过微信搜索获取文章列表,覆盖科技/AI、社会热点、财经、教育、职场等各类中文资讯;可按关键词检索并返回标题、概要、发布时间、来源公众号与链接。当用户需要查找微信公众号文章、整理参考资料或快速获取文章信息时使用此技能。
Wechat Publisher
@0731coderlee-sudo一键发布 Markdown 到微信公众号草稿箱。基于 wenyan-cli,支持多主题、代码高亮、图片自动上传。
google-meet
@byungkyuGoogle Meet API integration with managed OAuth. Create meeting spaces, list conference records, and manage meeting participants. Use this skill when users want to interact with Google Meet. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Calls run through the `maton` CLI with OAuth login; default to read and list calls, and confirm every write or new connection with the user.