Яндекс Метрика API: Счётчик Просмотров

В данном руководстве рассмотрим работу с API Метрики от Яндекса. Создадим счётчик просмотров страниц (статей).

Первое и самое важное, без чего невозможно продолжать - у вас должен быть подключен счётчик Яндекс.Метрики.

Далее порядок действий следующий.

  1. Получение OAuth-токена.
  2. Формируем запрос для получения данных + сохранение на вашем сервере.
  3. Настройка CRON (планировщика) для выполнения php-файла, который сохраняет (обновляет) данные метрики.
  4. Вывод количества просмотров на страницу.

1. Получаем OAuth-токен

Чтобы получить OAuth-токен перейдите на страницу создания приложения.

Регистрация приложения API Метрики

Обязательным для заполнения является поле Название приложения* - можете использовать любое.

Далее в секции Платформы выбираете чекбокс Веб-сервисы и нажмите на ссылку Подставить URL для разработки.

Веб-сервисы API метрики

Затем в секции Доступы* нажимаем на Яндекс.Метрика и выбираем чекбокс Получение статистики, чтение параметров своих и доверенных счётчиков.

Получение статистики API Яндекс метрики

Нажимаем Создать приложение.

Создение приложения API Метрики

На странице увидите следующие данные:

  1. ID: - 1e9c7ch29d533fa5abc9f04b6f6g71b3
  2. Пароль: - 3927fad02b854da9ka40f2d535f94e0u
  3. Callback URL - https://oauth.yandex.ru/verification_code

Теперь необходимо в адресной строке ввести следующий URL и вставить ваш ID.

https://oauth.yandex.ru/authorize?response_type=token&client_id=ваш_ID

После отправки данного запроса, нужно разрешить доступ приложению к вашим данным.

Разрешение на получение статистики Яндекс Метрики

На странице появится ваш OAuth-токен

2. Формирование запроса и сохранение полученных данных

Нам необходимо сформировать запрос для получения данных от Яндекс.Метрики и сохранить пришедшие данные (JSON) на сервере.

Создадим файл metric-api.php:

<?php

$options = array(
    "http" => array(
        "method" => "GET",
        "header" => array(
            "Content-Type: application/x-yametrika+json",
            "Authorization: OAuth ваш_токен"
        )
    )
);

$context = stream_context_create($options);

$url = "https://api-metrika.yandex.ru/stat/v1/data";

$parameters = [
    "ids"               => "",                            // номер счётчика метрики
    "metrics"           => "ym:pv:pageviews,ym:pv:users", // данные по: страницам и количеству просмотров
    "dimensions"        => "ym:pv:URLHash",               // группировка по URLHash
    "date1"             => "2018-09-01",                  // с какой даты получить отчёт
    "accuracy"          => "full",                        // точная статистика (без округления)
    "limit"             => "100000",                      // максимальный лимит данных
    "proposed_accuracy" => "false"                        // без округления данных
];

array_walk($parameters, function (&$key, $value) {
    return $key = "$value=$key";
});

$parameters = implode($parameters, "&");

$url = $url . "?&" . $parameters;

$metrikaRequest = file_get_contents($url, false, $context);

if (!empty($metrikaRequest)) {
    file_put_contents($_SERVER["DOCUMENT_ROOT"] . "/metrics.json", $metrikaRequest);
};

Обратите внимание на аргументы:

  • Authorization - после слова "OAuth" введите токен, полученный в предыдущем пункте;
  • ids - номер счетчика (можно посмотреть здесь);
  • date1 - с какой даты получать отчёт;
  • file_put_contents - куда сохранять полученный JSON-файл.

Если по каким-либо причинам, вы получите ошибку, можно заменить file_get_contents на curl.
Пример ошибки:

Warning: file_get_contents: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden

Получение данных с помощью cURL php

Изменим немного наш код, переписав с функции file_get_contents на cURL.

Изменённый код:

<?php

ini_set("error_reporting", E_ALL);
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);

$parameters = array(
    "ids"               => "",                            // номер счётчика метрики
    "metrics"           => "ym:pv:pageviews,ym:pv:users", // данные по: страницам и количеству просмотров
    "dimensions"        => "ym:pv:URLHash",               // группировка по URLHash
    "date1"             => "2018-09-01",                  // с какой даты получить отчёт
    "date2"             => "today",                       // до какой
    "accuracy"          => "full",                        // точная статистика (без округления)
    "limit"             => "100000",                      // максимальный лимит данных
    "proposed_accuracy" => "false"                        // без округления данных
);

array_walk($parameters, function (&$key, $value) {
    return $key = "$value=$key";
});

$parameters = implode("&", $parameters);

$url = "https://api-metrika.yandex.net/stat/v1/data" . "?" . $parameters;

function get_file_curl($url)
{
    $ch = curl_init();
    $headers = [
        "Content-type: application/x-yametrika+json",
        "Authorization: OAuth ваш_токен",
    ];

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Чтобы curl возвращал данные, вместо того, чтобы выводить их в браузер.
    curl_setopt($ch, CURLOPT_URL, $url);

    $data = curl_exec($ch);
    curl_close($ch);

    return $data;
}

