Окт
20
2021

Добавляем IndexNow в Битрикс

В октябре 2021 года Яндекс презентовал новый протокол для "ускорения интернета". Он позволяет оповещать поисковики об изменениях на сайте через API. Теперь не надо ждать пока поисковой робот зайдет на сайт и заметит новую/обновленную страницу.

Распространение IndexNow началось 18 октября 2021 г. на условиях лицензии Attribution-ShareAlike Creative Commons License. Однако доступен этот протокол далеко не всем поисковикам. Как сообщили CNews представители «Яндекса», протокол работает исключительно в Bing (принадлежит Microsoft) и в поисковой системе самого «Яндекса».

Как работать с IndexNow в Bitrix

Наш алгоритм:

  1. Создать ключ для проверки прав сайта Яндексом
  2. Добавить событие на обновление элементов инфоблока
  3. Получить адрес на сайте обновленного элемента
  4. Отправить информацию в Яндекс

Ключ для проверки прав сайта

Первым делом можно придумать ключ. Состоять он может из латинских символов, цифр и тире. Длина - от 8 до 128 символов.

Чтобы в будущем понимать для чего этот ключ, начните его с indexnow-. Себе я, например, сделаю ключ indexnow-EkpkVj75fj.

Теперь в корне сайта надо создать файл где имя файла - ваш-ключ.txt, контент файла - этот же ключ.

Наш файл должен открываться по адресу https://наш_сайт.ру/indexnow-EkpkVj75fj.txt

Событие на обновление элементов

В файл local/php_inerface/init.php или, если его нет, то в файл /bitrix/php_interface/init.php, добавьте следующий код:

<?
// Добавляем события на добавление, обновление, удаление элементов
AddEventHandler('iblock', 'OnAfterIBlockElementAdd', ['IndexNow', 'onElementAdd']);
AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', ['IndexNow', 'onElementUpdate']);
AddEventHandler('iblock', 'OnBeforeIBlockElementDelete', ['IndexNow', 'onElementDelete']);

class IndexNow {
    const KEY = 'indexnow-EkpkVj75fj'; // ключ, который сохранили в корень сайта
    const HOST = 'r-morozov.ru'; // хост сайта

    // Событие при добавлении элемента
    public static function onElementAdd(&$arFields) {
        if (! $arFields['ID']) {
            return;
        }

        self::addIblockElement($arFields['ID']);
    }

    // Событие при обновлении элемента
    public static function onElementUpdate(&$arFields) {
        if (! $arFields['RESULT']) {
            return;
        }

        self::addIblockElement($arFields['ID']);
    }

    // Событие при удалении элемента
    public static function onElementDelete($id) {
        self::addIblockElement($id);
    }

    // Добавляем ссылку на элемент в очередь на отправку в IndexNow
    public static function addIblockElement($id) {
        $detailPage = self::getDetailPageUrl($id);

        if (! $detailPage) {
            return;
        }

        self::saveLink('https://' . self::HOST . $detailPage);
    }

    // Получить ссылку на элемент инфоблока
    public static function getDetailPageUrl($id) {
        $res = CIBlockElement::GetList([], [
            'ID' => $id,
        ], false, false, [
            'ID', 'IBLOCK_ID', 'DETAIL_PAGE_URL',
        ]);

        if ($arItem = $res->GetNext() and ! empty($arItem['DETAIL_PAGE_URL'])) {
            return $arItem['DETAIL_PAGE_URL'];
        }
    }

    // Сохранить ссылку в очередь
    public static function saveLink($link)
    {
        file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt', $link . PHP_EOL, FILE_APPEND);
    }

    // Отправить все ссылки в IndexNow
    public static function executeLinks()
    {
        $links = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt');
        $links = explode(PHP_EOL, $links);
        $links = array_unique($links);
        $links = array_filter($links);
        $links = array_values($links);

        if (! count($links)) {
            return;
        }

        file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt', '');
        $result = self::sendLinks($links);

        if ($result['success'] !== true) {
            // Если неуспешно - вывести ошибку в панели администратора
            CAdminNotify::Add([
                'MESSAGE' => 'Произошла ошибка при работе IndexNow. Сообщение: "' . $result['message'] . '"',
                'TAG' => 'INDEX_NOW',
                'NOTIFY_TYPE' => CAdminNotify::TYPE_ERROR
            ]);
        }
    }

    // Отправить ссылки в IndexNow
    public static function sendLinks($links) {
        $payload = json_encode([
            'host' => self::HOST,
            'key' => self::KEY,
            'urlList' => $links,
        ]);

        $ch = curl_init('https://yandex.com/indexnow');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );

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

        return json_decode($result, true);
    }
}

Так же создайте файл /local/executeIndexnow.php с контентом:

<?php
$_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__ . '/..');

include $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
IndexNow::executeLinks();
include $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php';

И добавьте запуск файла /local/executeIndexnow.php в крон раз в минуту.

Как добавить крон задание

Тестирование

Чтобы протестировать всё ли запускается и уходит:

  1. Пересохраните запись в инфоблоке в админке
  2. Проверьте создался ли файл /upload/indexnow.txt, в котором должна быть ссылка на пересохраненную запись. (на публичную часть).
  3. Откройте через браузер файл /local/executeIndexnow.php.
  4. Перейдите в панель администратора - ошибок быть не должно. Файл /upload/indexnow.txt должен очиститься.

Пример ошибки в админке:

Ошибка IndexNow в Битрикс

Смотрите так же: отправка ссылок в IndexNow Online для любых CMS!

Вопросы

Надо ли отправлять запросы во все поисковые системы?

Хотя IndexNow использует на данный момент 2 поисковика, отправлять данные везде не стоит. Согласно протокола, поисковые системы, подключенные к IndexNow оповещают об изменениях друг друга самостоятельно. Достаточно отправить данные в одну из систем.

Как часто можно отправлять ссылки?

Яндекс говорит так: ограничений никаких нет, можно отправлять данные в любом количестве и с любой скоростью.

Но в то же время упоминается ответ HTTP 429 Too Many Requests, который говорит о том, что данные отправляются слишком часто.

Я отправил URL-адрес, что будет дальше?

IndexNow.org:

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

Что значит «понравится» ваш URL-адрес - не уточняется.

Я отправил URL-адрес, но не вижу, что он проиндексирован.

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

У меня используется несколько доменов, могу ли я использовать один ключ?

Один ключ можно использовать на неограниченном количестве доменов, но файл с ключем надо разместить на всех сайтах.

Помощь с добавлением IndexNow на ваш сайт

Если вам требуется помощь, пишите в телеграм:

Пожалуйста, оцените на сколько вам понравилась статья!
Голосов: 8 Среднее: 3.6