Как стать автором
Обновить

Интеграция с Яндекс Метрикой и выгрузка данных .NET

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров318

Введение

В этой статье рассмотрим краткий алгоритм работы с API Яндекс Метрики, включая авторизацию, получение данных и их синхронизацию с БД.

Подготовка

Важно! Для любого взаимодействия с API, необходимо получить токен авторизации. Но так как он не живет сам по себе, а выдается приложению, то сначала необходимо зарегистрировать приложение от имени аккаунта.

Создание приложения в Яндекс OAuth

1. Регистрируем приложение

Заполняем форму на https://oauth.yandex.ru/client/new. Обязательно сделать следующее:

  • Укажите название приложения.

  • В разделе Callback URI: Нажмите "Подставить URL для разработки"

    Или введите https://oauth.yandex.ru/verification_code

  • В разделе "Доступ к данным" выберите то, что вам нужно, например:

    "Яндекс.Метрика"

    "Получение статистики, чтение параметров своих и доверенных источников"

В итоге после регистрации вы получите информацию о приложении в частности Client ID, от имени которого будет выдаваться токен.

2. Разрешаем приложению доступ - получаем токен

  • Заходим на Яндекс с учетной записью пользователя, к аккаунту которого приложение должно запросить доступ. (Он может отличаться от аккаунта, из-под которого было создано приложение, но может и совпадать.)

  • Взять идентификтор приложения, подставить его в адрес
    https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор приложения>
    и открыть страницу. Нажать Разрешить.

  • Яндекс OAuth перенаправит вас на страницу с токеном и добавит данные токена после символа #:

    https://oauth.yandex.ru/verification_code#access_token=<новый OAuth-токен>&expires_in=<время жизни токена в секундах>

Важно! Необходимо сохранить полученный токен, так как Яндекс не хранит его в открытом доступе.

И так этот токен конкретно для каждого аккаунта(компании) его следует хранить в базе данных и использовать для получения данных по API. Например, можно сделать так:

  1. Получить сгенерированную ссылку для oauth с уже подставленным client_id https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор приложения>

  2. Перейти по ссылке дать разрешения на доступ.

  3. После редиректа получить токен авторизации и сохранить его для данного пользователя(компании)

Работа с API на примере метрики "Возрастные интервалы"

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

Архитектура решения

Note: Архитектура может быть какой угодно, это лишь пример.

Решение построено на следующих ключевых компонентах:

  1. YandexMetricaAgeIntervalSyncService - основной сервис для синхронизации данных

  2. YandexMetricaApiAgeIntervalService - клиент для работы с API Яндекс Метрики

  3. YandexMetricaApiClient - общий HTTP-клиент для всех запросов

  4. AgeIntervalEntity - модель данных для хранения возрастных интервалов

Цикл работы с данными

1. Синхронизация возрастных интервалов

Основной метод синхронизации:

  • Получение данных:

    • Использует OAuth‑токен из настроек интеграции

    • Запрашивает данные за указанный период (from‑to)

    • Применяет переданные фильтры сегментов

  • Преобразование данных:

    • Группирует по датам (последний элемент Dimensions)

    • Парсит возрастные интервалы (первый элемент Dimensions)

    • Сопоставляет с enum AgeIntervalTypes

    • Заполняет соответствующие свойства сущности AgeIntervalEntity

  • Сохранение в БД.

  • Типы возрастных интервалов:

    • UpTo18Age (до 18)

    • UpTo24Age (18-24)

    • UpTo34Age (25-34)

    • UpTo44Age (35-44)

    • UpTo54Age (45-54)

    • Over54Age (55+)

public async Task SyncAgeIntervalAsync(long companyId, long[] counterIds, string[] segmentFilters, DateOnly from, DateOnly to, CancellationToken cancellationToken)
{
    // Получаем настройки интеграции для конткретной компании
    YandexMetricaIntegrationSettings setting = await _metricaIntegrationSettingsRepository
        .GetByCompanyIdAsync(companyId, cancellationToken);

    // Получаем данные из API
    var response = await GetAgeIntervalAsync(
        setting.Settings.AccessToken, 
        segmentFilters, 
        from, 
        to, 
        counterIds, 
        cancellationToken);

    // Группируем данные по датам
    List<IGrouping<string, AgeInterval>> ageIntervals = 
        response.GroupBy(a => a.Dimensions.Last().Name).ToList();

    var ageIntervalEntities = new List();

    // Преобразуем данные API в сущности
    foreach (IGrouping data in ageIntervals)
    {
        DateOnly actualDay = data.Key.ParseDateOnlyFromFormattedString();

        var ageInterval = new AgeIntervalEntity
        {
            Date = actualDay,
            CompanyId = companyId
        };

        foreach (AgeInterval value in data)
        {
            AgeIntervalTypes ageIntervalType = (AgeIntervalTypes)int.Parse(value.Dimensions[0].Id);
            switch (ageIntervalType)
            {
                case AgeIntervalTypes.UpTo18Age:
                case AgeIntervalTypes.UpTo24Age:
                case AgeIntervalTypes.UpTo34Age:
                case AgeIntervalTypes.UpTo44Age:
                case AgeIntervalTypes.UpTo54Age:
                case AgeIntervalTypes.Over54Age:
                    ageInterval.GetType()
                        .GetProperty(ageIntervalType.ToString())?
                        .SetValue(ageInterval, value.Metrics[0]!.Value);
                    break;
            }
        }

        newAgeIntervalEntities.Add(ageInterval);
    }

    // Сохраняем в БД
    _ = await _ageIntervalRepository.SaveAsync(ageIntervalEntities, cancellationToken);

    return Result.Success();
}