$metrikaRequest = get_file_curl($url);

// echo $metrikaRequest;

if (!empty($metrikaRequest)) {
    file_put_contents($_SERVER["DOCUMENT_ROOT"] . "/metriks.json", $metrikaRequest);
};

Отлично! Мы создали php-файл, который будет получать и сохранять данные API Метрики на нашем сервере.

3. Настройка планировщика

Теперь нам необходимо настроить CRON (планировщик), чтобы наш файл metric-api.php отрабатывал (выполнялся) спустя определённое время, например, каждый час. Т.е. каждый час будет выполняться запрос на получение данных Яндекс.Метрики и обновлять файл, вносить свежие данные в metrics.json.

В панели управления хостингом необходимо перейти во вкладку Планировщик (Crontab).

Планировщик на хостинге

Ввести первую или вторую команду и выбрать периодичность исполнения файла:

Используя php:

php полный_путь_до_файла/metric-api.php

Или используя wget:

wget -O- ваш_домен/metric-api.php

4. Создание счётчика просмотров страницы

Создадим счётчик просмотров страницы с помощью JavaScript. Как вы помните, мы получаем данные по:

  1. страницам (url) - ym:pv:pageviews и
  2. просмотрам - ym:pv:users

Используя регулярные выражения, будем соотносить адрес текущей страницы и данные Яндекс метрики. При совпадении url текущей страницы и url метрики будем выводить количество просмотров этой страницы.

// Yandex metrika API
(function () {

    setTimeout(function () {

        // определяем текущий URL без домена и http
        const locationUrl = window.location.pathname;

        // формируем XMLHttpRequest
        const xmlhttpMetrika = new XMLHttpRequest();

        xmlhttpMetrika.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {

                // переводим данные из JSON в вид ассоциативного массива
                let metrikaData = JSON.parse(this.responseText)["data"],
                    summCountPeople = 0;

                // с помощью регулярного сравниваем данные Метрики и текущего URL
                if (locationUrl.slice(-1) == "/") {
                    const regExpForMetrika = new RegExp("(\\/\\/домен\\.ru\\" + locationUrl.substring(0, locationUrl.length - 1) + "\\/)($|\\?.*)");
                } else {
                    const regExpForMetrika = new RegExp("(\\/\\/домен\\.ru\\" + locationUrl + ")($|\\?.*)");
                }
                metrikaData.forEach(function (elem) {
                    if (regExpForMetrika.test(elem["dimensions"][0]["name"])) {
                        summCountPeople += elem["metrics"][0];
                    }
                })
                const countElem = document.createElement("span"); // создаём новый элемент
                countElem.className = "countPeople"; // присваиваем элементу класс
                countElem.innerHTML = "👁" + summCountPeople;

                const view_counter = document.getElementById("view_counter");

                if (view_counter) { // если страница поста
                    if (summCountPeople > 0) { // показываем счётчик, если количество просмотров > 0
                        view_counter.appendChild(countElem); // вставляем на страницу
                    }
                }
            }
        };
        xmlhttpMetrika.open("GET", "/metrics.json", true);
        xmlhttpMetrika.send();

    }, 1000);

})();

Домен - замените на свой.

Данный код выполняется с задержкой setTimeout в одну секунду, чтобы не замедлять скорость загрузки страницы. Можете изменить данное значение.

Используя Fetch API

Код будет работать аналогичным образом, но будет написан с помощью более современного метода fetch().

setTimeout(function () { // выполнять функцию через 1000 ms

    (function () {
        getResource("/metrics.json") //источник
            .then(data => createViewCounter(data)) // передаём ответ от сервера
            .catch(err => console.error(err));
    }());

    async function getResource(url) {
        const res = await fetch(url); // ждём ответ, только тогда наш код пойдёт дальше

        if (!res.ok) { // не 200
            throw new Error(`Не удалось получить ${url}, статус: ${res.status}`);
        }
        return await res.json();
    }

    function createViewCounter(metrikaResponse) {

        const locationUrl = window.location.pathname; // определяем текущий URL без домена и http
        let summCountPeople = 0;
        let regExpForMetrika = "";

        if (locationUrl.slice(-1) == "/") {
            regExpForMetrika
                = new RegExp("(\\/\\/домен\\.ru\\" + locationUrl.substring(0, locationUrl.length - 1) + "\\/)($|\\?.*)");
        } else {
            regExpForMetrika = new RegExp("(\\/\\/домен\\.ru\\" + locationUrl + ")($|\\?.*)");
        };
        metrikaResponse["data"].forEach(function (el) {
            if (regExpForMetrika.test(el["dimensions"][0]["name"])) {
                summCountPeople += el["metrics"][0];
            }
        });
        let countElem = document.createElement("span"); // создаём новый элемент для вставки на страницу
        countElem.className = "countPeople"; // присваиваем элементу класс countPeople
        countElem.innerHTML = "👁" + summCountPeople; // добавляем иконку "глаза"

        let view_counter = document.getElementById("view_counter");

        if (summCountPeople > 0) { // показываем счётчик, только если количество просмотров больше нуля
            view_counter.appendChild(countElem); // вставляем на страницу
        }

    };

}, 1000);