baoyu-post-to-weibo
Posts content to Weibo (微博). Supports regular posts with text, images, and videos, and headline articles (头条文章) with Markdown input via Chrome CDP. Use when user asks to "post to Weibo", "发微博", "发布微博", "publish to Weibo", "share on Weibo", "写微博", or "微博头条文章".
1实现原理 · 为什么它能做到
实现路线是驱动本机真实 Chrome:找 Chrome 可执行文件 → 起带调试端口的实例(独立 profile)→ 等调试端口就绪 → 连 CDP WebSocket → attach 到目标页。
export async function launchChrome(url: string, profileDir: string, chromePathOverride?: string): Promise<number> {
反自动化检测绕过是本 skill 的显式设计:SKILL.md 首段就把它写成卖点,代码里则关闭 Chrome 的自动化特征标记。
extraArgs: ['--disable-blink-features=AutomationControlled', '--start-maximized'],
内容注入的第一手段是『真实按键粘贴』而非合成事件,理由被明写在脚本用途里:网站能检测并忽略 CDP 合成事件。
This bypasses CDP's synthetic events which websites can detect and ignore.
普通微博的文本输入用 CDP Input.insertText,失败回退 execCommand;媒体上传直接把文件路径塞给页面 file input,再按 blob:/data: 计数校验。
await cdp.send('Input.insertText', { text }, { sessionId });
头条文章走 card.weibo.com 的 ProseMirror 编辑器:填标题/导语 → 粘贴 HTML → 逐图『复制图片 + 真实粘贴键』替换占位符 → 校验剩余占位符与图片数。
// Method 1: Copy HTML to system clipboard, then real paste keystroke
平台字数限制被硬编码并自动处理:标题 32 字符、导语 44 字符,超长按标点边界截断或从正文重生成。
const TITLE_MAX_LENGTH = 32;
会接管/复用已在运行的调试 Chrome:按 profile 目录 + --remote-debugging-port 在进程列表里匹配,必要时只终止自己这套 profile 的实例。
if (!line.includes(profileDir) || !line.includes('--remote-debugging-port=')) continue;
登录态来自持久 Chrome profile,首次需人工登录一次后长期复用;且脚本只负责把内容填进页面,发布由用户手动确认。
All scripts only fill content into the browser, user must review and publish manually
2核心能力
3外部依赖
| Kind | Dependency / Endpoint |
|---|---|
| network | 浏览器访问 weibo.com 与 card.weibo.com(发帖与头条文章编辑器) |
| network | 头条文章编辑器入口 |
| cli | 本地 Chrome/Chromium(--remote-debugging-port + --user-data-dir,带 AutomationControlled 关闭参数) |
| cli | 粘贴按键注入工具(macOS osascript / Linux xdotool 或 ydotool / Windows powershell.exe) |
| cli | 剪贴板工具(macOS swift 临时脚本 / Linux wl-copy 或 xclip / Windows PowerShell) |
| cli | ps(进程枚举,用于复用/清理调试 Chrome) |
| package | baoyu-chrome-cdp(npm,仓库 packages/ 内共享包:CDP 连接、Chrome 查找与启动、按键/剪贴板基础件) |
| package | baoyu-md(npm,仓库 packages/ 内共享包:Markdown → HTML,供头条文章使用) |
| cli | bun(内部以 npx -y bun 调起同目录辅助脚本) |
4管控建议与判定依据
- SKILL.md / 脚本: 调用未公开或逆向工程的私有 API / 伪造客户端标识
- SKILL.md / 脚本参数: 包含绕过自动化检测、关闭宿主沙箱或跳过 SSL 证书校验
- SKILL.md / 会话存储: 读取或复用浏览器用户登录态与会话 Cookie
- scripts/: 执行本地脚本或命令: bun {baseDir}/scripts/weibo-post.ts <text> --image/--video …
- 外部 API: 向外部平台执行发帖、资源创建或修改写入
- 本地工作目录: 文件读写与工件输出: Chrome profile 目录(默认 baoyu-skills/chrome-profile 体系,登录态与浏览器数据持久化)
5第二遍独立确认
- [ok] 反自动化检测绕过(判红主因) — 三处证据互相印证:SKILL.md 'bypasses anti-bot detection';weibo-utils.ts `extraArgs: ['--disable-blink-features=AutomationControlled', '--start-maximized'],`(launchChrome 传给 launchChromeBase);paste-from-clipboard.ts 'This bypasses CDP's synthetic events which websites can detect and ignore.'
- [ok] 真实按键是第一手段而非兜底 — weibo-article.ts 注释排序为 '// Method 1: Copy HTML to system clipboard, then real paste keystroke',失败后才走 DataTransfer paste 事件;图片替换循环直接 pasteFromClipboard('Google Chrome', 5, 1000)。
- [ok] 凭证面确认(无密钥读取,靠 profile 会话) — 全目录 process.env/API_KEY/TOKEN/SECRET/.env 扫描零命中;SKILL.md 说明登录态由 Chrome profile 持久化(First run: log in to Weibo manually (session saved)),EXTEND.md 仅支持默认 profile 一项。
- [ok] 外部端点仅微博自家域名 — grep https:// 命中 WEIBO_HOME_URL=https://weibo.com/ 与 WEIBO_ARTICLE_URL=https://card.weibo.com/article/v3/editor,另有一处仅作日志措辞的 'src: https://...';无第三方 API/CDN。
- [ok] 平台限制与自检 — MAX_FILES=18、TITLE_MAX_LENGTH=32、SUMMARY_MAX_LENGTH=44 均在源码;SKILL.md 的 Post-Composition Check(剩余 WBIMGPH_ 占位符、预期 vs 实际图片数)与代码校验逻辑一致。
- [ok] 进程清理不会误杀用户浏览器 — killChromeByProfile 只对同时包含 profileDir 与 '--remote-debugging-port=' 的行取 pid 并 SIGTERM;SKILL.md 用 CRITICAL 明确禁止 `pkill -f "Google Chrome"`。
- [ok] 无其他安全降级 — grep no-sandbox / rejectUnauthorized / --insecure / NODE_TLS_REJECT / disable-web-security 零命中;Chrome 参数仅为调试端口、profile、AutomationControlled 与最大化窗口。
- [ok] 元数据(license/stars/commit) — git HEAD=1567581c26ec29f4216c6e6835415bf30343b0e3;仓库根 LICENSE=MIT(Copyright (c) 2026 Jim Liu);GitHub API stars=25926、pushed_at=2026-09-10T15:13:43Z。
6结论
5673e558aeace4cc…