// Парсинг строки в формате "yyyy-MM-dd" в объект типа DateOnly.
public static DateOnly ParseDateOnlyFromFormattedString(this string value)
{
  return DateOnly.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
}

2. Работа с API Яндекс Метрики

  • Метод формирует запрос к API через сервис _metricaAgeIntervalService.

  • В запросе указываются все необходимые параметры для построения запроса, токен, счетчики, фильтры, даты, вид группировки (GroupTypes.Day).

  • После отправки запроса метод ожидает ответа от API в виде объекта AgeIntervalResponse.

  • Из полученного ответа извлекаются данные (ageIntervalResponse.Data) и преобразуются в массив типа AgeInterval[].

  • Результат возвращается в виде массива возрастных интервалов.

public async  Task<Result<AgeInterval[]>> GetAgeIntervalAsync(
    string accessToken, 
    string[] filters, 
    DateOnly from, 
    DateOnly to, 
    long[] counterIds, 
    CancellationToken cancellationToken)
{
    // Формируем и отправляем запрос
    AgeIntervalResponse ageIntervalResponse = await _metricaAgeIntervalService
        .GetAgeIntervalApiAsync(new GetAgeIntervalRequest(
            accessToken,     // авторизационный токен
            counterIds,      // счетчики, по которым велась статистика
            filters,         // примененные фильтры, обычно это сегменты
            from,            // дата "С"
            to,              // дата "До"
            GroupTypes.Day), // группировка статистики "по дням"
        cancellationToken);

     return ageIntervalResponse.Data.ToArray();
}

Реализация API клиента:

В данном методе происходит построение запроса непосредственно к API Метрики, в параметры запроса "вшиваются" счетчики по которым велась статистика, фильтры, даты в требуемом формате, вид группировки(по дням).

public async Task GetAgeIntervalApiAsync(
    GetAgeIntervalRequest request, 
    CancellationToken cancellationToken)
{
    // Формируем параметры запроса
  
    //Счетчики приложения
    string countersIdsString = string.Join(",", request.CountersIds);
    //Применяем фильтры
    string filtersString = string.Join(" OR ", request.Filters);

    var queryParams = new Dictionary
    {
        { "date1", request.From.ToString("yyyy-MM-dd") },
        { "date2", request.To.ToString("yyyy-MM-dd") },
        { "ids", countersIdsString },
        { "group", request.GroupBy.ToString().ToLower() },
        { "filters", filtersString }
    };

    // Формируем URL запроса
    string endPoint = _yandexMetricaOptions.GetAgeIntervalEndPoint;
    string queryString = string.Join("&", queryParams.Select(x => $"{x.Key}={x.Value}"));

    string separator = endPoint.Contains('?') ? "&" : "?";
    string url = $"{endPoint}{separator}{queryString}";

    // Отправляем запрос
    var getRequest = new GetRequest(request.AccessToken, url);
    return await _yandexMetricaApiClient.GetAsync(getRequest, cancellationToken);
}

3. Модели данных

Модель для хранения в базе данных, статистика интервалов возрастов за день :

public class AgeIntervalEntity : YandexMetricaExportEntityBase
{
    public DateOnly Date { get; set; }

    /// <summary>Возраст до 18 лет.</summary>
    public double UpTo18Age { get; set; }

    /// <summary>Возраст от 18 до 24 лет.</summary>
    public double UpTo24Age { get; set; }

    /// <summary>Возраст от 25 до 34 лет.</summary>
    public double UpTo34Age { get; set; }

    /// <summary>Возраст от 35 до 45 лет.</summary>
    public double UpTo44Age { get; set; }

    /// <summary>Возраст от 45 до 55 лет.</summary>
    public double UpTo54Age { get; set; }

    /// <summary>Более 55 лет.</summary>
    public double Over54Age { get; set; }
}

Модель ответа от API:

public class AgeInterval
{
    /// <summary>Информация об метриках(Названия).</summary>
    public SiteAudienceDimension[] Dimensions { get; set; } = null!;

    /// <summary>Метрики.</summary>
    public double?[] Metrics { get; set; } = null!;
}

public class SiteAudienceDimension
{
    /// <summary>Названия.</summary>
    public string Name { get; set; } = null!;

    /// <summary>Идентификатор метрики.</summary>
    public string Id { get; set; } = null!;
}

5. Конфигурация

Настройки endpoint'ов в конфигурации:

"YandexMetrica": {
    "BaseApiUrl": "https://api-metrika.yandex.net",
    "GetAgeIntervalEndPoint": "stat/v1/data?metrics=ym:s:visits&dimensions=ym:s:ageInterval,ym:s:date&accuracy=full&limit=10000&sort=ym:s:date",
    // другие конечные точки и настройки...
}

Заключение

В заключении приведу ссылку на примеры создания запросов для других метрик из официальной документации Примеры | API Яндекс Метрики. Приведенный выше вариант интеграции лишь пример, но работающий. В любом случае при составлении запросов к API Метрики, советую сравнивать полученные данные с данными, которые отображаются в самой Метрике и учитывать специфику задачи, которая перед вами стоит.

Теги:
Хабы:
+1
Комментарии0

Публикации

Работа

Ближайшие события