Перейти к содержанию

Telegram Mini Apps: выпуск учебного мини-приложения

В серии появился читающий экран, договор личного плана, самостоятельные модули и точная граница доверия. Теперь подготовим выпуск учебного mini app как проектную задачу. Результат урока — полный реестр поставляемых материалов, серверных обязательств и ожидаемых сценариев. Это не сообщение о состоявшемся развёртывании: настоящего бота, HTTPS-адреса, HTTP-сервиса и подтверждённого хранилища в ходе написания серии не создавалось.

Важно различать публикацию уроков на ProfessorWeb и выпуск самого приложения. Markdown-страницы и ZIP можно читать на сайте, но их появление не запускает endpoint /api/session или запись плана. Читающая оболочка также не становится личным сервисом от добавления серверной функции HMAC в другую папку. Владелец проекта должен отдельно связать HTTP-адаптер, секрет, сессии, модель данных, контроллер формы и жизненный цикл клиента.

Что уже подготовлено

В архиве серии находятся полные start/after собственной читающей оболочки уроков два — пять. В них последовательно добавляются host detection, тема и устойчивый viewport. Они показывают публичный каталог и не объявляют сохранение личного плана. Основные сценарии изучаются на одном домене из четырёх курсов, поэтому идентификаторы в форме, маршрутах и ссылках совпадают.

Далее идут самостоятельные полные модули: commit, навигация, launch, API, чтение формы, состояние, настройки, ссылки, sharing, pending operation, capabilities и переключение секций. Серверные функции validate-init-data и session-material отделены от клиента. STATE каждого урока объясняет предпосылку и границу. Эти материалы можно изучать и интегрировать осознанно; архив не маскирует независимые упражнения под один автоматически собирающийся full-stack сервис.

Реестр границ

Ниже полный редакционный реестр выпуска. Status prepared означает наличие собственных файлов и описанного договора, а not_implemented — требуемую интеграцию, которую пакет не предоставляет. Execution во всех строках остаётся not_run. Читаемый JSON включён в архив; это данные планирования, а не выполняющий команды deployment script.

{
  "series": "telegram-mini-apps",
  "exampleExecution": "not_run",
  "materials": [
    {"component": "public-reader-02-05", "status": "prepared"},
    {"component": "independent-client-modules-06-19", "status": "prepared"},
    {"component": "init-data-hmac-and-session-material", "status": "prepared"},
    {"component": "owner-bot-and-main-mini-app", "status": "not_implemented"},
    {"component": "https-origin-and-http-adapter", "status": "not_implemented"},
    {"component": "session-store-revocation-and-rate-limits", "status": "not_implemented"},
    {"component": "plan-store-cas-and-idempotency-transaction", "status": "not_implemented"},
    {"component": "integrated-form-controller-and-conflict-ui", "status": "not_implemented"},
    {"component": "real-client-and-accessibility-matrix", "status": "not_run"}
  ]
}

Этот реестр не является недостатком учебной последовательности: он показывает, где готовый небольшой модуль заканчивается и начинается новый слой ответственности. Проблема возникла бы при обещании, что reader/index.html уже реализует личную запись и безопасное восстановление после обрыва. В нашем пакете такой файл не вызывает серверную имитацию успеха. Любая будущая интеграция должна обновить реестр и соответствующие STATE, сохранив различие между подготовленным кодом и выполненным сценарием.

Адрес и бот

Для выпуска владелец создаёт собственного бота, задаёт Main Mini App и HTTPS-адрес страницы. Порядок и доступные способы запуска описаны в официальном руководстве Telegram. Username становится конфигурацией генератора ссылок; его нельзя заменить на чужой существующий бот из учебного примера. Наши статьи не регистрируют имя и не подтверждают настройки BotFather.

Origin клиента и API выбран единым. Относительные /api адреса обслуживает собственный HTTP-слой; статический хост без него вернёт другой документ или 404. Правильный 200 для HTML главной страницы не доказывает работу JSON API. TLS, правила маршрутизации, MIME, no-store персональных ответов и ограничение тела относятся к этой интеграции. Убедитесь, что секрет бота находится в серверной конфигурации и никогда не попадает в public folder, ZIP, клиентский bundle или аналитический запрос.

