Memory

Smart Message Plus

Try it

Cross-platform IM messaging CLI for DingTalk, Feishu (Lark) enterprise apps and WeCom (WeChat Work) group robot webhooks. Send P2P / group messages with text...

What it does

Cross-platform IM messaging CLI for DingTalk, Feishu (Lark) enterprise apps and WeCom (WeChat Work) group robot webhooks. Send P2P / group messages with text, Markdown, images, files, @mentions, recall, message templates, contact aliases, multi-account management, department broadcast, and a configurable safety gate with admin approval codes. Use when the user asks to send messages via DingTalk / Feishu / WeCom ("用钉钉/飞书/企业微信发消息", "smart-message 发给 XX", "跨平台发消息"). Message content must be provided by the user - AI must never draft it autonomously.

The skill document

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 /scripts/send.py"

# 🚀 推荐:交互式配置向导(选渠道→录凭证→自动验证→设默认账号,内嵌各平台权限清单)
$SCRIPT --onboard          # 已配置且有效的渠道自动跳过;--onboard --force 全部重配
$SCRIPT --onboard-status   # 查看配置完整度(渠道/凭证有效性/别名/门控)
# 非交互环境(Agent/管道)下 --onboard 不会卡死,自动改为输出状态+分步命令手册

# 或手动逐项配置:
# 1. 保存账号(钉钉企业内部应用)
$SCRIPT --save-account my-dingtalk dingtalk "钉钉Bot" \
  --app-key  --app-secret  [--robot-code ]

# 飞书自建应用
$SCRIPT --save-account my-feishu feishu "飞书Bot" \
  --app-id  --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 "内容"

收件人写法(三级解析)

  1. 联系人别名(推荐):--to 张三 — 一个别名可存双平台 ID
  2. 平台原生标识:钉钉=手机号/userId;飞书=邮箱/手机号/open_id
  3. 解析失败时会给出维护别名的具体命令
# 维护别名(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/.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 (机器人建群即在群内)

# 撤回 / 日志
$SCRIPT --list-log
$SCRIPT --recall           # 钉钉不限时;飞书 24h 内

# 账号管理
$SCRIPT --list-accounts / --set-default-account  / --remove-account 

# 通用
--dry-run       # 只预览不发送
--account  # 指定账号
--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 > /.smart-message/ > ~/.smart-message/
  • 凭证文件 600 权限、原子写入、永不进 git;日志和回显自动脱敏
  • 所有 HTTP 显式 timeout + 429/5xx 退避重试;token 缓存提前 5 分钟刷新

平台差异速查

钉钉飞书企业微信(webhook)
单聊收件人手机号/userId邮箱/手机号/open_id❌ 仅群聊
Markdown原生卡片 lark_md 渲染原生
图片上限20MB10MB2MB
文件上限20MB30MB20MB
撤回时限不限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(需通讯录读权限)
  • customconfig.jsonorg_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.pyCLI 主入口(参数解析/流程编排)
scripts/core/config.py数据目录/配置读写(原子写+600)
scripts/core/accounts.py多账号管理 + token 缓存
scripts/core/contacts.py联系人/群别名
scripts/core/http.pystdlib HTTP(超时+退避重试+multipart)
scripts/core/safety.py安全门控 + 审核码
scripts/core/sendlog.py发送日志(撤回路由)
scripts/core/templates.py消息模板渲染
scripts/core/onboard.py配置向导(--onboard/--onboard-status)
scripts/providers/base.pyProvider 抽象基类 + 能力矩阵
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 策略为:

  1. 直接建普通群(chatId)——建群即可发消息,走「应用消息通道」(chat/send):文本/MD/图片/文件,不支持按钮卡片和撤回
  2. 建群后自动输出提醒:列出补加机器人可解锁的能力(按钮卡片/撤回/@提醒/@机器人触发),附手动添加步骤(群设置→机器人→添加,约30秒)和切换命令 --save-group <别名> dingtalk
  3. 高级路径:已有可用场景群模板ID时 --with-bot --scene-template 可让机器人建群即在群内(全能力)

飞书无此差异:建群时机器人自动入群,全能力可用。

Related skills

Operate Feishu or Lark IM APIs via UXC + curated OpenAPI schema

21 installs

Push messages to WeChat, ClawBot, email, webhook, SMS, App and more via the pushplus HTTP API using only curl.

25 installs1 stars

Configure OpenClaw multi-agent routing for Feishu multi-account setups. Use when users need two or more Feishu bots (different appId/appSecret) to run on iso...

30 installs

Poll Feishu groups for new messages, download message resources, read Feishu docs/wiki/sheets/bitables, compile message-source markdown, judge which chat segments are worth preserving, and ingest valuable materials into the Research KB through a prepare/apply workflow.

WeCom MCP (work.weixin.qq.com). Use this skill for ANY WeCom MCP request — searching and reading data. Whenever a task involves WeCom MCP, use this skill instead of calling the API directly.