全部技能 / 基础工具与工作流 / setup-notifications-via-wecom
基础工具与工作流 · daymade/claude-code-skills

setup-notifications-via-wecom

Set up and send technical status notifications through WeCom (Enterprise WeChat) webhooks. Use this skill whenever the user needs to send notifications, alerts, backup completion reports, or status updates via WeCom; when they mention 企业微信, 企微机器人, webhook, or alerting; or when a message needs to be clear, unambiguous, and technically precise rather than vague or condescending.

风险提醒:橙色 · 评估后使用AI 侦查报告
作者 daymadeGitHub daymade/claude-code-skills ↗Stars 1392许可 MIT(仓库根 LICENSE,Copyright (c) 2025 daymade;GitHub API spdx MIT)commit d5c4678cb5
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

分成两层:一次性的「装好发信器」(存 webhook、绑定收件人分类、试发验证)+ 每次的「把话说清楚」(消息写作规范与模板)。发信本身是脚本 POST 到企业微信群机器人 webhook。

setup-notifications-via-wecom/SKILL.md
1. **One-time setup**: store the webhook URL, test connectivity, and create a reusable sender script. 2. **Send messages**: craft messages that distinguish state from delta, define every number, and avoid the misleading patterns that made earlier backup-sync notifications confusing.
注:这条同时解释了「为什么它能做法务级精确的状态播报」:能力一半在脚本,一半在写作文档纪律。

腾讯系服务必须绕过本地代理,脚本在发起请求前主动清理六个代理环境变量——这是针对中国大陆网络环境的必要适配,不是可选优化。

setup-notifications-via-wecom/scripts/send_wecom.py
def clear_proxy_env(): """Remove proxy env vars so Tencent endpoints are reached directly.""" for name in ( "http_proxy", "https_proxy", "all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", ): os.environ.pop(name, None)
注:SKILL.md 侧同步说明:'The bundled script `scripts/send_wecom.py` handles the actual HTTP call, including the proxy-unset rule required for Tencent services in mainland China.'

收件人身份被提升为强制配置项而非可推断项:config 必须有 recipient_scope(self/others)与 recipient_label,缺失即硬失败退出,不允许 agent 猜。

setup-notifications-via-wecom/scripts/send_wecom.py
recipient_scope = config.get("recipient_scope") if recipient_scope not in VALID_RECIPIENT_SCOPES: print( f"Missing or invalid 'recipient_scope' in {CONFIG_PATH}; " "run scripts/set_recipient.py with self or others.", file=sys.stderr, ) sys.exit(1)
注:设计意图(SKILL.md):'`self` may send automatically; `others` requires human confirmation; missing identity fails fast.'

防替换链条:set_recipient.py 把发信脚本的绝对路径与 sha256 写进 config,发信前 send_wecom.py 重新计算并比对,任何一侧不匹配都拒绝发送。这是把「发信器自身被换掉」当成威胁模型来防。

setup-notifications-via-wecom/scripts/send_wecom.py
sender_path = Path(sender_path_value).expanduser().resolve() running_sender = Path(__file__).resolve() if sender_path != running_sender or not sender_path.is_file(): print( f"Configured sender does not match this executable: {running_sender}", file=sys.stderr, ) sys.exit(1) if not isinstance(sender_sha256, str) or sha256_path(sender_path) != sender_sha256: print( "Configured sender digest is stale; rerun scripts/set_recipient.py.", file=sys.stderr, ) sys.exit(1)
注:对应的写入侧在 set_recipient.py:sender_sha256 = sha256_path(sender_path)。

自动发送(outbox 路径)走更严的一次性授权:必须由 runaway-guard 给出 payload 摘要,脚本核对 schema、scope、webhook 摘要、sender 指纹全部一致才发,且只尝试一次 HTTP。

setup-notifications-via-wecom/scripts/send_wecom.py
"status": "pending_auto_self", "sender_skill": "notify-wecom", "recipient_scope": "self", "recipient_label": config["recipient_label"], "webhook_sha256": webhook_sha256,
注:SKILL.md 侧对行为差异的说明:'Manual `--message` / `--file` sends retry transient errors up to 3 times. Guard-owned automatic `--outbox` delivery makes exactly one HTTP attempt and requires the guard-approved payload digest; a later run never sends a pre-existing payload.'

配置写入是原子的:临时文件 + fsync + os.replace + 目录 fsync,且保留原文件权限位(默认 0600),避免半写坏配置或权限放宽。

