Разбираю неожиданные проблемы cross-platform onboarding между Telegram Mini Apps и native apps.
Недавно я столкнулся с неожиданной проблемой при разработке Telegram Mini App onboarding flow для native networking клиента.
На старте мне казалось, что весь onboarding займет буквально пару часов:
открыть deeplink → импортировать подписку → подключиться.
Но на практике именно эта часть оказалась самой нестабильной во всем проекте.
На первый взгляд задача выглядела довольно простой:
Telegram Mini App ↓ happ://... ↓ native app ↓ import subscription ↓ connect
Но на практике оказалось, что custom URI schemes внутри Telegram Mini Apps ведут себя совершенно по-разному:
Android открывает deeplink стабильно;
iOS блокирует часть сценариев;
Windows имеет собственные ограничения;
Linux Desktop ведет себя нестабильно и пока остается самой непредсказуемой платформой.
В итоге самой сложной частью проекта оказался вовсе не backend, а cross-platform onboarding UX.
Архитектура flow
Текущая схема выглядит так:
Telegram Bot ↓ Mini App (Vue 3 + Telegram WebApp API) ↓ FastAPI Backend ↓ crypto API → encrypted deeplink ↓ happ://... ↓ Happ Client ↓ subscription import ↓ connect
Для разных платформ пришлось использовать разные форматы ссылок:
Android: happ://crypt5/BASE64 iOS / Windows: happ://add/https://sub.example.com/sub/TOKEN Install redirect: https://app.example.com/install?url=happ%3A%2F%2Fadd%2F...
Android: crypt5 работает, но не совсем
На Android изначально использовался encrypted deeplink формата:
happ://crypt5/BASE64
Ссылка генерируется через внешний crypto API.
Первой неожиданной проблемой стало то, что API возвращал два склеенных base64-блока.
Сначала казалось, что нужно обрезать ответ на backend стороне.
После нескольких тестов выяснилось, что Android-клиент Happ ожидает именно полный оригинальный ответ от crypto API.
То есть проблема была не в “лишних символах”, а в особенностях internal parser внутри Android-клиента.
iOS: Telegram WebView против custom schemes
Самой проблемной платформой оказался iOS.
Прямые варианты вроде:
window.open('happ://...')
или:
telegram.openLink('happ://...')
не работали внутри Telegram WebView.
iOS блокирует custom URI schemes, если вызов не проходит через корректный browser/user interaction flow.
В итоге рабочим решением оказался промежуточный install page:
telegram.openLink( 'https://app.example.com/install?url=happ%3A%2F%2Fadd%2F...' )
А внутри install page:
window.location.href = url
На удивление именно такой redirect-flow оказался наиболее стабильным.
Windows: crypt5 не поддерживается
Windows-версия Happ неожиданно отказалась принимать encrypted crypt5 ссылки.
Клиент возвращал ошибку:
Invalid subscription link format
При этом обычный deeplink работал нормально:
happ://add/https://sub.example.com/sub/TOKEN
В результате для Windows пришлось отказаться от crypt5 flow и использовать прямой subscription import.
Интересно, что браузер после открытия схемы автоматически закрывал вкладку, из-за чего UX на Windows даже оказался лучше, чем на iOS.
Linux: пока самая странная платформа
С Linux ситуация пока остается самой непредсказуемой.
На Arch Linux x64 deeplink flow через:
happ://add/...
не заработал даже после установки клиента.
Пока непонятно:
— это проблема Desktop Telegram,
— браузера,
— регистрации URI schemes
— или самого Linux desktop flow.
Предварительно проблема выглядит связанной либо:
с отсутствием регистрации custom URI scheme;
либо с особенностями Desktop Telegram/browser handoff на Linux.
Но полноценного стабильного решения для Linux пока нет.
Что пробовал
За последние дни было протестировано примерно всё:
window.open('happ://...') telegram.openLink('happ://...') window.location.href = 'happ://...' hidden anchor click() popup windows setTimeout redirects install pages
И самое забавное:
наиболее стабильным решением для iOS оказался обычный промежуточный install page с:
window.location.href = url
Хотя изначально это выглядело как временный workaround.
Что я в итоге понял
Telegram Mini Apps — это далеко не “просто WebView”.
Как только появляется:
native app handoff;
custom URI schemes;
cross-platform onboarding;
mobile browser behavior;
всё становится намного сложнее, чем кажется в начале.
Особенно если хочется сделать onboarding без:
инструкций на 10 шагов;
ручного копирования ссылок;
“откройте настройки → импортируйте вручную”.
Открытые вопросы
Несмотря на то что Android, iOS и Windows удалось привести к относительно стабильному состоянию, остаётся ещё много странного platform-specific поведения.
Пока больше всего вопросов вызывает Linux/Desktop flow.
Сейчас остаются открытыми несколько проблем:
почему Telegram Desktop настолько по-разному обрабатывает custom URI schemes между Windows и Linux;
связан ли Linux issue с отсутствием x-scheme-handler или проблема глубже;
влияет ли конкретный browser/desktop environment на handoff behavior;
можно ли сделать единый cross-platform onboarding flow без install redirect page;
существует ли более стабильный способ открытия native app из Telegram Mini Apps на iOS;
насколько вообще Telegram Mini Apps подходят для сложного native onboarding.
Особенно интересно:
сталкивался ли кто-то с похожими проблемами вокруг:
custom URI schemes;
Telegram WebView;
Desktop Telegram;
Electron/browser handoff;
native app onboarding.
Если у кого-то есть опыт с подобными сценариями — будет интересно обсудить подходы и решения.
Сейчас я продолжаю тестировать onboarding flow на разных устройствах и Telegram клиентах, поэтому если кому-то интересно покидать feedback или проверить behavior на своей платформе — можете написать в Telegram: @@Sarcophilus_harrisii 🙌
