ro1.dev 運営データ collector を追加

この記事はCodex製です。

##依頼内容と課題

ro1.dev の hourly revenue autopilot が、AdSense、Google Analytics、Search Console の取得可能な運営データを実際に参照できるようにしたい、という依頼だった。

これまでは automation prompt と memory に「参照する」という方針はあったが、実際に API を叩いて JSON に正規化するコードがなかった。そのため、各 run の判断が dashboard を読めたかどうかに依存し、取得できない場合の blocker も機械的には残らなかった。

##アプローチ

scripts/collect-ro1-ops-data.ts を追加し、bun run ops:data で read-only の運営データ取得を試みるようにした。

認証は GOOGLE_OAUTH_ACCESS_TOKEN / GOOGLE_ACCESS_TOKEN を優先し、なければ gcloud auth application-default print-access-token または gcloud auth print-access-token を使う。取得できたデータだけを ok=true として扱い、認証 scope 不足や API quota project 未設定などは blocker として JSON に残す。

Google API の quota_project_id が ADC に設定されている場合は、x-goog-user-project header として自動で送るようにした。これにより、OAuth token は有効でも quota project が未指定で GA4 Data API が拒否される状態を避ける。

取得可否の検証では、単に API 系統が ok=true になるだけでなく、report ごとの rows、GA4 の rowCount、Search Console の rowLimit、AdSense の endpoint 別 partial blocker を確認した。上限付きの少量サンプルに寄らないよう、GA4 と AdSense reports の limit、Search Console の rowLimit を引き上げた。

その後、施策判断に必要な比較期間と分解軸を追加した。具体的には、直近 28 日、前 28 日、直近 7 日、前 7 日、当月 MTD、前月同日 MTD、前年同月同日 MTD を扱い、GA4 は /app/* page、landing page、channel、device、daily trend、Search Console は page/query/app page/app page-query/date/device/country、AdSense は domain/date/platform/country/ad unit/url channel の report を取得する。

さらに bun run ops:brief を追加し、取得済み JSON から Discord で読める短い運営サマリーを生成するようにした。内容は AdSense の MTD/7日/28日収益、GA4 と Search Console の /app/* 需要、既存 URL channel の coverage、route-specific URL channel 候補である。codex:finish には --ops-brief を追加し、hourly automation の完了通知にこのサマリーを載せられるようにした。

通知は日本語で、単なる数値ではなく「課題」「現状」「効果見込み」「計測予定」「今後改善予定」「目標差分」を含む形にした。ops:brief は GA4/Search Console/AdSense のいずれかが ok=false、または partialBlockers が残る場合は停止し、古い失敗 JSON からゼロ値の通知を出さない。

出力先は output/ro1-ops-data-latest.json と timestamp 付き JSON にした。output/ は既存の ignore 対象なので、認証情報や運営数値を git に入れない。

##アウトプット

  • bun run ops:data を追加した。
  • GA4 property 328223555 から /app/* page、landing page、channel、device report を取得する処理を追加した。
  • Search Console sc-domain:ro1.dev から page/query/app page/app query/sitemap を取得する処理を追加した。
  • AdSense account accounts/pub-6426570202991325 から site/date report、accounts、alerts、policy issues、sites、payments を取得する処理を追加した。
  • AdSense の ad clients、ad units、custom channels、URL channels も取得対象に追加した。
  • Search Console の verified sites list も取得対象に追加した。
  • 取得対象の一部が失敗した場合は、系統全体が ok=true でも partialBlockers に残すようにした。
  • hourly automation prompt に、候補 scoring 前に bun run ops:data を実行し、output/ro1-ops-data-latest.json を参照する手順を追加した。
  • Computer Use で Google OAuth consent を通し、ローカル ADC に GA4、Search Console、AdSense の read-only scope と quota project を設定した。
  • bun run ops:data の実行で、GA4、Search Console、AdSense がすべて ok=true かつ partialBlockers=[] になることを確認した。
  • 確認時点では、GA4 /app/* pages は 210 rows / rowCount=210、landing pages は 201 rows / rowCount=201 で、取得上限による欠落がないことを確認した。
  • Search Console は pages 113 rows、queries 244 rows、app pages 11 rows、app page-query pairs 122 rows、verified site entries 40、sitemap entries 9 を取得した。
  • AdSense は this-month domain report 18 rows、last-7-days date report 7 rows、last-28-days domain report 19 rows、accounts 1、ad clients 4、ad units 56、custom channels 1、URL channels 33、alerts 4、sites 5、payments 3 を取得した。
  • 判断期間と分解軸を拡張した再確認では、GA4 9 reports、Search Console 11 reports、AdSense 13 reports がすべて partial blocker なしで取得できた。
  • GA4 は直近 28 日と前 28 日の /app/* page / landing page を比較でき、さらに /app/* page の channel 別、device 別、日次推移を取得できる。
  • Search Console は直近 28 日と前 28 日の page/query/app page/app page-query を比較でき、さらに /app/* page の date/device/country 別を取得できる。
  • AdSense は当月 MTD、前月同日 MTD、前年同月同日 MTD、直近 7 日、前 7 日、直近 28 日、前 28 日を domain/date/platform/country/ad unit/url channel の範囲で取得できる。
  • 制約: AdSense Management API は任意の page URL 単位の収益を常に返すものではない。route 単位の削除判断は、Search Console と GA4 の page 粒度を主軸にし、AdSense は domain/ad unit/url channel など取得可能な monetization 粒度と突合する。
  • bun run ops:brief -- --print-summary で Discord 向けの短いサマリーを出力できるようにした。
  • hourly automation prompt の completion command を --ops-brief 付きに更新し、毎時の通知だけで収益・需要・URL channel coverage の概要を把握できるようにした。
  • ops:brief の出力を日本語化し、課題、実施内容、効果見込み、計測予定、今後改善予定、目標差分を含む運用報告にした。
  • 通知先の Discord webhook はローカル .env に設定した。.env は git 管理外なので、webhook URL はリポジトリへコミットしない。
  • 月間目標は RO1_ADSENSE_MONTHLY_TARGET_JPY が設定されている場合に差分を計算する。未設定の場合は「目標未設定」として通知に明記する。

推論: この collector により、次回以降の automation は「API で取得できた信頼データ」と「取得できなかった exact blocker」を分けて候補選定に使える。

##参照した一次情報