Автопубликация статей в Telegram-канале с поддержкой Instant View

от
PHP/MySQL    telegram, бот, php

На нашем сайте уже давно используется автопубликация статей и прочей полезной информации в Telegram-канал. Хочу рассказать, как это сделано, а заодно и поведаю, как добавить поддержку Instant View, потому что автоматически она доступна только для популярных сайтов, для которых в Telegram написаны парсеры.

Для начала вкратце расскажу, как публикуется сообщение в канал. Допустим, на сайте произошло какое-то событие — добавлена новая статья. Мы должны отправить запрос к Telegram API, где указать содержимое нового сообщения, например "Дорогие друзья, на нашем сайте опубликована новая статья: <ссылка>". Это сообщение публикует бот, которого мы предварительно создали и добавили в канал в качестве администратора. Вот и вся магия. Теперь по порядку.


Шаг 1. Создание бота
Бота создаём при помощи @BotFather. Отправляем ему команду /newbot, затем имя и логин. В ответ получим информацию с токеном. Кто запутается, можете посмотреть видео https://youtu.be/jwzeBzfBvOo?t=19. У меня создание бота заняло 26 секунд с 19 по 45 секунду.


Шаг 2. Добавление бота в администраторы канала
Идём в Manage Channels -> Administrators -> Add administrator, ищем там своего бота и добавляем в канал как администратора.

add-bot.gif


Шаг 3. Обращение к Telegram Bot API
Здесь достаточно отправить GET-запрос с нужными параметрами, а именно: токен бота, идентификатор канала или группы, а также текст сообщения.
  1. public static function telegramSendMessage($botToken, $text, $chatId = '@annimon_com') {
  2.     $url = 'https://api.telegram.org/bot' . $botToken
  3.             . '/sendMessage?chat_id=' . $chatId
  4.             . '&text=' . urlencode($text);
  5.     $ch = curl_init();
  6.     curl_setopt_array($ch, [
  7.         CURLOPT_URL => $url,
  8.         CURLOPT_SSL_VERIFYHOST => false,
  9.         CURLOPT_SSL_VERIFYPEER => false,
  10.         CURLOPT_RETURNTRANSFER => true
  11.     ]);
  12.     $result = curl_exec($ch);
  13.     curl_close($ch);
  14.     return $result;
  15. }
Осталось только вызвать функцию при нужном событии на сайте:
  1. telegramSendMessage($telegramBotToken, 'Опубликована статья: https://annimon.com/article/' . $id, '@annimon_com');

Кстати, если у вас приватный канал, то chatId по имени не получить, в таком случае придётся один раз обратиться к боту через метод getUpdates: https://toster.ru/q/244962

shot-20171214T011858.png


Шаг 4. Добавляем парсер Instant View
Заходим на сайт https://instantview.telegram.org/, логинимся и жмём My Templates. Вводим ссылку на существующую статью на вашем сайте и жмём Enter. Попадаем в редактор.

shot-20171214T012929.png

Дальше нужно при помощи XPath получить со страницы необходимую информацию.

Можете посмотреть примеры в Sample Templates, они там с комментариями, или вот мой:
  1. # Parse all pages except the root page
  2. ?path: /.+
  3.  
  4. $header: //header
  5. $body: //*[@id="content"]
  6.  
  7. $title: $header//h1
  8.  
  9. $author: //a[@rel="author"]
  10. $author_url: $author/@href
  11.  
  12. $published_date: //meta[@property="article:published_time"]/@content
  13.  
  14. # code
  15. $code: //div[@class="backcode"]
  16. @remove: $code/div/div
  17. <code>: $code/div/ol
  18. <pre>: $code/div
  19.  
  20. # spoiler
  21. @remove: //div[@class="tops"]/..
  22. @remove: //div[@class="tops2"]/..

Для удобства обращения к часто используемым блокам, их можно сохранить в переменную (знак доллара необязателен, но с ним понятнее):
  1. $header: //header
  2. $code: //div[@class="backcode"]

Наша задача заполнить переменные:
   - title - заголовок
   - subtitle - подзаголовок (если есть)
   - author - имя автора
   - author_url - ссылка на профиль автора
   - published_date - дата публикации
   - body - содержимое статьи

Также по возможности нужно убрать лишнее специальной конструкцией $remove. Например, убрать спойлеры, оставив само их содержимое:
  1. @remove: //div[@class="tops"]/..
  2. @remove: //div[@class="tops2"]/..

Можно заменять теги. Вывод кодов у нас сделан с номером строк, поэтому их можно убрать и сам код обернуть в <pre><code>:
  1. $code: //div[@class="backcode"]
  2. @remove: $code/div/div
  3. <code>: $code/div/ol
  4. <pre>: $code/div

Как только всё будет готово, жмите вверху View in Telegram. Получится ссылка вот такого вида: https://t.me/iv?url=https%3A%2...rhash=8d520542820502

Теперь, чтобы Instant View был доступен, достаточно отправить сообщение с новой ссылкой:
  1. telegramSendMessage($telegramBotToken, 'Опубликована статья: https://t.me/iv?url=' . urlencode('https://annimon.com/article/' . $id) . '&rhash=8d520542820502');

shot-20171213T223215.png

Instant View справляется отлично. Показывает ролики с YouTube, обычные видео, даже музыку проигрывает.

telegram-article-iv.gif

Посмотреть результат в действии можно на нашем канале https://t.me/annimon_com
Помните, что Instant View поддерживается лишь на мобильных устройствах.
  • +9
  • views 7619