PHPackages                             phpdmitry/laravel-metrica-client-visits - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. phpdmitry/laravel-metrica-client-visits

ActiveLibrary

phpdmitry/laravel-metrica-client-visits
=======================================

Асинхронный поиск источников визитов Яндекс.Метрики по ClientID для Laravel.

v0.2.2(today)014↑2900%MITPHPPHP ^8.2CI passing

Since Jul 23Pushed todayCompare

[ Source](https://github.com/phpdmitry/laravel-metrica-client-visits)[ Packagist](https://packagist.org/packages/phpdmitry/laravel-metrica-client-visits)[ RSS](/packages/phpdmitry-laravel-metrica-client-visits/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (9)Versions (8)Used By (0)

Laravel Metrica Client Visits
=============================

[](#laravel-metrica-client-visits)

Пакет для Laravel 12–13, который находит источник визита Яндекс.Метрики по `ClientID` и времени события. Он не является SDK Метрики: поддерживает только batch-поиск визитов через Logs API.

Вход — список событий `ClientID + Unix timestamp (UTC)`. Пакет строит один или несколько периодов выгрузки, асинхронно получает TSV через Logs API, сохраняет все визиты нужных клиентов, выбирает подходящий визит и очищает временную выгрузку в Метрике.

Полные логи счётчика не сохраняются.

Установка
---------

[](#установка)

```
composer require phpdmitry/laravel-metrica-client-visits
php artisan vendor:publish --tag=metrica-client-visits-config
php artisan migrate
```

Пакет использует обычные Laravel queue и cache. Redis не нужен. Для database-драйверов в приложении один раз создайте стандартные таблицы Laravel:

```
php artisan make:queue-table
php artisan make:cache-table
php artisan migrate
```

Запустите worker:

```
php artisan queue:work --timeout=110
```

Конфигурация
------------

[](#конфигурация)

В `.env` приложения задайте OAuth-токен Метрики с правом `metrika:read` и номер счётчика:

```
YANDEX_METRIKA_TOKEN=...
YANDEX_METRIKA_COUNTER_ID=12345678

QUEUE_CONNECTION=database
CACHE_STORE=database
DB_QUEUE_RETRY_AFTER=130
```

OAuth `client_id` и `client_secret` этому пакету не нужны: OAuth-flow он намеренно не выполняет. Все опции находятся в `config/metrica-client-visits.php`, в том числе часовой пояс счётчика, цель по умолчанию, лимит параллельных выгрузок и интервалы polling.

Нужно соблюдать: `HTTP timeout (90) < job timeout (110) < DB_QUEUE_RETRY_AFTER (130)`. Параметры `http_timeout_seconds`, `job_timeout_seconds` и `queue_retry_after_seconds` находятся в конфиге пакета; последнее значение служит ориентиром и не переопределяет настройку Laravel автоматически.

Использование
-------------

[](#использование)

```
use PhpDmitry\MetricaClientVisits\ClientEventMatcher;
use PhpDmitry\MetricaClientVisits\Data\BatchLookupRequest;
use PhpDmitry\MetricaClientVisits\Data\ClientEvent;

$batch = app(ClientEventMatcher::class)->start(new BatchLookupRequest(
    events: [
        new ClientEvent(
            externalId: 'amo-deal-123',
            clientId: '1234567890123456789',
            occurredAtUnix: 1700000000,
            goalId: 42, // null — использовать цель из config; disableGoalCheck: true — не проверять цель
        ),
    ],
    attribution: 'last',
    lookbackDays: 30,
    timeToleranceSeconds: 120,
    // selectionStrategy: 'first', // необязательно; по умолчанию — 'last'
));
```

Методы `$batch->status()`, `$batch->isCompleted()`, `$batch->matches()`, `$batch->missingEvents()` и `$batch->failedEvents()` дают состояние задачи и результаты. `$batch->matches()` сохраняет один лучший визит для обратной совместимости. В `metrica_visit_matches` доступны нормализованные поля: `source`, `source_detail`, `utm_source`, `utm_medium`, `utm_campaign`, `referrer`, `start_url` — без ключей `` из ответа Logs API.

### Все визиты и история повторных запросов

[](#все-визиты-и-история-повторных-запросов)

Каждый визит нужного `ClientID`, найденный в выгрузке, сохраняется как `VisitCandidate`, даже если он не станет лучшим совпадением. Кандидаты в batch отсортированы от раннего визита к позднему:

```
$candidates = $batch->candidates()->get();

foreach ($candidates as $visit) {
    $visit->visit_id;
    $visit->visit_started_at;
    $visit->duration_seconds;
    $visit->source;
    $visit->source_detail;
    $visit->utm_source;
    $visit->utm_medium;
    $visit->utm_campaign;
    $visit->referrer;
    $visit->start_url;
    $visit->goal_ids;
    $visit->goal_times;
}
```

`externalId` — стабильный бизнесовый идентификатор: менять его для повторного поиска не нужно. Новый `start()` с теми же параметрами создаёт новую выгрузку, если предыдущий batch уже завершён или завершился ошибкой. Только одновременно активный идентичный batch (`queued`, `planning`, `exporting`) возвращается повторно и не запускает второй экспорт.

Чтобы получить объединённую историю по `externalId`, включая результаты повторных выгрузок, используйте:

```
$visits = app(ClientEventMatcher::class)
    ->candidatesForExternalId('amo-deal-123');
```

В этом списке один `visit_id` встречается только один раз; при повторной загрузке сохраняются более актуальные данные. Результат также отсортирован от раннего визита к позднему.

По умолчанию селектор сохраняет прежнее поведение и выбирает самый поздний подходящий визит (`last`). Для отдельного batch можно указать `selectionStrategy: 'first'`; это влияет только на `VisitMatch`, а не на сохранение всех `VisitCandidate`.

Если указана цель, точным совпадением считается достижение этой цели рядом со временем события. Если цели в логе нет, событие получает `reason = goal_not_found`, но лучший временной кандидат всё равно сохраняется как `temporal_candidate`.

Обслуживание
------------

[](#обслуживание)

```
php artisan metrica-client-visits:status
php artisan metrica-client-visits:clean-pending
php artisan metrica-client-visits:stuck --minutes=30
```

Устойчивость к сбоям
--------------------

[](#устойчивость-к-сбоям)

- Для HTTP 429 учитывается заголовок `Retry-After`; остальные сетевые и серверные ошибки повторяются с backoff `15, 30, 60, 120, 300` секунд.
- POST создания выгрузки не повторяется автоматически при неопределённом результате. Сначала пакет получает список Logs-запросов и ищет точное совпадение. При отсутствии или неоднозначности совпадения запрос получает статус `creation_uncertain` или `creation_ambiguous`, а batch — `failed`, без риска создать дубликат.
- Ошибки polling и загрузки TSV ставят cleanup в очередь: уже созданный удалённый файл очищается даже при неуспешном batch.
- Внешние запросы ограничены по счётчику через Laravel rate limiter; экспорт дополнительно удерживает cache lock до cleanup.

Совместимость и разработка
--------------------------

[](#совместимость-и-разработка)

- Laravel 12: PHP 8.2–8.5.
- Laravel 13: PHP 8.3–8.5.

```
composer install
composer test
```

Старые `metrica-logs-*.php` в корне — самостоятельный CLI-прототип. Пакет на них не опирается и не поддерживает их как публичный API.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

7

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/65415315?v=4)[phpdmitry](/maintainers/phpdmitry)[@phpdmitry](https://github.com/phpdmitry)

---

Top Contributors

[![phpdmitry](https://avatars.githubusercontent.com/u/65415315?v=4)](https://github.com/phpdmitry "phpdmitry (7 commits)")

---

Tags

laravelyandexmetricalogs apiclientid

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/phpdmitry-laravel-metrica-client-visits/health.svg)

```
[![Health](https://phpackages.com/badges/phpdmitry-laravel-metrica-client-visits/health.svg)](https://phpackages.com/packages/phpdmitry-laravel-metrica-client-visits)
```

###  Alternatives

[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k96.5k1](/packages/mike-bronner-laravel-model-caching)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[flarum/core

Delightfully simple forum software.

201.4M2.4k](/packages/flarum-core)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
