Communitygithub.com

terryso/wechat-channels-video

Ego Lite 経由で微信视频号助理に動画の下書きを保存します(公開はしません)。ログイン確認、動画アップロード、説明文・短タイトル・トピック・位置情報・カバーなどを設定し、下書きのみを保存します。チャンネルがログアウトしている場合はソフトフェイルし、Ego 内でのQRコードスキャンを促します。個人利用向け。

wechat-channels-video とは?

このスキルは、AI エージェント(Claude Code、Cursor、Codex など)が微信视频号助理(WeChat Channels Assistant)に動画の下書きを保存するためのものです。公開は行わず、下書きのみを保存します。Ego Lite ブラウザ自動化フレームワークを利用し、まず `node scripts/check-login.mjs` でログイン状態を確認します(セッションの有効期限が短いため毎回必須)。ログインが確認できたら、`serve-file` スクリプトで動画ファイルをローカルサーバーで公開し、Web ページのファイル入力に DataTransfer API 経由で注入してアップロードします。その後、説明文、短タイトル、トピック、位置情報、カバー画像を設定し、「保存草稿」ボタンをクリックして下書きを保存します。ユーザーが手動で公開する必要がある場合は `task.handOff()` で制御を戻します。このスキルは WeChat Channels Assistant の wujie マイクロフロントエンド環境に対応しており、スナップショット、 evaluate、マウスクリック、waitForFileChooser などの ego-browser API を状況に応じて使い分けます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/terryso/ego-skills/tree/main/skills/wechat-channels-video

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

wechat-channels-video は何をしますか?

Ego Lite セッションを使用して 视频号助手 に 動画の下書きを保存 します。「公開」はクリックしません(QRコードでの公開は人間に委ねます)。

Save a WeChat Channels draft through Ego Lite. Never click Publish — QR publish is human-only.

事前準備:Ego のインストール

Ego Lite をインストールし、ego-browser が PATH に含まれていることを確認してください。不足している場合はソフトフェイルし、ユーザーにインストールを促します。ブラウザを直接操作しないでください。

毎回の公開前:ログインチェック(必須)

视频号のログイン状態は非常に早く期限切れになります。Agent はアップロードやフォーム入力の前に以下を実行する必要があります:

node scripts/check-login.mjs
# ユーザーにQRコードスキャンのためにウィンドウを残す場合:
node scripts/check-login.mjs --keep
終了コード意味Agent のアクション
0ログイン済みlogin_tip をユーザーに表示し、処理を続行
2未ログイン / ego-browser なしhow_to_login / how_to_login_zh を表示し、停止。ユーザーが Ego でQRコードをスキャンした後、check-login を再実行
1その他のエラーJSON error を報告し、公開済みと偽装しない

詳細は references/login.md を参照してください。別途 cookie-healthcheck スキルを作成しないでください。

入力(汎用、ローカル製品パスは不使用)

呼び出し元は動画とテキストフィールドを提供します。references/inputs.md を参照してください。本スキルは ~/… のようなビジネスディレクトリをハードコードしません。

最低限必要なもの:ローカルの video パス、description、short_title。オプション:tags、cover、位置情報/オリジナル/イベント。

CLI 薄型スクリプト(安定部分)

ego-browser nodejs はシェルの argv を転送しません。check-login は一時的なエントリと ego-browser nodejs -e でラップされています。

# リポジトリルート
node skills/wechat-channels-video/scripts/check-login.mjs
node skills/wechat-channels-video/scripts/check-login.mjs --keep
node skills/wechat-channels-video/scripts/serve-file.mjs --file /absolute/path/to/video.mp4 --port 18765

# インストール済みスキルディレクトリ内でも相対パスを使用可能
node scripts/check-login.mjs
node scripts/serve-file.mjs --file /absolute/path/to/video.mp4 --port 18765
  • check-login:唯一のログインゲート;デフォルトで finish({ keep: [] }) で終了(--keep を除く)。
  • serve-file:ページの fetch 用ローカル CORS ファイルサーバー;{ url, bytes, port } を出力し、SIGINT で終了。大きな動画は base64 エンコードしないでください。

公開UI全体を1つの巨大なスクリプトにまとめないでください:wujie、座標クリック、カバーの waitForFileChooser などは Agent がスナップショット/スクリーンショットを見て判断する必要があります。スクリプトはログインとファイル転送の判定可能な部分を担当し、フォーム入力は以下の Agent 手順に従います。

ego-browser API クイックリファレンス

ego-browser nodejs を実行するたびに新しいプロセスが起動します。TaskSpace / Page は呼び出し間で永続化されず、JS 変数も永続化されません。

API説明
taskSpace(name|id)1ユーザー目標に1つの space;spaceId を記録して再利用
task.page("p1")最初の画面は goto で再利用;ページをむやみに開かない
page.snapshot()観察用(open shadow を見通せる);クリックは wujie 内でよくインターセプトされる
page.evaluate(fn, arg)1つの JSON シリアライズ可能なパラメータのみ受け付ける(長いテキストはこちら)
page.mouse.click(x, y)wujie 内のポップアップでよく使用
page.waitForFileChooser()カバーアップロードの唯一の確実な方法
task.handOff()人間にQRコード公開/ログインを委ねる
task.finish({ keep: [] })後片付けで space を閉じる;人間が続けて見る必要がある場合は handOff を使用し、長期間マシンを占有しない

重要: snapshot は wujie shadow を見通せます;ref/text クリックはポインターイベントのインターセプトを報告します。wujie 内の操作は evaluate 内の .click() または座標 mouse.click を使用します。

Agent の流れ(ログイン通過後)

