Есть одна очень удобная для пользователей штука - Telegram Instant View (IV). Она подгружает контент со ссылки прямо в приложении телеграма, показывая удобную для чтения версию и экономит трафик. Существует два официальных способа включить его для вашего сайта или блога:

  • Нерабочий: Добавить ваш шаблон в реестр шаблонов, а потом ждать аппрува. Который, возможно, никогда не наступит. Я свой отправил два (или даже три?) года назад, так ничего и не добавили.

  • Кривой: Формировать специальные ссылки с хешем вашего шаблона вроде t.me/iv?url=...&rhash=.... Это работает для ручного постинга (например в ваш канал), но не будет работать при отправке ссылки пользователями прямой ссылки. Требуется поддержка этого со стороны софта, который у вас делает кросс-постинг (если не ведёте канал руками). Кроме того, ссылки с rhash выглядят просто уродливо.

Есть один способ, как заставить Телеграм отображать Instantview глобально, для любых прямых ссылок вашего блога или сайта. Реализацию оформил в виде небольшого плагина для Wordpress. Так же, способ без проблем адаптируется для других платформ.

Изыскания

Я давно уже видел Instant View у ряда популярных медиа и новостных сайтов, и очень уже мне нравилась эта фича - удобная и красивая. Захотелось себе конечно - поэтому быстренько гуглим официальный мануал, делаем шаблон для нашего сайта, добавляем и садимся ждать. Ждём год, два или три - и ничего не происходит. Видимо, команда Телеграма добавляет вручную только для некоторых сайтов, в категорию которых мой маленький бложик не входит. Все шаблоны триггерятся по имени домена. Но, как оказалось - не все.

Пока я ждал, случайно заметил что у моего товарища его карманный блог (на своём домене) отображает Instantvew, и на мой вопрос «как ты это сделал?» - ответ никак, просто завёл себе акк на teletype. И в этой блогоплатформе можно прикрутить свой домен, и все ссылки всё равно будут отображаться как InstantView без плясок с бубном.

Дело в том, что данная блого-платформа использует недокументированный способ активации шаблона, а именно мета-тегом:

<meta property="tg:site_verification" content="g7j8/rPFXfhyrq5q0QQV7EsYWv4=">

На самом деле, одного тега недостаточно, необходимо ещё что бы контент был завернут в верстку определенной структуры. Мне удалось найти готовый сниппет на Github, за что огромное спасибо fishchev! Это сэкономило кучу времени. Собственно дальше способ напрашивается сам собой: если гора не идёт к Магомеду, то Магомед идёт к горе - будем подсовывать боту Телеграмма то, что он хочет увидеть :-)

Похоже, что Teletype - единственный с такой фичей, я просканировал список доменов из реестра шаблонов и не нашёл ни у кого подобных мета.

Реализация

Я веду свой бложик на Wordpress с автоматическим кросс-постингом в основные социальные сети через fs-poster. Плагин кросс-постинга очень удобный, легко расширяется и допиливается своими хуками (у меня сделан автоматический выбор разных шаблонов и формата поста в зависимости от типа социальной сети и содержания - длиннопост, картинка + описание и т.п.). Для примера реализуем свой плагин для Wordpress, что бы InstantView включался для всех постов в блоге и не требовал больше ничего. Готовый код плагина можно найти на Github или в Реестре плагинов.

Определяем бота Телеграма по юзер-агенту и суём ему другой шаблон:

<?php
function tgiv_instanview() {
    global $wp_query;
    // Activate only on single post page
    if (1 !== $wp_query->post_count) {
        return;
    }
    // Detect Telegram bot
    if ('TelegramBot (like TwitterBot)' == $_SERVER['HTTP_USER_AGENT']) {
        // Dsiplay special template to trigger IV
        require (dirname(__FILE__) . '/tg-display.php');
        // We are done, stop processing here
        exit();
    }
}
// Load replace function - just before header starts to be rendered
add_action('template_redirect', 'tgiv_instanview', 1);
?>

Данный минимальный код устанавливает хук на событие, когда Wordpress будет решать, какой шаблон ему выбрать. Добавляемся туда с высоким приоритетом и если нас смотрит бот - переходим на наш шаблон. В шаблоне тоже никакой магии:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta property="telegram:channel" content="@petro_ws">
    <meta property="tg:site_verification" content="g7j8/rPFXfhyrq5q0QQV7EsYWv4=">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<div id="content" class="site-content article">
<article class="article__content">
	<div class="entry-content">
		<div class="single-entry-thumb">
			<?php the_post_thumbnail(); ?>
		</div>
		<?php the_content(); ?>
	</div><!-- .entry-content -->
	<footer class="entry-footer">
	<?php
		if (get_the_category_list()) {
			?>
				<div class="cat-links">
					<?php the_category(', '); ?>
				</div>
			<?php
		}
		if (get_the_tag_list()) {
			?>
				<div class="tags-links">
					<?php the_tags('', ', '); ?>
				</div>
			<?php
		}
	?>
	</footer><!-- .entry-footer -->
</article><!-- #post-## -->
</div>
</body>

