InfraGuard

Аналитика посетителей и поиска

Смотрите аналитику посетителей GA4 и поисковый трафик Search Console прямо с карточки сайта, используя сервисный аккаунт, сохранённый для каждого сайта вместе с сопоставлением ресурса.

Обзор — что делает этот экран

Рядом с числом уникальных посетителей на каждой карточке Сервисы ▸ Веб расположены два значка, каждый из которых открывает модальное окно.

Значок Окно Источник
Человек Аналитика посетителей Google Analytics 4 (Analytics Data API)
Лупа Поисковый трафик Google Search Console (Search Analytics API)

Если сведения о доступе nginx_meta_ct на карточке говорят вам, что получил ваш сервер, то эти два окна говорят, откуда пришли посетители и какие поисковые запросы их привели, — таких сведений в журналах вашего сервера попросту нет.

То, что Site Kit делает в WordPress, по существу сводится к тому, чтобы собрать за вас запросы к отчётам. В Laravel вы собираете их сами и получаете те же самые числа, поэтому мы не используем ни плагин, ни google/apiclient: вся работа — «подписать JWT закрытым ключом и обменять его на токен доступа», а сервер подписывает это средствами самого языка. Тащить огромное дерево зависимостей ради двух REST-эндпоинтов — плохая сделка.

Когда это нужно

Устройство экрана

Оба окна разделены на вкладки Обзор / Запросы / Трафик (вкладка запросов есть только в окне поиска), так что вы переключаетесь, а не прокручиваете. Выбор периода предлагает 7 / 28 / 90 дней — ровно тот набор, который разрешён на сервере.

Аналитика посетителей (GA4)

Канал и источник — не одно и то же. Канал — это сгруппированный ответ (Organic Search), источник — конкретный (google, naver, github.com). Особенно для корейских сайтов naver против google — это две совершенно разные истории привлечения.

Поисковый трафик (Search Console)

Средняя позиция взвешена по показам. При простом среднем один показ на первой позиции компенсирует десять тысяч показов на сороковой, что грубо приукрашивает число.

Как это настроить

1. Создайте сервисный аккаунт (Google Cloud)

  1. Google Cloud Console → выберите или создайте проект → IAM и администрирование ▸ Сервисные аккаунты → Создать сервисный аккаунт. Роль на уровне проекта не требуется.
  2. Откройте аккаунт → Ключи → Добавить ключ ▸ Создать ключ ▸ JSON → скачайте файл.
  3. В разделе API и сервисы ▸ Библиотека включите Google Analytics Data API и Google Search Console API.

2. Зарегистрируйте его в InfraGuard

В разделе Сервисы ▸ Веб ▸ Управление сайтами ▸ вкладка редактирования сайта, в блоке Интеграция с Google:

Поле Значение Где найти
Идентификатор ресурса GA4 только цифры (например, 550688232) Администратор GA4 ▸ Сведения о ресурсе либо URL #/a<account>p<property>/ — часть после p
Ресурс Search Console sc-domain:example.com или https://example.com/ в точности та строка, что показана в списке ресурсов Search Console
JSON сервисного аккаунта вставьте скачанный файл целиком —

Идентификатор ресурса GA4 — это не идентификатор аккаунта. В #/a405285491p550688232/ часть после a — это аккаунт, а часть после p — ресурс. Google намеренно не отличает «такого ресурса нет» от «нет прав» (само существование ресурса уже является сведением), поэтому неверный номер выглядит в точности как проблема с правами. Сначала проверьте идентификатор ресурса.

Никогда не выводите ресурс Search Console из домена. Только тот, кто подтвердил права, знает, ресурс это домена (sc-domain:) или префикс URL (https://…/), а неверный выбор возвращает пустой результат, а не ошибку.

3. Пригласите сервисный аккаунт в каждый ресурс

JSON — это лишь удостоверение личности; доступ выдаётся для каждого ресурса отдельно. Скопируйте client_email, показанный после сохранения, а затем:

Ресурс Где Роль
GA4 Администратор ▸ Управление доступом к ресурсу ▸ + Читатель
Search Console Настройки ▸ Пользователи и разрешения ▸ Добавить пользователя Полный доступ

В GA4 это управление доступом к ресурсу, а не к аккаунту (левый столбец — аккаунт, средний — ресурс). В Search Console нужен полный доступ, а не ограниченный: Search Analytics API отклоняет пользователей с ограниченными правами. У сервисных аккаунтов нет почтового ящика, поэтому снимите флажок «уведомить по электронной почте».

4. Проверьте подключение

[Проверить подключение] в окне управления один раз обращается к обоим API (за последние 7 дней), используя сохранённые учётные данные, и сообщает результат по каждой части отдельно.

Состояние Значение
ok Google ответил. Ноль строк — это тоже ok: новый сайт и отставание GSC не являются ошибками
fail Формулировка самого Google плюс client_email, который нужно пригласить
skip Ресурс не настроен, поэтому шаг пропущен (это не сбой)

Если учётных данных нет вовсе, не выполняется ни одного вызова (ноль исходящих запросов). Несохранённые изменения не проверяются — сначала сохраните.

Правила точности — почему числа считаются именно так

Они следуют ловушкам, уже доказанным опытом Site Kit, и каждая опирается на факты.

Правило Причина
Окно заканчивается вчерашним днём Сегодняшний день агрегирован лишь частично, поэтому его включение всегда обрушивает правый край
GA4 читает totals[0] из metricAggregations:['TOTAL'] Суммирование строк, к которым применён limit, занижает итоговое число
Фильтр по списку hostName в каждом запросе к GA4 Один ресурс часто охватывает несколько хостов, и без фильтра карточка показывает весь трафик ресурса. Мы передаём все домены, которыми владеет сервис (основной, дополнительные, www), чтобы точно совпасть с агрегацией vts на карточке
В рейтингах используются keepEmptyRows:false + notExpression{emptyFilter} Значение (not set) в GA4 регулярно обгоняет настоящие города и источники
Во временных рядах используется keepEmptyRows:true День без трафика не должен исчезать с оси
GSC использует dataState:'all' плюс отставание около 2 дней Без этого последние дни читаются как нули, что выглядит как обвал трафика
Ресурсы домена ограничиваются через 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 здесь работать не может. Зарегистрированные сайты принадлежат разным владельцам, а значит и разным аккаунтам Google, и один сервисный аккаунт читает только те ресурсы, в которые его пригласили: как только зарегистрированы сайты двух заказчиков, хотя бы один всегда будет давать отказ. Отсюда и поле, куда вставляют ключ для каждого сайта.

Поле учётных данных передаётся, только если вы его тронули. Форма никогда не получает закрытый ключ обратно, поэтому трактовка «не передано» как «очистить» стирала бы учётные данные каждый раз, когда кто-то правит одну лишь заметку. Явная очистка — единственный способ удаления.

Права доступа

Цель задаётся только идентификатором id зарегистрированного сайта — идентификатор ресурса нельзя передать параметром. Если бы вызывающая сторона могла назвать ресурс, права нашего сервисного аккаунта превратились бы в способ читать чужие ресурсы GA4 и Search Console (та же дисциплина защиты от SSRF, что и у живых проверок в Каталоге). Период точно так же ограничен на сервере значениями 7/28/90.

Диагностика · Частые вопросы

Смежные разделы

순 방문자 옆의 방문자 · 검색 아이콘
순 방문자 옆의 방문자 · 검색 아이콘