lark-to-wechat-mp-1926f2 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited lark-to-wechat-mp-1926f2 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Sync a Feishu doc/wiki → WeChat Official Account draft in one workflow. Images are migrated, formatting is preserved.
CRITICAL — 执行前 MUST 先用 Read 工具读取 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md)(lark-cli 认证、权限)
~/.claude/wechat-mp.json (see Setup)cat > ~/.claude/wechat-mp.json << 'EOF'
{
"app_id": "wx...",
"app_secret": "YOUR_APP_SECRET"
}
EOF
chmod 600 ~/.claude/wechat-mp.jsoncurl -s ifconfig.meAPP_ID=$(python3 -c "import json; c=json.load(open(os.path.expanduser('~/.claude/wechat-mp.json'))); print(c['app_id'])" 2>/dev/null || \
python3 -c "import json,os; c=json.load(open(os.path.expanduser('~/.claude/wechat-mp.json'))); print(c['app_id'])")
APP_SECRET=$(python3 -c "import json,os; c=json.load(open(os.path.expanduser('~/.claude/wechat-mp.json'))); print(c['app_secret'])")
TOKEN=$(curl -s "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APP_ID}&secret=${APP_SECRET}" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token OK: ${TOKEN:0:20}..."DOC_URL="https://xxx.feishu.cn/wiki/..."
lark-cli docs +fetch --api-version v2 --doc "$DOC_URL" --doc-format markdown > /tmp/lark_doc.json⚠️ 飞书图片 URL 有时效性,必须立即进行 Step 3,不可搁置。
对文档中每个  图片:
mkdir -p /tmp/wx_imgs
# 下载
curl -L -o /tmp/wx_imgs/imgN.png "FEISHU_IMAGE_URL" -s
# 上传到微信(返回 wechat_cdn_url)
curl -s -X POST "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=${TOKEN}" \
-F "media=@/tmp/wx_imgs/imgN.png;type=image/png"
# → {"url":"http://mmbiz.qpic.cn/..."}记录 {feishu_url: wechat_cdn_url} 映射表,后续替换用。
# 缩放为 JPEG,控制在 64KB 以内(微信 thumb 上限)
sips -Z 700 /tmp/wx_imgs/img0.png -s format jpeg -s formatOptions 60 --out /tmp/wx_imgs/thumb.jpg
# 检查大小
wc -c /tmp/wx_imgs/thumb.jpg # 应 < 64000 bytes,否则降低 formatOptions
# 上传为永久素材(type=thumb),获取 media_id
curl -s -X POST "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=${TOKEN}&type=thumb" \
-F "media=@/tmp/wx_imgs/thumb.jpg;type=image/jpeg"
# → {"media_id":"xxx","url":"..."}使用本 skill 目录的 draft.py 脚本一键完成转换 + 创建:
python3 ~/.claude/skills/lark-to-wechat-mp/draft.py \
--doc "$DOC_URL" \
--title "文章标题(可选,自动提取)" \
--author "" \
--digest "摘要(可选,自动生成)"
# → ✓ Draft created successfully! media_id: xxx或手动创建(当需要精细控制 HTML 时):见文末「手动创建草稿」。
微信公众号文章必须使用 inline style,class 样式会被过滤。
| 元素 | 样式要点 |
|---|---|
全局容器 <section> | font-family:'PingFang SC',...;line-height:1.8;color:#333; |
<h1> 一级标题 | font-size:22px;border-bottom:2px solid #07C160; |
<h2> 二级标题 | font-size:18px;border-left:4px solid #07C160;padding-left:10px; |
<p> 正文 | margin:12px 0; |
<img> 图片 | max-width:100%;display:block;margin:20px auto; + 必须同时设置 `data-src` 和 `src` |
<a> 链接 | color:#07C160; |
<code> 行内代码 | background:#f0f0f0;padding:2px 6px;font-family:monospace;color:#e83e8c; |
<div style="margin:16px 0;padding:14px 18px;background:#fffbe6;border:1px solid #ffe58f;border-radius:6px;color:#333;">
<p style="margin:0 0 8px;font-weight:700;">🏖️ 标题</p>
<ul>...</ul>
</div>> → 灰色左边框<blockquote style="margin:16px 0;padding:14px 18px;background:#f5f5f5;border-left:4px solid #07C160;color:#555;">
引用内容
</blockquote>payload = {
"articles": [{
"title": "标题",
"author": "",
"digest": "摘要(120字内)",
"content": "<section>...HTML...</section>",
"content_source_url": "飞书原文链接",
"thumb_media_id": "封面图 media_id(必填)",
"need_open_comment": 1,
"only_fans_can_comment": 0
}]
}
# POST https://api.weixin.qq.com/cgi-bin/draft/add?access_token=TOKEN| 错误 | 原因 | 解决 |
|---|---|---|
errcode:40164 invalid ip | 当前 IP 未加白名单 | 微信公众平台 → IP白名单 → 添加 curl ifconfig.me 返回的 IP |
errcode:40001 invalid credential | Token 过期(有效期 7200s)或凭证错误 | 重新获取 Token |
Thumb upload: errcode:40009 | 缩略图超过 64KB 或非 JPEG | 降低 sips formatOptions,确认文件格式 |
| 图片显示为空 | 微信 <img> 需同时有 src 和 data-src | 两个属性都填 WeChat CDN URL |
| 飞书图片下载失败 | URL 已过期(搁置太久) | 重新 docs +fetch 获取新 URL |
当 draft.py 转换效果不满意时,手动在 Python 中构建 HTML 字符串并 POST:
import json, urllib.request
TOKEN = "..."
payload = {"articles": [{"title": "...", "content": "<section>...</section>", "thumb_media_id": "..."}]}
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(
f"https://api.weixin.qq.com/cgi-bin/draft/add?access_token={TOKEN}",
data=data, headers={"Content-Type": "application/json; charset=utf-8"}
)
with urllib.request.urlopen(req) as r:
print(json.loads(r.read()))~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.