setup-notifications-via-wecom/scripts/set_recipient.py
mode = stat.S_IMODE(path.stat().st_mode) or 0o600 tmp = path.with_name(f".tinkle_{path.name}.{os.getpid()}.tmp") try: fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, mode) with os.fdopen(fd, "w", encoding="utf-8") as handle: json.dump(config, handle, ensure_ascii=False, indent=2) handle.write("\n") handle.flush() os.fsync(handle.fileno()) os.chmod(tmp, mode) os.replace(tmp, path)
注:配套测试 RecipientConfigTests.test_setter_preserves_webhook_and_mode 明确断言 webhook 不被改写、mode 保持。

2核心能力

01企业微信群机器人 webhook 一次性配置与连通性试发
02收件人分类绑定(self 自动发 / others 需人工确认)与发信器指纹绑定
03纯文本消息发送(--message / --file / --outbox 三种互斥入口)
04代理变量隔离(Tencent 直连)
05瞬时错误重试(手动发送最多 3 次,间隔 2s)
06响应体真伪判定(HTTP 200 不等于成功,必须读 errcode)
07消息长度硬限制(4096 字节,UTF-8 计)
08三类消息模板 + 写作规范(备份完成 / 告警 / 状态更新)
09写作纪律清单(区分状态/增量、每个数字带定义、去噪音、告警只报症状不报原因)

3外部依赖

类型依赖
api企业微信群机器人 webhook(腾讯官方)
cliuv(以 --no-project 方式运行脚本,避免依赖项目环境)
clipython3(脚本运行时;标准库 urllib 发请求)
clicurl(文档提供的等价内联发送方式)
clienv(清代理的 shell 内建)

4风险提醒 风险提醒:橙色 · 评估后使用

风险提醒:橙色 · 评估后使用
  • 本地持有 bearer 密钥 — config.json 的 webhook_url 等同于「可往目标群发任意消息」的密钥。SKILL.md 已要求 chmod 600 与置于 skill 包外,但密钥一旦泄漏(误提交仓库、备份同步、屏幕分享)即可被任意发送。建议按密钥管理:不进版本控制、定期在企微侧轮换。
  • others(外部收件人)路径依赖人工确认门被执行 — 脚本能验证并拒绝越界的 outbox 自动发送,但『others 发送前必须展示 label 与正文并等人类确认』这一步是流程要求,由宿主 agent 执行;若 agent 忽略该步,脚本本身不会阻止一次 --message 直接发往 others 目标。
  • 静默清理代理环境变量可能改变本机网络行为 — clear_proxy_env() 在进程内 pop 掉六个代理变量。在只能经代理访问外网的环境里,这次发送会走直连并失败;在更复杂的环境里也可能绕过预期的出口策略。这是针对腾讯服务的刻意设计,但使用者应知道它存在。
  • 消息正文无净化,外部内容可直接出站 — 若把抓取的网页文本或工具输出原样拼成通知,会把不可信内容发进团队群(含潜在钓鱼链接或误导性数字)。规范要求「每个数字必须有定义」,但这是人的纪律而非代码约束。
  • 仅支持纯文本,能力边界需明确 — SKILL.md 自述 'It does not handle rich media messages (markdown cards, news, images) — only plain text.',不要指望它发富文本卡片。
风险提醒:橙色,评估后使用。判橙的触发点是【凭证读取】:脚本必须从 ~/.config/setup-notifications-via-wecom/config.json 读出 webhook_url——该 URL 的 key= 段是可发送任意消息到目标群的 bearer 密钥——并读同文件的身份与完整性字段;同时它在进程内清理代理环境变量并对外发起 POST。为什么不是红:没有任何安全降级(不开 TLS 校验、不绕反爬、不批量采集),没有把密钥送往非预期对象(目标就是密钥所属的腾讯官方端点),消息内容受 4096 字节上限与 errcode 校验约束。为什么不是黄:涉及本地密钥的读取与出站使用,且 config 里的 sender_path/sender_sha256 绑定说明作者自己就把「发信器可能被替换」列为威胁模型。缓解与设计亮点:self/others 分权 + others 需人工确认 + 缺失身份即硬失败;outbox 自动发送只允许一次 HTTP 且必须携带 guard 批准的 payload 摘要;config 原子写并保权限位。使用建议:webhook 只放在 600 权限的 config 里、不要进仓库,也不要把网页抓来的内容直接当通知正文发送。