Данный шаблон выводит содержимое поста в нужном формате, список категорий, тегов а так же ссылку на ваш канал. Этого уже достаточно и InstantView начинает работать для любых ссылок на посты - без плясок с бубнами с rhash. Предосмотр будет показываться для ссылок отправленных как лично, так и в каналы, так же с использованием любых способов кросс-постинга.

Пример поста с InstantView
Пример поста с InstantView

Теперь чужой шаблон работает, но есть одна проблема: если в посте использована Галерея картинок, то он будет отображать только первую. Это происходит из-за того что Wordpress формирует набор вложенных тегов <figure>, что-бы исправить достаточно сделать ещё один небольшой хук и развернуть галерею при рендере в набор последовательных изображений:

<?php
function tgiv_extract_gallery($block_content)
{
    // Find all images
    if (preg_match_all('/<img[^>]+\/>/', $block_content, $out)) {
        $html = '';
        foreach($out[0] as $v) {
            $html .= '<figure class="wp-block-image size-large">'.$v.'</figure>';
        }
        return $html;
    }

    return $block_content;
}
add_filter('render_block_core/gallery', 'tgiv_extract_gallery');
?>

Теперь галереи отображаются как галереи:

Пример поста с галереей из двух изображений
Пример поста с галереей из двух изображений
Пример поста с галереей из трёх изображений
Пример поста с галереей из трёх изображений

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

Пример поста с кодом (к сожалению, без подсветки синтаксиса)
Пример поста с кодом (к сожалению, без подсветки синтаксиса)

Особенности

У Телеграма есть пара особенностей, о которых надо помнить:

  • Бот кеширует результат парсинга, и если определенная ссылка была уже запощена в Телеграм ранее, то бот второй раз ходить не будет. Возможно будет через какое-то время, как кеш протухнет. Можно заставить его перезапросить, если для теста модифицировать ссылку, вроде https://site.com/post/?a=1 , добавив мусор в query.

  • Фича InstantView есть только на мобильных платформах :-) Да, звучит глупо, но я реально убил некоторое время, пытаясь понять, почему у меня он не включается на десктопном клиенте.

Послесловие

Надеюсь, данная информация будет кому-то полезной. У меня бложик некоммерческий и без рекламы, следовательно InstantView будет приятной фичей для пользователей, а я только выигрываю снижением трафика и нагрузки.

Отдельно вызывает недоумение, почему команда Telegram не сделала этот способ официальным? Добавили бы возможность подсунуть свой несчастный rhash в определенный мета-тег и всё было бы намного проще для пользователей. Но в итоге запилили замечательную фичу и бросили на полпути недоделанной.

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

Комментарии (12)


  1. 13werwolf13
    12.04.2024 11:24
    +1

    • Фича InstantView есть только на мобильных платформах :-) Да, звучит глупо, но я реально убил некоторое время, пытаясь понять, почему у меня он не включается на десктопном клиенте.

    считаю это боооольшой недоработкой телеги, но увы со мной согласно так мало людей что видимо чуда не случится.


    1. omari0n
      12.04.2024 11:24

      Включи бета обновление и сразу получишь instanview на десктопе)


      1. 13werwolf13
        12.04.2024 11:24

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


  1. vindi
    12.04.2024 11:24

    Ссылки с telegra.ph открываются в instant view, например посты одного канала в десктопной версии выглядят так:

    OS: Windows 10, APP: Telegram Desktop 4.16.6


    1. petro_64 Автор
      12.04.2024 11:24

      В винду завезли видимо, может быть я из-за этого помнил - что вроде было, и тупил когда своей концепт тестил. У меня десктопный клиент под Linux и специально посмотрел ту же версию что у вас - там нет. Спасибо за замечание!


  1. php7
    12.04.2024 11:24

    А вообще отключить эти превьюшки при отправке допустим с компа?


    1. petro_64 Автор
      12.04.2024 11:24

      Как написал в посте - результат кэшируется, если ссылка была обработана ботом, то так и будет отправляться дальше любыми пользователями с любых клиентов. Но можно сделать параметры URL и ими контролировать отдачу шаблона боту, например ссылки типа https://example.com/post/?iv=0 , таким образом и кэш будет инвалидирован (так как ссылка поменялась), так и можно сделать логику, что отдавать боту. Можно кстати вообще ничего не отдавать, тогда не будет даже превью ссылки обычной.


      1. php7
        12.04.2024 11:24

        Я не хочу чтобы вставлялись превьюшки при отправке мной ссылок на левые сайты, ибо это бесит.


        1. petro_64 Автор
          12.04.2024 11:24

          При отправке превьюшку можно удалить, у меня по крайней мере так:

          По умолчанию наверное не настроить никак. Можете разве что открыть feature request или пропатчить самому :-)


          1. php7
            12.04.2024 11:24

            Вот именно по умолчанию и нужно.


      1. timurey
        12.04.2024 11:24
        +1

        Попробуйте обновить кэш бота с помощью @WebpageBot


  1. mihdan
    12.04.2024 11:24

    На десктопе на маке тоже работает instantview