Серверный договор до подключения формы

HTTP-адаптер обмена ограничивает JSON-тело, проверяет тип и исходную строку initData, затем вызывает HMAC-функцию по алгоритму Telegram. У функции лимит raw восемь тысяч сто девяносто два JavaScript-символа; это не замена байтовому лимиту HTTP. В учебном контракте адаптера выбрано шестьдесят четыре KiB. Результат проверки не раскрывает секрет, а owner для плана поступает только из подтверждённой сессии.

Сессия имеет случайный bearer, сервер хранит digest, срок и отзыв. Выбранные пятнадцать минут не считаются сроком Telegram и не заменяют окно свежести auth_date. Персональные методы проверяют срок при каждом доступе; фоновой очистки недостаточно. После выхода нужен серверный отзыв, а после смены аккаунта — новая модель экрана. Store обязан работать согласованно с числом процессов и не исчезать неожиданно от рестарта без предусмотренного поведения.

План сохраняется атомарно с expectedVersion. Реестр operationId привязан к владельцу и содержимому, повтор успешного запроса возвращает его прежний результат. Сбой между записью и ответом должен восстанавливаться по этому договору, а не повтором нового UUID. В архиве есть схемы и ожидаемые сценарии, но нет реализованного движка базы или транзакции. Подключать автоматическое повторение записи до этой реализации нельзя: клиентский UUID не создаёт гарантию сам.

Клиентская интеграция

Контроллер собирает host, сессию, API, state, form и commit. Он отвечает за сопоставление позднего ответа текущему экрану, восстановление dirty и отображение конфликта. Native и обычные кнопки вызывают одинаковую доменную операцию. При неподдержанном SDK остаётся запасное действие документа; если недоступен именно сервер, объяснение относится к сохранению, а не требует обновить Telegram без причины.

У draft есть срок жизни и владелец. В текущем варианте он сохраняется в памяти открытого приложения, настройка density — отдельно в browser storage. Полное offline recovery после закрытия не реализовано. Для его добавления понадобится новый ограниченный формат, привязка к подтверждённому аккаунту и явный статус восстановления. Не сериализуйте весь объект сессии в localStorage ради удобства: это изменит выбранную границу хранения токена.

Ожидаемая матрица

Сначала читающая оболочка должна показать четыре курса в обычном браузере. Затем в выбранном Telegram-клиенте ожидаются тема, корректный возврат и отсутствие перекрытого поля при клавиатуре. На серверной части свежий допустимый запуск даёт сессию; повреждённая подпись, старое время, истёкший токен и чужой owner не дают персональную запись. Изменение плана в другом окне приводит к конфликту, а повтор завершённого UUID не увеличивает version ещё раз.

Отдельный сценарий обрыва сети сохраняет pending и новый ввод. Для доступности проверяются фокус скрытых секций, label ошибок, увеличение текста и native fallback. Матрица архива пока содержит expected и not_run, без выдуманных платформенных результатов, screenshots или чисел производительности. Реальные версии Telegram и Node.js записывает исполнитель при будущей проверке; семейство Node.js 24 является выбранным серверным профилем, а не обнаруженной у нас установкой.

Сопровождение после первого выпуска

После интеграции полезен небольшой пилот с собственными допустимыми аккаунтами и понятным обратным каналом. Журнал хранит коды, request ID и результат операции, не raw initData и bearer. При обновлении SDK перечитывается таблица возможностей и повторяется конкретный изменённый сценарий. У публичных startapp значений сохраняется совместимость, как у внешних адресов сайта; удалённый курс получает понятную альтернативу.

План отката должен учитывать данные, а не только HTML. Замена клиента старым файлом не отменяет уже записанные планы и operation records. Серверная схема и контракт версий должны оставаться совместимыми либо иметь отдельное подтверждённое восстановление. В ходе подготовки ничего из этого не выполнялось: приложения, команды, сеть, бот, база и развёртывание оставались not_run. Серия заканчивается честной картой проекта, с которой можно переходить к отдельной реализации сервиса и осмысленному выпуску.

Оглавление серии