phpdmitry / laravel-metrica-client-visits
Асинхронный поиск источников визитов Яндекс.Метрики по ClientID для Laravel.
Package info
github.com/phpdmitry/laravel-metrica-client-visits
pkg:composer/phpdmitry/laravel-metrica-client-visits
Requires
- php: ^8.2
- illuminate/bus: ^12.0 || ^13.0
- illuminate/cache: ^12.0 || ^13.0
- illuminate/console: ^12.0 || ^13.0
- illuminate/database: ^12.0 || ^13.0
- illuminate/http: ^12.0 || ^13.0
- illuminate/queue: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
Requires (Dev)
- orchestra/testbench: ^10.0 || ^11.0
- phpunit/phpunit: ^11.0
README
phpdmitry/laravel-metrica-client-visits асинхронно выгружает визиты Яндекс.Метрики по ClientID и сохраняет их в БД Laravel. Каждый импорт привязан к внутреннему бизнес-событию пользователя: регистрации, заявке, звонку или другому действию.
Пакет использует Logs API только для визитов (source=visits). Он не является универсальным SDK Метрики.
Установка
composer require phpdmitry/laravel-metrica-client-visits php artisan vendor:publish --tag=metrica-client-visits-config php artisan migrate
Нужны OAuth-токен с правом metrika:read, работающий Laravel queue worker и cache store с locks.
YANDEX_METRIKA_TOKEN=oauth-токен-с-правом-metrika-read YANDEX_METRIKA_COUNTER_ID=12345678 METRICA_CLIENT_VISITS_QUEUE=metrica-client-visits METRICA_CLIENT_VISITS_COUNTER_TIMEZONE=Europe/Moscow METRICA_CLIENT_VISITS_GOAL_TIMEZONE=Europe/Moscow METRICA_CLIENT_VISITS_TARIFF=free METRICA_CLIENT_VISITS_OPTIONAL_VISIT_FIELDS=
Импорт визитов
Публичная точка входа — VisitImporter. Импорт не ждёт Метрику: он создаёт batch и ставит задачи в очередь.
use PhpDmitry\MetricaClientVisits\Data\VisitImportRequest; use PhpDmitry\MetricaClientVisits\Data\VisitLookup; use PhpDmitry\MetricaClientVisits\VisitImporter; $batch = app(VisitImporter::class)->start(new VisitImportRequest( lookups: [ new VisitLookup( clientId: '1234567890123456789', occurredAtUnix: 1_777_386_720, // всегда UTC Unix timestamp eventName: 'Регистрация', ), new VisitLookup( clientId: '1234567890123456789', occurredAtUnix: 1_777_386_060, eventName: 'Оставил заявку', goalId: 42, // необязательная цель Метрики ), ], lookbackDays: 30, timeToleranceSeconds: 120, ));
eventName — внутреннее название события, а не цель Метрики. По умолчанию оно равно Целевое действие. Один import принимает до 1000 событий; 100 ClientID обрабатываются одним экспортом, если их периоды можно объединить.
Событие уникально в пределах счётчика по client_id + occurred_at + event_name. Повторный импорт этой же тройки заменяет её набор визитов и основной визит. Визиты, не связанные больше ни с одним событием, удаляются.
Вместо контейнера доступен фасад:
use PhpDmitry\MetricaClientVisits\Facades\MetricaClientVisits; $batch = MetricaClientVisits::start(new VisitImportRequest([ new VisitLookup('1234567890123456789', 1_777_386_720, 'Звонок'), ]));
Чтение данных из БД
Visit — самостоятельная постоянная модель визита. В ней доступны client_id, visit_id, started_at, duration_seconds, source, source_detail, utm_source, utm_medium, utm_campaign, utm_content, utm_term, referrer, start_url, goal_ids и goal_times.
Пакет запрашивает компактный набор полей для маркетингового анализа: источники, поисковые и социальные сети, кампании Яндекс Директа, Openstat, GCLID/SBCLID, все пять UTM-меток, реферер, посадочную/выходную страницу, географию, устройство, браузер и показатели визита. Полный перечень соответствует разделу «Визиты» документации Logs API; e-commerce, параметры визита и данные звонков не выгружаются.
Тариф задаётся через METRICA_CLIENT_VISITS_TARIFF: значение free используется по умолчанию и исключает недоступное бесплатным счётчикам поле ym:s:isRobotPro. Для Метрики Про укажите pro, чтобы включить его.
Поля, которые могут поддерживаться не всеми счётчиками, по умолчанию не запрашиваются. Включайте их только после проверки в своём счётчике: METRICA_CLIENT_VISITS_OPTIONAL_VISIT_FIELDS=sbclid,messenger,recommendation_system. Значения: sbclid (оба поля SBCLID), messenger, recommendation_system.
Все запрошенные поля также сохраняются в JSON-атрибуте data под исходными именами Logs API. Это удобно для редко используемых измерений, которые не имеют отдельной колонки в модели:
Все query-параметры посадочной страницы автоматически разбираются в JSON-атрибут landing_params. Это включает и нестандартные метки, например utm_regionid и utm_regionname; повторяющиеся ключи сохраняются массивом, пустые значения не теряются.
use PhpDmitry\MetricaClientVisits\Models\Visit; use PhpDmitry\MetricaClientVisits\Models\VisitEvent; $visits = Visit::query() ->whereIn('client_id', ['1234567890123456789']) ->orderBy('started_at') ->get(); foreach ($visits as $visit) { echo $visit->utm_source; echo $visit->utm_content; echo $visit->data['ym:s:<attribution>DirectClickOrderName']; echo $visit->landing_params['utm_regionid']; } $events = VisitEvent::query() ->where('client_id', '1234567890123456789') ->with(['visits', 'primaryVisit']) ->get(); foreach ($events as $event) { $event->event_name; // «Регистрация», «Заявка» и т. п. $event->visits; // все найденные визиты для этого события $event->primaryVisit; // один основной визит или null }
Один Visit может быть связан с несколькими VisitEvent: например, если одинаковый визит подходит и для регистрации, и для заявки. Основной визит хранится у события, поэтому контекст не теряется.
При goalId сначала выбирается визит с подтверждённой целью Метрики. Если цели нет или она не найдена, используется визит, покрывающий момент события; иначе — последний визит до события в пределах lookbackDays. В случае не найденной цели временной кандидат остаётся основным, а у события будет reason = goal_not_found.
Статус и очередь
$batch->refresh(); $batch->status(); // queued, planning, exporting, completed, completed_with_missing или failed $batch->isCompleted(); php artisan queue:work --queue=metrica-client-visits --timeout=110
Жизненный цикл: планирование периода → создание Logs-запроса → опрос статуса → загрузка TSV → сохранение Visit и связей с VisitEvent → выбор основного визита → удаление временного Logs-запроса в Метрике.
Полезные команды:
php artisan metrica-client-visits:status <batch-uuid> php artisan metrica-client-visits:stuck --minutes=45 php artisan metrica-client-visits:clean-pending --batch=<batch-uuid>
Миграция с прежней версии
Миграция пакета переносит старые VisitCandidate и VisitMatch в новые Visit, связи событий и primary_visit_id. Старым событиям присваивается название Целевое действие. Прежние таблицы намеренно не удаляются автоматически, но старые PHP API удалены: используйте VisitImporter, VisitLookup, Visit, VisitEvent.
Все временные значения хранятся и гидратируются как UTC. occurredAtUnix всегда передавайте в UTC.
Тестирование
composer test