소스 정보
- 저장소
- aAAaqwq/openclaw-team
- 최근 소스 활동
- 2026년 6월 18일 02:18
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 1
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/aAAaqwq/openclaw-team --skill gzh-publisher명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
霸下销售总监大师技能包 — 全球顶尖B2B销售能力。对标华为铁三角+Salesforce+麦肯锡谈判法。
墨白首席美学官大师技能包 — 全球顶级视觉战略能力。对标伦敦皇家艺术学院 + 奥美全球 + 苹果Jony Ive设计标准。
轩辕AI编码舰队——OpenClaw作为大脑,指挥Claude Code/Cursor/Windsurf/Trae/Codex CLI集群并行开发。覆盖:ACP配置、IDE接入、权限管理、任务分发、windsurf+cursor双IDE调度、worktree隔离、舰队看板。触发词:IDE舰队、编码集群、AI IDE、多工具编排、ACP配置、Cursor舰队、Windsurf集群、Trae接入、IDE调度、并行编码、AI编码引擎、IDE编排、coding fleet
SOC 직업 분류 기준
SKILL.md 표시 중
| name | gzh-publisher |
| description | 微信公众号统一发布技能:通过 OpenClaw Browser 自动化完成登录、写文章、一键排版、封面、存草稿。 |
| metadata | {"version":"3.2.0","author":"Daniel Li","domains":["content","publishing","automation","wechat"],"type":"automation"} |
唯一官方微信公众号发布方式。基于 OpenClaw Browser 自动化。
# 推荐:自动扫描 gzh/ 目录图片
python3 scripts/publish.py --article gzh/article.md --author "Daniel"
# 跳过一键排版
python3 scripts/publish.py --article gzh/article.md --author "Daniel" --no-format
# 跳过封面
python3 scripts/publish.py --article gzh/article.md --author "Daniel" --no-cover
需要 OpenClaw Browser 运行中(openclaw browser start)。
📋 发布前确认内容合规:
~/clawd/projects/MediaClaw/references/platforms/weixin-mp.md
┌─────────────────────────────────────────────────────┐
│ Step 1: 检查登录状态 │
│ browser → navigate(mp.weixin.qq.com) │
├─────────────────────────────────────────────────────┤
│ Step 2: 新建文章(新标签页 appmsg_edit) │
├─────────────────────────────────────────────────────┤
│ Step 3: 填标题(JS evaluate, textarea) │
├─────────────────────────────────────────────────────┤
│ Step 4: 填作者(JS evaluate, input) │
├─────────────────────────────────────────────────────┤
│ Step 5: 粘贴素材图片(clipboard + Ctrl+V) │
│ → 每张等8秒 CDN 转换 → 收集 mmbiz URL │
├─────────────────────────────────────────────────────┤
│ Step 6: 设封面「从正文选择」← 必须在 HTML 注入前! │
├─────────────────────────────────────────────────────┤
│ Step 7: 注入正文 HTML(CDP WebSocket, 含 CDN 图片) │
├─────────────────────────────────────────────────────┤
│ Step 8: 一键排版(新标签页 articlestruct) │
│ → 点"使用此排版" → 图片不会丢失 ✅ │
├─────────────────────────────────────────────────────┤
│ Step 9: 保存草稿 │
└─────────────────────────────────────────────────────┘
innerHTML 注入 <img> → 图片不加载DOM.setFileInputFiles → 上传但不插入编辑器browser upload → 同上Type not supportedarticlestruct,需切换 targetId 后点"使用此排版"fill() 在微信 textarea 上会超时ta.value = ... + dispatchEvent('input') via browser evaluateevaluate 的 fn 有字符长度限制,>2000字会被截断/tmp/wechat-article.html → CDP WebSocket Runtime.evaluate 注入browser(action="navigate", profile="openclaw", url="https://mp.weixin.qq.com")
browser(action="snapshot", profile="openclaw")
// 点"新的创作"
browser(action="act", kind="evaluate", fn="""
() => {
const h2s = document.querySelectorAll('h2');
for (const h of h2s) {
if (h.textContent.trim() === '新的创作') { h.click(); return 'clicked'; }
}
}
""")
// 等1秒 → 点"文章"(y>300 的第一个文本="文章"的元素)
// 等待6秒 → 用 tabs 找 appmsg_edit 标签页
browser(action="tabs", profile="openclaw")
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const ta = document.querySelector('textarea[placeholder*="标题"]');
ta.focus(); ta.value = '文章标题';
ta.dispatchEvent(new Event('input', {bubbles:true}));
return 'filled: ' + ta.value;
}
""")
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const inp = document.querySelector('input[placeholder*="作者"]');
inp.focus(); inp.value = 'Daniel';
inp.dispatchEvent(new Event('input', {bubbles:true}));
return 'filled';
}
""")
必须用 CDP WebSocket 方式(browser 工具的 evaluate 传 base64 太大):
# 写成独立脚本 /tmp/paste_images.py,exec 运行
import asyncio, json, base64, httpx, websockets, os
async def paste_all(images, target_id):
async with httpx.AsyncClient() as c:
r = await c.get("http://127.0.0.1:18800/json/list")
ws_url = next(t["webSocketDebuggerUrl"] for t in r.json() if target_id in t["id"])
async with websockets.connect(ws_url, max_size=50*1024*1024) as ws:
# Grant clipboard
await ws.send(json.dumps({"id":0,"method":"Browser.grantPermissions",
"params":{"permissions":["clipboard-read","clipboard-write"],"origin":"https://mp.weixin.qq.com"}}))
await ws.recv()
for img_path in images:
with open(img_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
# Write to clipboard
await ws.send(json.dumps({"id":1,"method":,
:{:}}))
ws.recv()
asyncio.sleep()
ws.send(json.dumps({:,:,
:{:}}))
ws.recv()
ev [,]:
ws.send(json.dumps({:,:,
:{:ev,:,:,:,:}}))
ws.recv()
asyncio.sleep()
JPG 必须先转 PNG(Pillow):Image.open(p).save(p.with_suffix('.png'), 'PNG')
收集 CDN URL:
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => JSON.stringify(
Array.from(document.querySelectorAll('.ProseMirror img'))
.filter(i => i.src.includes('mmbiz')).map(i => i.src)
)
""")
⚠️ 必须在 Step 7 HTML 注入之前做!
// 1. 点"从正文选择"
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const items = document.querySelectorAll('#js_cover_description_area a, a');
for (const el of items) {
if (el.textContent.includes('从正文选择')) { el.click(); return 'clicked'; }
}
return 'not found';
}
""")
// 2. 选第一张图
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const items = document.querySelectorAll('.appmsg_content_img_item');
if (items.length > 0) { items[0].click(); return 'selected'; }
return 'empty';
}
""")
// 3. 下一步 → 确认
长 HTML 必须用 CDP(先写文件再注入):
# 1. 生成 HTML 写入文件(图片 URL 替换为 CDN)
write(path="/tmp/wechat-article.html", content=生成的HTML)
# 2. CDP 注入
python3 << 'EOF'
import json, asyncio, httpx, websockets
async def inject():
async with httpx.AsyncClient() as c:
r = await c.get("http://127.0.0.1:18800/json/list")
ws_url = next(t["webSocketDebuggerUrl"] for t in r.json() if TARGET in t["id"])
with open("/tmp/wechat-article.html") as f:
html = f.read()
async with websockets.connect(ws_url) as ws:
await ws.send(json.dumps({"id":1,"method":"Runtime.evaluate","params":{
"expression": f"(() => {{ const e = document.querySelector('.ProseMirror'); e.innerHTML = {json.dumps(html)}; e.dispatchEvent(new Event('input', {{bubbles:true}})); return 'ok'; }})()",
"returnByValue": True
}}))
print(json.loads(await ws.recv())["result"]["result"]["value"])
asyncio.run(inject())
EOF
// 1. 在编辑器页点"一键排版"
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const all = document.querySelectorAll('span, div, button, a');
for (const el of all) {
if (el.textContent.trim() === '一键排版' && el.offsetParent !== null) {
el.click(); return 'clicked';
}
}
}
""")
// 2. 等待 → 用 tabs 找 articlestruct 标签页
// 3. 在排版页点"使用此排版"
browser(action="act", kind="click", ref=使用此排版ref, targetId=排版页)
// 4. 排版自动应用,回到编辑器
browser(action="act", kind="evaluate", targetId=编辑器, fn="""
() => {
const btns = document.querySelectorAll('button');
for (const b of btns) {
if (b.textContent.includes('保存为草稿') && b.offsetParent !== null) {
b.click(); return 'clicked';
}
}
}
""")
| Markdown | HTML 样式 |
|---|---|
# H1 | 22px bold, text-align center |
## H2 | 18px bold, border-left 4px #1a73e8 |
### H3 | 16px bold |
**bold** | <strong> |
*italic* | <em> |
`code` | bg #f6f8fa, padding 2px 6px |
> quote | border-left 3px #ddd, color #666 |
 | 居中, max-width 100% |
正文段落:font-size:15px; color:#3f3f3f; line-height:1.75; margin:8px 0
输入:
article_path: string # Markdown 文章路径(必需)
author: string # 作者名(可选)
image_paths: list # 素材图片(可选,默认自动扫描 gzh/ 目录)
输出:
status: ok | error
draft_saved: true/false
appmsgid: string
title: string
images_uploaded: number
format_applied: boolean
cover_set: boolean
| Skill | 关系 |
|---|---|
wemp-operator | 全 API(统计/评论/粉丝/素材/群发) |
daily-gzh-content | 公众号内容生成 |
wechat-toolkit | 文章下载工具 |
v3.2.0 (2026-04-22): 修复图片位置bug
v3.1.0 (2026-04-18): 实战验证固化
v3.0.0 (2026-04-18): 大重写