1仕組みと動作原理
3系統の投稿ルートが共存:公式API(高速・認証情報必須)、ブラウザCDP(低速・ログインセッションを再利用)、remote-api(ローカルレンダリング + ホワイトリスト登録サーバーIPから送信するためのSSH SOCKS5トンネル)。
| `scripts/wechat-api.ts` | Article posting via API (文章) |
認証情報の解決チェーンは明示的な複数ソースの優先順位を採用:EXTEND.mdのアカウントブロック → プレフィックス付き環境変数 → WECHAT_APP_ID/WECHAT_APP_SECRET(process.env、<cwd>/.baoyu-skills/.env、~/.baoyu-skills/.env)。
buildCredentialSource("process.env", process.env, "WECHAT_APP_ID", "WECHAT_APP_SECRET"),
APIルートはWeChat公式の4ステップ手順に準拠:access_token取得 → uploadimg(本文画像) → material/add_material(カバー素材) → draft/add(下書き作成)。
const DRAFT_URL = "https://api.weixin.qq.com/cgi-bin/draft/add";
本文画像にはWeChat側の厳格な制限があるため、スクリプトが事前にトランスコード/圧縮した上でアップロードし、マジックバイトを用いて宣言フォーマットと実際のフォーマットの不一致を補正します。
export const WECHAT_BODY_IMAGE_MAX_SIZE = 1024 * 1024; // 1MB
remote-apiの仕組みは、レンダリング、画像処理、下書きの組み立てをローカルで完結させ、api.weixin.qq.comへの送信HTTPSリクエストのみをSSHダイナミックポート転送(SOCKS5)経由で行います。
are tunneled through an SSH SOCKS5 dynamic port forward (`ssh -N -D`)
ブラウザルートのログインセッションは永続化された共有Chromeプロファイルから取得され、起動引数でChromeの自動化検出フラグを強制的に無効化(--disable-blink-features=AutomationControlled)します(技術的なアンチ自動化検出回避の典型的な手法)。
extraArgs: ['--disable-blink-features=AutomationControlled', '--start-maximized'],
同一ディレクトリに「実キー入力貼り付け」ヘルパーも同梱されており、Webサイトが検知可能な合成イベントの回避を目的とすることが明記されています。
This bypasses CDP's synthetic events which websites can detect and ignore.
ログインセッション取得のための外部送信チャネルが存在:未ログイン時にログイン用QRコードを取得し、オプションでTelegram Bot経由で指定のチャットに送信できます。
const tgResp = await fetch(`https://api.telegram.org/bot${botToken}/sendPhoto`, {
エンジニアリング対応:EXTEND.mdの複数アカウントブロックおよびアカウント解決に加え、事前の環境・権限セルフチェック用スクリプトを完備。
EXTEND.md supports an `accounts:` block for managing multiple Official Accounts.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| api | 微信公众平台 access_token |
| api | 正文图片上传(uploadimg) |
| api | 永久素材/封面上传(add_material) |
| api | 建草稿(draft/add,含 need_open_comment / only_fans_can_comment 等字段) |
| api | Telegram Bot API(可选:把登录二维码发到指定聊天) |
| network | 浏览器访问 mp.weixin.qq.com(公众号后台登录与发文界面) |
| cli | ssh(-N -D SOCKS5 动态端口转发;仅密钥认证) |
| cli | 本地 Chrome/Chromium(--remote-debugging-port 启动,带 AutomationControlled 关闭参数) |
| cli | 系统剪贴板工具(macOS: swift/osascript;Linux: wl-copy 或 xclip;Windows: powershell.exe) |
| cli | 粘贴按键工具(macOS osascript System Events;Linux xdotool/ydotool;Windows PowerShell SendKeys) |
| package | jimp / @jsquash/webp / socks / baoyu-md / baoyu-chrome-cdp |
| cli | bun(内部以 npx -y bun 调起同目录脚本) |
4推奨統制措置と判定根拠
- SKILL.md / 脚本: 未公開またはリバースエンジニアリングされたプライベートAPIの呼び出し / クライアント識別子の偽装
- SKILL.md / 脚本参数: 自動化検出の回避、ホストサンドボックスの無効化、またはSSL証明書検証のスキップを含む
- SKILL.md / 会话存储: ブラウザユーザーのログインセッションおよびセッションCookieの読み取りまたは再利用
- scripts/: ローカルスクリプトまたはコマンドの実行: bun {baseDir}/scripts/wechat-api.ts <file> --theme … [--remote …](APIルート)
- 网络端点: 外部ネットワークアクセスの宣言: https://api.weixin.qq.com(token / uploadimg / add_material / draft/add)— 利用可能
- 本地工作目录: ファイルの読み書きおよびアーティファクト出力: ローカルでレンダリングされた貼り付け対象HTMLおよび本文画像処理成果物(WeChat側アップロード用)
5二重目の独立検証
- [ok] 反自动化检测绕过(判红主因) — scripts/cdp.ts:125 `extraArgs: ['--disable-blink-features=AutomationControlled', '--start-maximized'],` 由 launchChromeBase 传给 Chrome(浏览器脚本共用);scripts/paste-from-clipboard.ts:5-7 明写 'This bypasses CDP's synthetic events which websites can detect and ignore.'
- [ok] 该绕过是否真的在发布路径上 — cdp.ts 的 Chrome 启动函数是 wechat-browser.ts 与 wechat-article.ts 的入口(两者都从 cdp.ts 导入并把自动化参数交给 launchChromeBase);paste 助手本身在本 commit 未被这两个主流程引用,已在 reason/injection_surface 如实标注程度。
- [ok] 凭证读取链 — wechat-extend-config.ts 的 loadCredentials 依次尝试 EXTEND.md account → 前缀 env/.env → WECHAT_APP_ID/WECHAT_APP_SECRET(process.env、cwd .env、home .env),与 SKILL.md 描述一致。
- [ok] 微信 API 端点与 payload 规则 — wechat-api.ts 常量区四个 URL 与 SKILL.md 的 draft/add payload rules(article_type/thumb_media_id/need_open_comment/only_fans_can_comment/content_source_url)逐项对应。
- [ok] remote-api 的隧道实现与承诺 — wechat-remote-publish.ts 组装 `-N -T -D 127.0.0.1:<port>` 等参数且仅用密钥(`if (config.identityFile) args.push("-i", …)`);SKILL.md 承诺不在远端落文件、AppSecret 不出本机——源码内确无远端文件写入路径(只建隧道与本地 SOCKS 出站)。
- [ok] Telegram 二维码外发为可选 — wechat-article.ts sendQrToTelegram 在 `if (!botToken || !chatId) return;` 之后才发请求;未配置即完全不走该路径。
- [ok] 依赖与剪贴板工具链 — package.json/bun.lock 声明 jimp、@jsquash/webp、socks、baoyu-md、baoyu-chrome-cdp;copy-to-clipboard.ts 分别用 swift/osascript、wl-copy/xclip、powershell.exe,与 check-permissions.ts 的检查项一致。
- [ok] 无其他安全降级 — 全目录 grep no-sandbox / rejectUnauthorized / insecure / NODE_TLS_REJECT_UNAUTHORIZED 零命中;Chrome 启动参数仅常规项 + AutomationControlled。
6結論
1f149b01778641d8…