0. 公開ページへのルーティング

goto /platform/post/create を直接行わないでください(レイジーロードで白画面になります)。UI パスを使用します:

ホーム → 左カラム「コンテンツ管理」→「動画」→ 右側「動画を公開」

準備完了:wujie 内に「動画説明」「短タイトル」のテキスト、非表示の input[type=file][accept*="video"]、および「下書きを保存」ボタンがあることを確認します。

const state = await page.evaluate(() => {
  const app = document.querySelector('wujie-app');
  if (!app?.shadowRoot) return { wujie: false };
  const t = app.shadowRoot.textContent || '';
  return {
    wujie: true,
    hasDesc: t.includes('视频描述'),
    hasShort: t.includes('短标题'),
    hasUpload: !!app.shadowRoot.querySelector('input[type=file][accept*="video"]'),
    hasSave: t.includes('保存草稿'),
  };
});

1. 動画のアップロード

最初に serve-file を起動し(デフォルトポート 18765)、ページ内で fetch + DataTransfer を使用して非表示のファイル入力に注入します(動画コンポーネントは isTrusted による保護がありません;カバーは保護されています):

const r = await page.evaluate(async (p) => {
  const root = document.querySelector('wujie-app').shadowRoot;
  const input = root.querySelector('input[type=file][accept*="video"]');
  const resp = await fetch(p.url);
  const dt = new DataTransfer();
  dt.items.add(new File([await resp.blob()], p.name, { type: 'video/mp4' }));
  input.files = dt.files;
  input.dispatchEvent(new Event('input', { bubbles: true }));
  input.dispatchEvent(new Event('change', { bubbles: true }));
  return 'injected ' + dt.files[0].size;
}, { url: 'http://127.0.0.1:18765/video.mp4', name: 'video.mp4' });

検証は DOM のみで行います:「转发/赞/评论」プレビューカードが表示され、進行状況が 100% で安定していることを確認します。performance resource ではアップロード POST を取得できません。アップロード中はフォーム入力をしないでください;wujie が一時的に null になった場合は少し待ってから再試行し、リフレッシュしないでください。

1.5 チェックポイント:先に下書き保存

アップロード完了後、すぐに「下書きを保存」ボタンを1回クリックしてから、説明文/短タイトル/位置情報を入力し、最後にもう一度保存します。途中で問題が発生して大きなファイルを再アップロードする事態を避けるためです。

2. 説明文 + トピック

説明文は .input-editor(contenteditable ではありません)です。execCommand を使用します;テキストは evaluate の第二パラメータから渡します:

await page.evaluate((p) => {
  const ed = document.querySelector('wujie-app').shadowRoot.querySelector('.input-editor');
  ed.focus();
  document.execCommand('selectAll', false, null);
  document.execCommand('delete', false, null);
  document.execCommand('insertText', false, p.desc);
}, { desc });
await page.evaluate((p) => {
  const ed = document.querySelector('wujie-app').shadowRoot.querySelector('.input-editor');
  ed.focus();
  document.execCommand('insertParagraph');
  document.execCommand('insertText', false, p.tags);
  ed.blur();
}, { tags });

3. 短タイトル

本物の <input> です。ネイティブセッターを使用する必要があります;input.value を読み取って検証します(innerText には input の値は含まれません)。

4. 位置情報

デフォルトで都市が含まれることがよくあります。確実な方法:mouse.click で開く → スナップショット/スクリーンショット → 「位置情報を表示しない」をクリック → フィールドを読み戻して確認します。evaluate の座標は非表示のレイヤーにクリックしてしまう可能性があります。

5. 下書きを保存(終点)

「下書きを保存」をクリックします。成功の合図:「已保存」というメッセージと、下部のボタンがグレーアウトします。その後、下書きボックスに移動して確認します。下書きボックスが表示されるまではエディターから離れないでください。

オプション:オリジナル宣言、イベント検索(ネイティブセッターで検索語を入力;見つからなければ「イベントに参加しない」を選択)。

6. カバー画像(オプション)

唯一の確実な方法:waitForFileChooser() + 信頼できる「カバーをアップロード」のクリック + chooser.setFiles(<絶対パス>)。input.files の合成や OS ファイルダイアログの方法はテスト済みですが失敗しています。確認ボタンの回転が止まり、プレビューがデフォルトフレームに戻らなくなってから下書きを保存します。

7. 後片付け

  • serve-file を停止します(ポートを解放)。
  • 人間が公開する必要がある場合:下書きボックスで handOff()。
  • それ以外:finish({ keep: [] }) を実行し、space を長時間占有しない。

注意点リスト

  1. wujie shadow:クエリは wujie-app.shadowRoot から開始します。
  2. 直接 create に遷移すると白画面:UI パスを使用して公開ページに入る必要があります。
  3. wujie 内の ref/text クリックがインターセプトされる → evaluate または座標クリックを使用します。
  4. 長いテキストは evaluate パラメータ経由でのみ渡します。
  5. 説明文は execCommand、短タイトルはネイティブセッターを使用します。
  6. 位置情報は2段階の座標 + 読み戻し検証。
  7. カバーは waitForFileChooser のみ。
  8. アップロード検証は DOM のみ;アップロード後は先に下書きを保存します。
  9. 下書きが保存されるまでナビゲーションで離れない。
  10. ログインページの「読み込み失敗」はレッドヘリング;handOff で人間にQRコードスキャンを促します。
  11. 公開前に毎回 check-login;exit 2 の場合は必ず停止します。
  12. 公開は人間の終点;本スキルは下書きまでです。

テスト

npm test

関連スキル