5第二遍独立确认

  • [ok] 每条外部依赖的调用点是否真实存在 — webhook 端点(SKILL.md Quick Start 第 2 步 + 脚本 docstring + 内联 curl 三处一致)、uv --no-project(SKILL.md 命令块,脚本以 uv run 方式被调用)、python3/urllib(脚本 import 段与 urllib.request.Request/urlopen)、curl(SKILL.md 内联等价示例)、env -u / env|grep(SKILL.md 两处)。无推测项。
  • [ok] 凭证/密钥处理是否有反例(例如把 webhook 打印出去、写入日志、发往第三方) — 反例检索失败:全目录 grep webhook 的每一处均不打印其值——SKILL.md 的 set_recipient 说明写 'without exposing or rewriting the webhook value';脚本只把它用于 urllib.request.Request(webhook_url, …),出错时的报错文案(load_config 的四条 sys.exit 提示)不含 URL 本身;唯一的 webhook 值落点是 config.json 与用户自行执行的 echo(SKILL.md 明示 chmod 600)。发信目标与密钥归属同一服务。第一遍结论成立。
  • [ok] 「self 可自动发、others 需人工确认」是否只是文档口号(脚本是否真的挡) — 脚本层面真实生效:recipient_scope 不在 {self, others} 即 sys.exit(1);outbox 自动路径额外要求 payload.delivery 的 recipient_scope 必须为 'self'、recipient_label 与 webhook_sha256 必须与当前 config 完全一致,任一不符即拒绝('Outbox item is not bound to this explicit self target')。不是纯口号。
  • [ok] 发信器指纹绑定能否被绕过(是否只在文档里说、代码里没验) — 代码里确实验:send_wecom.py 同时比对 sender_path != running_sender 与 sha256_path(sender_path) != sender_sha256,两处不符都 sys.exit(1)。相应地,config 本身被篡改时这两个字段可被一起改写——这是该机制的边界,已在 security.injection_surface 第 ③ 点写明,不算被遗漏。
  • [ok] 写盘是否可能损坏配置或放宽权限 — set_recipient.py 用 O_EXCL 建临时文件、fsync 文件、os.chmod(tmp, mode) 后 os.replace,并对父目录 fsync;mode 取自原文件(stat.S_IMODE(path.stat().st_mode) or 0o600),不会放宽。tests 里 test_setter_preserves_webhook_and_mode 对 webhook 与权限有直接断言。结论成立。
  • [ok] references 与 SKILL.md 的规范条数/内容是否一致 — SKILL.md 的 Message Best Practices 8 条(标题先行/状态vs增量/数字定义/地点用词/去噪音/精确不居高临下/验证指标/下一步)在 references/message_best_practices.md 中为 12 节(多出告警 vs 状态更新、告警额外规则、常见错误模板、发送前自检),属扩充而非冲突。
  • [ok] 同一 pin 下本 skill 是否曾产出过旧侦查记录 — data/analysis 目录中不存在 setup-notifications-via-wecom.json 的旧记录(本次为首次产出)。同 repo 其他 slug 有旧记录的情况见各自文件。
  • [ok] pin commit 与 skill.path 是否与任务书一致 — git rev-parse HEAD = d5c4678cb5d4fd6acc9c922690df035dbd33d247;目录位于仓库根,相对路径 setup-notifications-via-wecom;本目录最后提交 878f947(2026-09-07)。GitHub API 复核 MIT / stars 1392 / pushed 2026-09-15T09:30:04Z。

6结论

  • 把「收件人是谁」做成必填且可验证的配置,而不是让 agent 推断——这是群机器人通知类工具里少见的边界设计。
  • 腾讯服务必须绕代理这一中国大陆特有坑被写成脚本内置行为,而不是留给用户排查。
  • 「HTTP 200 不代表成功」这一企业微信特有失败模式被显式处理,避免假成功。
  • 消息质量被当作可复用的工程资产:模板 + 规范清单 + eval 用例三层,且有真实纠错来源。
  • 配置写入具备原子性与权限保持,属于工程细节上的用心。
  • 适合:适合:中文技术团队里「把脚本跑完的结果可靠地播报到企微群」这类需求——备份/同步/cron/服务状态的固定格式播报,尤其是曾被批评「消息看不懂、说不清有没有漏」的场景。也适合需要区分私聊自查通道(self)与对外群发(others)并希望发信器不被随意替换的团队。
    不适合:不适合:需要富媒体卡片/图片/文件消息的场景(只支持纯文本);需要多渠道(Slack/飞书/邮件)统一抽象的场景(本 skill 只解决企微);只想临时发一条消息而不想配置持久化的场景(配置是必填前置,缺失即硬失败);把 webhook 密钥集中托管在高安全等级系统里的团队(密钥要求落在本地 600 文件)。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-15
    方式 A · 人下载镜像包下载 setup-notifications-via-wecom.tar.gz
    sha256: 75c3e6008604ce81…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit d5c4678cb5;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库daymade / daymade/claude-code-skills
    Stars1392
    最近推送2026-09-15
    本 skill commitd5c4678cb5
    许可MIT(仓库根 LICENSE,Copyright (c) 2025 daymade;GitHub API spdx MIT)
    本站信息
    收录日期2026-09-06
    分类基础工具与工作流
    侦查报告AI 侦查 · 2 遍 · 2026-09-06
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。
    同分类邻近