概要 — 何をする画面か
サービス ▸ Web の各カードでは ユニークビジター 数の横に2つのアイコンが並び、それぞれモーダルを開きます。
| アイコン | モーダル | データ元 |
|---|---|---|
| 人物 | ビジター分析 | Google Analytics 4(Analytics Data API) |
| 虫めがね | 検索トラフィック | Google Search Console(Search Analytics API) |
カードの nginx_meta_ct アクセスインテルが 自サーバーが受け取ったもの を教えるのに対し、この2つのモーダルは 訪問者がどこから来たのか、どの検索語が連れてきたのか を教えます — サーバーログにはそもそも含まれていない情報です。
WordPress で Site Kit が行っていることは、突き詰めれば レポートのリクエストを代わりに組み立てること です。Laravel では自分で組み立てれば同じ数値が得られるため、プラグインも
google/apiclientも使いません — 作業の全体は「秘密鍵で JWT に署名し、アクセストークンと交換する」だけであり、サーバーはそれをネイティブに署名できます。REST エンドポイント2つのために巨大な依存ツリーを抱えるのは割に合いません。
こんなときに使う
- カードのトラフィックが増えたので、どのチャネル・どのソース がもたらしたのかを知りたいとき。
- インプレッションとクリックを生んでいる 検索キーワード と、各キーワードが どのページ に着地しているかを知りたいとき。
- 新規訪問者の割合・デバイス構成・流入の内訳といったオーディエンス構成を一目で把握したいとき。
- コンテンツ公開後のインプレッション・クリック・平均掲載順位を追跡しているとき。
画面構成
どちらのモーダルも 概要 / キーワード / トラフィック のタブに分かれており(キーワードタブは検索モーダルにのみ存在します)、スクロールではなくタブ切り替えで見ます。期間セレクターは 7 / 28 / 90 日 を提供します — サーバー側でホワイトリスト化されているものと同じ集合です。
ビジター分析(GA4)
- 6つの KPI: ユーザー数、新規ユーザー数、セッション数、ページビュー、エンゲージメント率、平均セッション時間 — それぞれ直前の同じ長さの期間との増減を伴います。
- 3つの構成比ストリップ: 訪問者のロイヤルティ(新規/再訪)、デバイス構成(デスクトップ 対 モバイル・タブレット)、流入(検索 対 その他)。3つとも2分割なので視覚言語が揃い、絶対数はすでに KPI が示しているため、ここでは 比率のみ を示します。
- 推移グラフ: ユーザー数、セッション数、ページビュー。
- 6つのパネル(トラフィックタブ): チャネル、ソース、都市、国、デバイス、人気ページ。
チャネルとソースは同じものではありません。 チャネルはまとめられた答え(
Organic Search)、ソースは具体的な答え(naver・github.com)です。とくに韓国のサイトでは、naver か google かで、流入の物語がまったく別のものになります。
検索トラフィック(Search Console)
- 5つの KPI: クリック数、インプレッション数、CTR、平均掲載順位、キーワード数。
- ワードクラウド: 大きさと色がインプレッションを表し、● は実際のクリックを生んだキーワードを示します。数値は
~1d / ~7d / allのインプレッションです。 - キーワード表: クリック数、インプレッション数、CTR、掲載順位。
- ランディングページ × クエリ: ページを展開すると、そのページから流入したキーワードが分かります。
- 3つのパネル: ランディングページ、国、デバイス。
平均掲載順位はインプレッション加重です。 単純平均では、掲載順位1位のインプレッション1件が40位の1万件を相殺してしまい、数値を実態よりはるかに良く見せてしまいます。
設定手順
1. サービスアカウントを作成する(Google Cloud)
- Google Cloud Console → プロジェクトを選択または作成 → IAM と管理 ▸ サービス アカウント → サービス アカウントを作成。プロジェクトレベルのロールは不要です。
- 作成したアカウントを開く → キー → 鍵を追加 ▸ 新しい鍵を作成 ▸ JSON → ファイルをダウンロードします。
- API とサービス ▸ ライブラリ で Google Analytics Data API と Google Search Console API を有効化します。
2. InfraGuard に登録する
サービス ▸ Web ▸ Web サイト管理 ▸ 対象サイトの編集タブ、Google 連携 の下で設定します。
| 項目 | 値 | 入手先 |
|---|---|---|
| GA4 プロパティ ID | 数字のみ(例 550688232) |
GA4 の管理 ▸ プロパティの詳細、または URL #/a<account>p<property>/ の p の後ろ |
| Search Console プロパティ | sc-domain:example.com または https://example.com/ |
Search Console のプロパティ選択に表示される文字列そのまま |
| サービスアカウント JSON | ダウンロードしたファイル 全体 を貼り付け | — |
GA4 のプロパティ ID はアカウント ID ではありません。
#/a405285491p550688232/では、aの後ろがアカウント、pの後ろがプロパティ です。Google は「そのようなプロパティは存在しない」と「権限がない」を意図的に区別しません(プロパティの存在自体が情報だからです)。そのため番号を間違えると、権限の問題とまったく同じに見えます。まずプロパティ ID を確認してください。
Search Console のプロパティをドメインから推測してはいけません。 それがドメインプロパティ(
sc-domain:)なのか URL プレフィックス(https://…/)なのかは、所有権を確認した本人しか知りません。選択を誤ると エラーではなく空の結果 が返ります。
3. 各プロパティにサービスアカウントを招待する
JSON はあくまで身元にすぎず、アクセス権は プロパティごと に付与します。保存後に表示される client_email をコピーして、次を行います。
| プロパティ | 場所 | ロール |
|---|---|---|
| GA4 | 管理 ▸ プロパティ のアクセス管理 ▸ + |
閲覧者 |
| Search Console | 設定 ▸ ユーザーと権限 ▸ ユーザーを追加 | フル |
GA4 ではこれは プロパティ のアクセス管理であり、アカウント のアクセス管理ではありません(左の列がアカウント、真ん中がプロパティです)。Search Console は制限付きではなく フル にしてください — Search Analytics API は制限付きユーザーを拒否します。サービスアカウントには受信箱がないため、「メールで通知」のチェックは外してください。
4. 接続をテストする
管理モーダルの [接続テスト] は、保存済みの認証情報で両方の API を1回ずつ(直近7日)呼び出し、それぞれの結果を個別に報告します。
| 状態 | 意味 |
|---|---|
ok |
Google が応答しました。0件でも成功です — 新しいサイトや GSC の遅延はエラーではありません |
fail |
Google 自身の文言と、招待すべき client_email |
skip |
プロパティが未設定のためスキップしました(失敗ではありません) |
認証情報がまったくない場合は何も呼び出しません(外部リクエストはゼロ)。未保存の編集内容はテストされません — 先に保存してください。
正しさのルール — なぜ数値をこのように組み立てるのか
以下は Site Kit がすでに実証した落とし穴に倣ったもので、いずれも根拠のあるものです。
| ルール | 理由 |
|---|---|
| 期間は 昨日で終わる | 当日は集計途中のため、含めると右端が必ず落ち込んで見えます |
GA4 は metricAggregations:['TOTAL'] の totals[0] を読む |
limit の掛かった行を合計すると、見出しの数値が過少になります |
すべての GA4 リクエストに hostName の in-list フィルター |
1つのプロパティが複数ホストにまたがることは多く、これがないとカードにプロパティ全体のトラフィックが出ます。カードの vts 集計と正確に一致させるため、そのサービスが保有するすべてのドメイン(主ドメイン・追加ドメイン・www)を渡します |
ランキングは keepEmptyRows:false + notExpression{emptyFilter} を使う |
GA4 の (not set) は実在の都市やソースを日常的に上回ってしまいます |
時系列は keepEmptyRows:true を使う |
トラフィックが0の日が軸から消えてはいけません |
GSC は dataState:'all' と約2日の遅延を用いる |
これがないと直近数日が0として読め、トラフィックの急落に見えます |
ドメインプロパティは page contains でスコープを絞る |
sc-domain: は全サブドメインにまたがるため、兄弟サイトのキーワードが混入します |
データソース
| 対象 | 接続 / 場所 | 役割 |
|---|---|---|
infr_web_service.ga4_property_id · gsc_site_url |
default(000771) | サイトごとのプロパティ紐付け |
infr_web_service.google_cred_enc · google_cred_email |
default(000772) | サイトごとのサービスアカウント(Crypt、書き込み専用) |
Analytics Data API properties/{id}:runReport |
外部 | ビジターレポート |
Search Console searchAnalytics/query |
外部 | 検索トラフィックレポート |
サービス: Services\Google\{GoogleTokenService, GoogleReportService, SiteInsightService}、エンドポイントは Service\WebController@insight{Visitors,Search,Test}。
キャッシュ: レポートのレスポンスはキャッシュされ、キャッシュキーには実行主体(client_email)が含まれます。同じ URL・同じ本文でも別アカウントからのリクエストは別の認可であり、キーを共有すると、あるサイトに別のサイトのキャッシュ応答を返してしまいます。
認証情報がサイトごとである理由
グローバルな .env キー1つでは 成り立ちません。 登録されたサイトはそれぞれ別のオーナー、したがって別の Google アカウントに属し、1つのサービスアカウントは招待されたプロパティしか読めません — 顧客が2社になった瞬間、どちらかが必ず失敗します。だからこそサイトごとに貼り付ける欄があります。
Crypt(APP_KEY) で保存され、書き込み専用 です。モデルが暗号文を隠すため、UI が目にするのは真偽値と、秘密ではないclient_emailだけです。秘密鍵は二度と外に出ません。- 保存時に3通りの検証を行います。JSON がパースできること、
client_email/private_keyが存在すること、そして 署名鍵の検査がその鍵を受け入れること です。貼り付けが途中で切れる事故はよくあり、これを通してしまうと後から偽の「権限がありません」として現れ、Google の IAM を延々と探す羽目になります。 - サーバー全体の認証情報は 単一アカウント構成向けのフォールバック として残ります。サイト自身の認証情報が常に優先されます。
認証情報の欄は 触れたときにだけ送信されます。フォームが秘密鍵を受け取り直すことはないため、「送られてこない=消去」と解釈すると、メモだけを編集したときにも認証情報が消えてしまいます。明示的に空にすることだけが削除の方法です。
アクセス権限
- 参照: ログイン済みの全ユーザー(
infr.auth、レベル1以上)。外部の統計を 読む だけで、InfraGuard にも Google にも何も変更しないため、ステップアップ認証も監査記録もありません(IP 評判照会 と同じ規律です)。 - 認証情報・プロパティの保存:
user_level >= 2(Web サイトの保存と同じ)、infr_audit_logに記録されます。
対象は 登録済みサイトの id でのみ 指定します — プロパティ ID をパラメーターで渡すことはできません。呼び出し側がプロパティを指定できるなら、当方のサービスアカウント権限が 他人の GA4/Search Console プロパティを読む経路になってしまいます(カタログのライブテスト と同じ SSRF 回避の規律です)。期間も同様にサーバー側で 7/28/90 にホワイトリスト化されています。
トラブルシューティング・FAQ
- カードにアイコンが出ない — ボタンが現れるには、そのサイトに認証情報とプロパティ紐付けの 両方 が必要です。判定はサイトごとなので、グローバルな
.envが空でも、自前の認証情報を持つサイトは動作します。保存してから再読み込みしてください。 - すべてのチェックが緑なのに0が返る — それはクエリの問題ではなく収集の問題です。① 期間は昨日で終わるため、今日設置したタグはまだ範囲外です。② サイトが実際に配信している測定 ID(
G-…)が、照会しているプロパティのものか確認してください(GA4 の管理 ▸ データストリーム)。データが別のプロパティに入っていれば、いつまでも0を読み続けます。③ Search Console は約2日遅れ、新しいサイトではインプレッションがまだ1件もないこともあります。 User does not have sufficient permissions— 手順3(アカウントの招待)が抜けているか、GA4 のプロパティ ID が誤っています。どちらも文言がまったく同じなので、まずプロパティ ID を確認してください。- Search Console だけ空で返る — プロパティ文字列が実態と一致していない可能性が高いです(
sc-domain:かhttps://…/か)。エラーではなく空の結果として失敗するため、プロパティ選択と照合してください。 - 保存したら認証情報が消えた — 欄を空にして保存することは明示的な削除です。触れずに残しておけば保持されます。
- モーダルに
Sampleバッジが出る — まだデータが収集されていないため、レイアウト確認用のサンプルを表示しています。データが届けば自動的に実データへ切り替わります。
関連項目
- サービス ▸ Web — Web 監視画面そのもの(カード・稼働率・証明書)
- 公開ランディングページとビジター分析 — 収集側(gtag/GTM、Search Console の所有権確認)
- IP 評判照会 — 同じ読み取り専用の外部照会の権限モデル
