РКН и ссылки на Телеграм

С тех пор, как РКН начал блокировать Телеграм, прошло уже вроде больше месяца. Телеграм всё ещё жив. Но этот пост не про то, как немощен РКН, а про то, что все упустили из виду одну проблему.

Проблема

Домен t.me заблокирован у большинства пользователей.

В масштабах использования мессенджера это вообще не важно, потому что никак не влияет на отправку сообщений, файлов, стикеров и пр. Приложения чуть тормозят, но обходят блокировку. Домен же не меняет своего адреса, потому если у вас его заблокировали, сам он уже никак не разблокируется.

Многие пользуются VPN, потому даже не заметили этого. Но большинство для доступа к Телеграму используют SOCKS5-прокси, который никак не влияет на доступность домена. Потому, если вы где-то в интернете делитесь ссылкой на себя, на свой канал или на какой-то пост, то есть большая вероятность того, что по ней не смогут перейти.

Однако, РКН может заблокировать что угодно, но не может заблокировать принципы работы веба. Телеграм запускает приложение с помощью перехода по адресу, который начинается с протокола tg. Потому, если у пользователя уже установлено приложение, то заменив все ссылки на t.me ссылками с протоколом tg, можно сделать их все доступными независимо от блокировок.

Правда, тут возникает иная проблема. У пользователя может быть не установлено приложение, или из-за каких-то проблем схема может не сработать (например, пользователь установил себе бета-версию Телеграма, или какой-то вообще иной клиент, который по каким-то причинам не работает с протоколом tg). Потому легче совместить два решения в одно.

Решение

Если вы нажмёте на ссылку ниже, то увидите, о каком решении я говорю:

https://t.me/igoradamenko_channel

При открытии с десктопа пользователь попадёт на страницу, на которой написано о том, что происходит:

Если у него установлено приложение, то он увидит стандартный запрос:

Дальше всё как обычно.

На мобильных аналогичная история, даже проще. Там приложения могут перехватывать не только протоколы, но и целые адреса, потому обычно вы не видите страницы t.me, т. к. ОС сразу перенаправляет вас в приложение. С этим решением будет аналогичная история, потому что обычно на мобильных после перехода в приложение с помощью протокола, исходная страница закрывается. Потому пользователь тут тоже не увидит промежуточной страницы.

Относительно кода всё просто. Телеграм формирует ссылки примерно таким образом:

tg://resolve?domain=igoradamenko_channel # ссылка на канал или пользователя
tg://resolve?domain=igoradamenko_channel&post=454 # ссылка на конкретный пост в канале
tg://join?invite=ABCDEFGHIJKLMNOPQRSTUV # ссылка-инвайт

Потому всё, что от вас нужно, это переадресовать все телеграмные ссылки на какую-то промежуточную страницу, например так:

document.addEventListener('DOMContentLoaded', function () {
  [].slice
    .call(document.querySelectorAll('a[href^="https://t.me"]'))
    .forEach(function (x) {
      x.href = location.origin + '/tg.php?url=' + x.href;
      x.target = '_blank';
    });
});

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

<script>
  window.location.href = 'tg://resolve?domain=igoradamenko_channel'
</script>

У этого решения есть две проблемы.

Первая — Телеграм может поменять структуру ссылок. Но мы поверим, что они так не сделают.

Вторая — наличие промежуточной страницы. На самом деле этого можно избежать, если накодить кучу хаков. У браузеров различное поведение при переходе на страницы с протоколом, который не поддерживается (в нашем случае поддержки не будет, если у пользователя не установлен Телеграм), потому можно для каждого из них написать код, который будет это поведение обрабатывать, и если что, перенаправлять пользователя на t.me, а надежде, что страница у него откроется. На Гитхабе можно найти решения вроде custom-protocol-detection.

Однако, я решил выбрать более надёжное и явное решение. Такие дела ¯\_(ツ)_/¯.

2018
Популярное