コンテンツにスキップ
Documents for MorningStatusApp
Esc
移動開く⌘Jプレビュー
このページの内容

Instagram Reelフラグ バックフィル 運用ドキュメント

概要

scripts/patch/patch-instagram-reel-flag.ts は、指定した1アカウント(メンバー or 公式アカウント)のInstagramプロフィールグリッドを再確認し、既にBlobに収集済みの投稿のうち実際にはReelだったものを検出して isReel: true に更新するCLIスクリプト。

isReelHrefscripts/workflow/collect-instagram-posts.ts)のバグにより、Reel投稿のグリッド内リンク(/{username}/reel/{id}/ 形式)が常に通常投稿として収集され、isReel フラグが一切立たない状態が続いていた(#1373)。バグ修正後は新規収集分から正しく判定されるが、修正前に収集済みの既存投稿には遡って反映されない。既存データを補正したい場合にこのスクリプトを使う。


前提条件

必要な環境変数

環境変数 用途
BLOB_READ_WRITE_TOKEN Instagram投稿データ(instagram/{memberId}/posts.json)の読み書き
MEMBERS_BLOB_URL メンバーデータの取得元(指定したInstagramアカウント名からメンバーを逆引きするため)
APP_URL 更新後のキャッシュ破棄先(/api/revalidate
REVALIDATE_TOKEN キャッシュ破棄APIの認証トークン

ローカル実行時は .env.local に設定する。

Instagram認証状態

Playwrightでプロフィールページを開くため、ログイン済みのCookie情報(auth_state.json)が必要。

  • auth_state.json がカレントディレクトリに存在しない場合、INSTAGRAM_AUTH_STATE 環境変数(GitHub Secretと同じ値)から復元を試みる
  • どちらもない場合はエラーで終了する。その場合は node scripts/console/save-instagram-auth.ts を先に実行してログインし、auth_state.json を生成すること

実行ランタイム: node --env-file=.env.local --import tsx を使うこと(bun 不可)

Windows環境では bun でPlaywrightの chromium.launch() を呼ぶとハングし応答が返らない既知の制約がある(開発ノート テスト手法#24)。そのため node で実行する必要があるが、以下2点のオプションが必須:

  • --import tsx: このリポジトリは拡張子なし相対import(from '../../types/member' 等、tsconfig.jsonmoduleResolution: "bundler" 前提)を使っており、プレーンな node のESMローダーはこれを解決できず ERR_MODULE_NOT_FOUND になる。tsx(devDependencies)のローダーが拡張子省略を解決する
  • --env-file=.env.local: bun.env.local を自動読み込みするが、node は自動読み込みしないため明示的に指定する必要がある
# NG: ハングする
bun scripts/patch/patch-instagram-reel-flag.ts --id nakazawa_yuko_official

# NG: ERR_MODULE_NOT_FOUND になる(拡張子なしimportを解決できない)
node scripts/patch/patch-instagram-reel-flag.ts --id nakazawa_yuko_official

# OK
node --env-file=.env.local --import tsx scripts/patch/patch-instagram-reel-flag.ts --id nakazawa_yuko_official

使い方

--id には Instagramの実アカウント名https://www.instagram.com/{username}/{username} 部分)を指定する。メンバーの内部ID(data/members.json 相当のID)や公式アカウントの内部ID(constants/instagram-official-accounts.tsid)ではない点に注意。resolveUsername(スクリプト内)が、渡されたアカウント名を①メンバーのofficialSns→②OFFICIAL_INSTAGRAM_ACCOUNTSの順に、登録されている instagramUrl から逆引きして照合する。

メンバーを指定する例

node --env-file=.env.local --import tsx scripts/patch/patch-instagram-reel-flag.ts --id nakazawa_yuko_official

公式アカウントを指定する例

node --env-file=.env.local --import tsx scripts/patch/patch-instagram-reel-flag.ts --id morningmusume_official

処理内容:

  1. --id(Instagramアカウント名)からメンバー/公式アカウントを逆引きする
  2. プロフィールグリッドを開き、最大10回までスクロールしながら /reel/ リンクのpostIdを収集する(読み込み件数が増えなくなった時点で打ち切り)
  3. 既存の収集済み投稿(Blob)と収集したpostIdを突合し、Reelと判明した投稿を isReel: true に更新する
  4. 変更があれば Blob に書き戻し、/api/revalidate でキャッシュを破棄する

エラーになる場合:

  • 指定したアカウント名がどのメンバーのofficialSnsにもOFFICIAL_INSTAGRAM_ACCOUNTSにも一致しない場合: 「収集対象として登録されていません」エラー
  • 指定したアカウント名がメンバーのofficialSnsに登録されているが active: false(収集対象から除外済み)の場合: 「登録されていますが、active: false のため収集対象外です」エラー

出力例:

[中澤裕子] @nakazawa_yuko_official のプロフィールグリッドを確認します...
[中澤裕子] グリッド上で 3 件の Reel 投稿を検出しました。
[中澤裕子] 2 件の投稿を isReel: true に更新しました。
キャッシュを破棄しました。

制限事項

  • スクロール範囲外の古いReelは検出できない: グリッド上で読み込まれた投稿のみが対象。アカウントの投稿数が多い場合、古いReel投稿は遡及できないことがある
  • 誤って isReel: false に戻すことはない: 今回のスクロール範囲で検出されなかった投稿があっても、既に isReel: true の投稿は維持される(見逃し許容・誤消去防止を優先する設計)
  • 1回の実行で1アカウントのみ: 複数アカウントをまとめて処理する機能はない。必要なアカウント分だけ個別に実行する

関連ファイル

ファイル 説明
scripts/patch/patch-instagram-reel-flag.ts スクリプト本体
scripts/workflow/collect-instagram-posts.ts 通常の定期収集スクリプト(isReelHrefextractPostId を共有)
scripts/console/save-instagram-auth.ts Instagram認証状態(auth_state.json)の取得スクリプト
scripts/patch/revalidate-cache.ts キャッシュ破棄の共通ヘルパー

このページは役に立ちましたか?