Главная
telegram-webapp-sdk — это типобезопасная и эргономичная обёртка на Rust/WASM
над JavaScript API Telegram Web Apps.
Она позволяет писать Telegram Mini Apps полностью на Rust: на чистом
WebAssembly или через готовые интеграции с Yew и
Leptos.
Покрытие API
Крейт отслеживает версию Telegram WebApp API 9.6 — это последняя версия
Mini App, доступная в telegram-web-app.js. Bot API с тех пор дошёл до 10.1, но
версии с 9.7 по 10.1 не добавили новых методов, полей или событий WebApp,
поэтому покрытие полное. Bot API 9.5 добавил icon_custom_emoji_id для нижних
кнопок; 9.6 добавил WebApp.requestChat и события requestedChatSent /
requestedChatFailed — всё реализовано.
Покрытая поверхность включает:
- Кнопки: Main, Secondary, Back и Settings
- Диалоги: alert, confirm, popup и сканер QR-кодов
- Навигацию, ссылки, шеринг и инвойсы
- Тему, цвета, вьюпорт и safe-area отступы
- Хранилища: CloudStorage, DeviceStorage и SecureStorage
- Сенсоры: акселерометр, гироскоп, ориентацию устройства и LocationManager
- Биометрическую аутентификацию и тактильную отдачу
Полный чек-лист по методам — в файле
WEBAPP_API.md.
Флаги фич
По умолчанию фичи не включены (default = []) — подключайте только нужное.
| Фича | Что включает |
|---|---|
macros | telegram_app!, telegram_page! и telegram_router! для приложений и роутинга без бойлерплейта |
yew | use_telegram_context, реактивные хуки use_viewport / use_theme / use_safe_area и компоненты BottomButton / BackButton / SettingsButton |
leptos | provide_telegram_context, те же реактивные хуки use_* и аналогичные компоненты для Leptos |
mock | Настраиваемый мок Telegram.WebApp для локальной разработки и тестов |
full | Объединяет macros, yew, leptos и mock |
telegram-webapp-sdk = { version = "0.11", features = ["leptos", "mock"] }
Оглавление документации
- Установка — строка зависимости, флаги фич, MSRV и цель wasm32
- Быстрый старт — получение инстанса WebApp,
ready()/expand(), чтение init data и минимальный MainButton - WebApp API — обзор покрытой поверхности по разделам и паттерн
*_with_callbackпротивasync - Интеграция с фреймворками — хуки и компоненты для Leptos и Yew
- Мок и тестирование — фича
mockиwasm_bindgen_test - Примеры — демо-приложение, vanilla, бот и полноценная интеграция
Лицензия
telegram-webapp-sdk распространяется под лицензией MIT.
Установка
Добавление зависимости
Добавьте крейт в Cargo.toml:
[dependencies]
telegram-webapp-sdk = "0.11"
Включение флагов фич
Крейт поставляется без включённых фич (default = []), поэтому вы явно
подключаете только нужное:
telegram-webapp-sdk = { version = "0.11", features = ["macros", "yew", "leptos", "mock"] }
| Фича | Назначение |
|---|---|
macros | Макросы telegram_app!, telegram_page! и telegram_router! |
yew | Хук контекста, реактивные хуки и компоненты системных кнопок для Yew |
leptos | Провайдер контекста, реактивные хуки и компоненты системных кнопок для Leptos |
mock | Настраиваемый мок Telegram.WebApp для локальной разработки |
full | Сокращение для macros + yew + leptos + mock |
Обычно включают один фреймворк плюс mock:
# Приложение на Leptos с поддержкой локального мока
telegram-webapp-sdk = { version = "0.11", features = ["leptos", "mock"] }
Минимальная поддерживаемая версия Rust
MSRV — Rust 1.96 (edition 2024). Более старые тулчейны не поддерживаются.
rustup update stable
rustc --version # должно быть >= 1.96
Цель сборки — браузер
Telegram Mini Apps исполняются как WebAssembly во встроенном браузере Telegram,
поэтому собирайте под цель wasm32-unknown-unknown:
rustup target add wasm32-unknown-unknown
Сборка через Trunk или wasm-pack
Используйте WASM-бандлер, чтобы получить итоговый .wasm, JS-обвязку и
index.html.
Trunk (рекомендуется для целых приложений — его использует демо):
cargo install trunk
trunk serve # dev-сервер с автоперезагрузкой
trunk build --release
Минимальный index.html для Trunk подключает скрипт Telegram и ваш крейт:
<!doctype html>
<html>
<head>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<link data-trunk rel="rust" />
</head>
<body></body>
</html>
wasm-pack (для библиотек или интеграции, управляемой из JS):
cargo install wasm-pack
wasm-pack build --target web
Дальше
- Быстрый старт — инициализация SDK и первая кнопка
- Интеграция с фреймворками — подключение Leptos или Yew
- Мок и тестирование — запуск вне Telegram при разработке
Быстрый старт
Эта страница проходит через минимальное полезное Mini App: инициализация SDK, получение инстанса WebApp, сигнал готовности, чтение данных запуска и показ MainButton.
1. Инициализация SDK и получение инстанса
init_sdk() разбирает initData и themeParams из Telegram.WebApp и
сохраняет их в глобальном контексте. После этого получите живой хендл WebApp.
Есть два аксессора:
TelegramWebApp::instance()возвращаетOption<TelegramWebApp>(None, если код запущен не внутри Telegram) — удобно для graceful degradation.TelegramWebApp::try_instance()возвращаетResult<TelegramWebApp, JsValue>— удобно внутри функций, использующих?.
use telegram_webapp_sdk::{core::init::init_sdk, webapp::TelegramWebApp};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn main() -> Result<(), JsValue> {
init_sdk()?;
let app = TelegramWebApp::try_instance()?;
app.ready()?; // сообщаем Telegram, что интерфейс инициализирован
app.expand()?; // разворачиваем Mini App на полную высоту
Ok(())
}
Если нужен запуск без паники, используйте try_init_sdk() — он возвращает
Ok(false), когда Telegram недоступен:
use telegram_webapp_sdk::core::init::try_init_sdk;
match try_init_sdk() {
Ok(true) => { /* запущено внутри Telegram */ }
Ok(false) => { /* обычный браузер — используем фолбэк */ }
Err(e) => eprintln!("ошибка инициализации: {e}")
}
2. Чтение init data и пользователя
Разобранные данные запуска лежат в глобальном TelegramContext. Доступ — через
геттер на основе замыкания:
use telegram_webapp_sdk::core::context::TelegramContext;
TelegramContext::get(|ctx| {
if let Some(user) = &ctx.init_data.user {
web_sys::console::log_1(&format!("Привет, {}", user.first_name).into());
}
let _ = ctx.init_data.auth_date;
let _ = ctx.init_data.start_param.as_deref();
});
Для серверной проверки подписи возьмите сырую URL-кодированную строку и отправьте её на бэкенд (проверяйте там, с токеном бота — никогда на клиенте):
use telegram_webapp_sdk::TelegramWebApp;
let raw_init_data = TelegramWebApp::get_raw_init_data()?;
// POST /auth { "init_data": raw_init_data }
Ok::<(), Box<dyn std::error::Error>>(())
3. Минимальный MainButton
Задайте подпись, покажите кнопку и зарегистрируйте колбэк клика. Колбэк
возвращает EventHandle, который позже можно передать в
remove_main_button_callback.
use telegram_webapp_sdk::webapp::TelegramWebApp;
fn run() -> Result<(), wasm_bindgen::JsValue> {
let app = TelegramWebApp::try_instance()?;
app.set_main_button_text("Отправить заказ")?;
app.set_main_button_color("#2481cc")?;
app.enable_main_button()?;
app.show_main_button()?;
let handle = app.set_main_button_callback(|| {
if let Some(app) = TelegramWebApp::instance() {
let _ = app.send_data("order-confirmed");
}
})?;
// позже, когда кнопка больше не нужна:
app.remove_main_button_callback(handle)?;
app.hide_main_button()?;
Ok(())
}
Что дальше
- WebApp API — полная покрытая поверхность: диалоги, хранилища, сенсоры
- Интеграция с фреймворками — реактивные хуки и компоненты кнопок для Leptos/Yew
- Мок и тестирование — запуск этого кода вне Telegram
WebApp API
Почти все возможности доступны через хендл TelegramWebApp
(instance() / try_instance()), плюс несколько модулей со свободными
функциями в telegram_webapp_sdk::api::* для сенсоров, хранилищ, тактильной
отдачи и темы. Эта страница группирует поверхность по разделам. Исчерпывающий
чек-лист — в
WEBAPP_API.md.
Паттерн *_with_callback против async
У каждого одноразового колбэка Telegram есть два Rust-сиблинга:
foo_with_callback(..., F)— синхронная регистрация; ваше замыкание вызывается, когда Telegram присылает результат. Используйте, когда нельзя.await(например, внутри не-async замыкания).async fn foo(...)— возвращает естественный Rust-тип через.await. Предпочтительно в продакшене.
use telegram_webapp_sdk::webapp::TelegramWebApp;
async fn run() -> Result<(), wasm_bindgen::JsValue> {
let app = TelegramWebApp::try_instance()?;
let confirmed: bool = app.show_confirm("Отправить заказ?").await?;
let scanned: String = app.show_scan_qr_popup("Сканируйте QR-код").await?;
let granted: bool = app.request_write_access().await?;
let _ = (confirmed, scanned, granted);
Ok(())
}
То же справедливо для share_message, request_chat,
check_home_screen_status, set_emoji_status, request_emoji_status_access,
open_invoice, download_file, read_text_from_clipboard, show_popup и
invoke_custom_method.
Кнопки
Нижние кнопки Main и Secondary используют enum-селектор BottomButton
(BottomButton::Main / BottomButton::Secondary):
use telegram_webapp_sdk::webapp::{BottomButton, BottomButtonParams, TelegramWebApp};
fn run() -> Result<(), wasm_bindgen::JsValue> {
let app = TelegramWebApp::try_instance()?;
app.set_bottom_button_text(BottomButton::Main, "Отправить")?;
app.show_bottom_button(BottomButton::Main)?;
// Атомарное обновление через setParams:
let params = BottomButtonParams {
text: Some("Отправить"),
color: Some("#2481cc"),
text_color: Some("#ffffff"),
is_active: Some(true),
is_visible: Some(true),
icon_custom_emoji_id: Some("123456789"), // Bot API 9.5+
..Default::default()
};
app.set_bottom_button_params(BottomButton::Main, ¶ms)?;
Ok(())
}
Есть удобные алиасы для главной кнопки (set_main_button_text,
show_main_button, enable_main_button, set_main_button_callback, …) и для
вторичной (set_secondary_button_text, show_secondary_button, …).
Кнопки Back и Settings управляются напрямую:
use telegram_webapp_sdk::webapp::TelegramWebApp;
fn run() -> Result<(), wasm_bindgen::JsValue> {
let app = TelegramWebApp::try_instance()?;
app.show_back_button()?;
let handle = app.set_back_button_callback(|| { /* назад */ })?;
app.remove_back_button_callback(handle)?;
app.show_settings_button()?;
let sh = app.set_settings_button_callback(|| { /* настройки */ })?;
app.remove_settings_button_callback(sh)?;
Ok(())
}
Диалоги
use telegram_webapp_sdk::webapp::TelegramWebApp;
async fn run() -> Result<(), wasm_bindgen::JsValue> {
let app = TelegramWebApp::try_instance()?;
app.show_alert("Сохранено!")?;
let ok: bool = app.show_confirm("Удалить элемент?").await?;
let button_id: String = app.show_popup(&wasm_bindgen::JsValue::NULL).await?;
let code: String = app.show_scan_qr_popup("Наведите на QR-код").await?;
app.close_scan_qr_popup()?;
let _ = (ok, button_id, code);
Ok(())
}
Навигация и ссылки
open_link (с опциональным OpenLinkOptions), open_telegram_link,
switch_inline_query, share_url, share_message / share_to_story,
request_chat, add_to_home_screen и check_home_screen_status.
Тема и цвета
set_header_color, set_background_color, set_bottom_bar_color,
color_scheme(), а также свободная функция
telegram_webapp_sdk::api::theme::get_theme_params(), возвращающая разобранную
палитру.
Вьюпорт и safe-area
viewport_height(), viewport_width(), viewport_stable_height(),
expand_viewport() и аксессоры SafeAreaInset: safe_area_inset() /
content_safe_area_inset(). Полноэкранный режим и ориентация:
request_fullscreen, exit_fullscreen, is_fullscreen, lock_orientation и
unlock_orientation.
Хранилища
- CloudStorage —
api::cloud_storage::{get_item, set_item, remove_item, get_items, remove_items, get_keys}(каждая возвращает JSPromise). - DeviceStorage —
api::device_storage::{set, get, remove, clear}(async). - SecureStorage —
api::secure_storage::{set, get, restore, remove, clear}(async).
use telegram_webapp_sdk::api::device_storage::{get, set};
async fn run() -> Result<(), wasm_bindgen::JsValue> {
set("theme", "dark").await?;
let value: Option<String> = get("theme").await?;
let _ = value;
Ok(())
}
Сенсоры
Акселерометр, гироскоп и ориентация устройства предоставляют start(),
stop(), геттер (get_acceleration(), get_angular_velocity(),
get_orientation()) и колбэки жизненного цикла on_started / on_changed /
on_stopped / on_failed. LocationManager: init(), get_location(),
open_settings(), on_location_manager_updated и on_location_requested.
use telegram_webapp_sdk::api::accelerometer::{get_acceleration, start, stop};
start()?;
let reading = get_acceleration();
stop()?;
let _ = reading;
Ok::<(), wasm_bindgen::JsValue>(())
Биометрия
api::biometric::{init, is_biometric_available, request_access, authenticate, update_biometric_token, open_settings, is_inited, is_access_granted, device_id, …}.
use telegram_webapp_sdk::api::biometric::{authenticate, init, is_biometric_available, request_access};
fn run() -> Result<(), wasm_bindgen::JsValue> {
init()?;
if is_biometric_available()? {
request_access("auth-key", Some("Разблокировать хранилище"), None)?;
authenticate("auth-key", None, None)?;
}
Ok(())
}
Тактильная отдача
use telegram_webapp_sdk::api::haptic::{
impact_occurred, notification_occurred, selection_changed,
HapticImpactStyle, HapticNotificationType,
};
impact_occurred(HapticImpactStyle::Light)?;
notification_occurred(HapticNotificationType::Success)?;
selection_changed()?;
Ok::<(), wasm_bindgen::JsValue>(())
См. также Интеграция с фреймворками — реактивные обёртки над событиями вьюпорта, темы и safe-area.
Интеграция с фреймворками
Крейт поставляет опциональные интеграции для Leptos (фича
leptos) и Yew (фича yew). Обе предоставляют одни и те же
три реактивных хука и три компонента системных кнопок. Хуки инициализируются
текущими значениями и перерисовывают компонент, когда Telegram присылает события
viewportChanged, themeChanged, safeAreaChanged или
contentSafeAreaChanged. Подписки очищаются автоматически при размонтировании /
уничтожении скоупа.
Leptos
Предоставьте контекст один раз рядом с корнем, затем читайте через
use_context:
use leptos::prelude::*;
use telegram_webapp_sdk::{core::context::TelegramContext, leptos::provide_telegram_context};
#[component]
fn App() -> impl IntoView {
provide_telegram_context().expect("context");
let ctx = use_context::<TelegramContext>().expect("context");
view! { <span>{ ctx.init_data.auth_date }</span> }
}
Реактивные хуки
В Leptos хуки возвращают ReadSignal<T>, поэтому читайте их через .get()
внутри замыкания:
use leptos::prelude::*;
use telegram_webapp_sdk::leptos::{use_safe_area, use_theme, use_viewport};
#[component]
fn Status() -> impl IntoView {
let viewport = use_viewport(); // ReadSignal<ViewportState>
let theme = use_theme(); // ReadSignal<ThemeState>
let safe = use_safe_area(); // ReadSignal<SafeAreaState>
view! {
<div>
{ move || viewport.get().height }
{ move || theme.get().color_scheme.unwrap_or_default() }
{ move || safe.get().area.map(|i| i.top).unwrap_or(0.0) }
</div>
}
}
ViewportState содержит height, stable_height и is_expanded. ThemeState
содержит color_scheme: Option<String> и разобранную палитру params.
SafeAreaState содержит area и content как Option<SafeAreaInset>.
Компоненты
BottomButton принимает селектор button и реактивный text (и опциональные
color / text_color / on_click). BackButton и SettingsButton принимают
реактивный сигнал visible и опциональное замыкание on_click. Все три
управляют нативными кнопками Telegram и очищаются при размонтировании.
use leptos::prelude::*;
use telegram_webapp_sdk::{
leptos::{provide_telegram_context, BackButton, BottomButton, SettingsButton},
webapp::BottomButton as Btn,
};
#[component]
fn App() -> impl IntoView {
provide_telegram_context().expect("context");
let (text, _set_text) = signal("Отправить".to_owned());
let visible = RwSignal::new(true);
view! {
<BottomButton button=Btn::Main text on_click=move || { /* отправка */ } />
<BackButton visible=visible on_click=move || { /* назад */ } />
<SettingsButton visible=visible on_click=move || { /* настройки */ } />
}
}
Yew
Читайте контекст хуком use_telegram_context. Он возвращает
Result<TelegramContext, JsValue> и реактивно резолвится, как только контекст
инициализирован:
use telegram_webapp_sdk::yew::use_telegram_context;
use yew::prelude::*;
#[function_component(App)]
fn app() -> Html {
match use_telegram_context() {
Ok(ctx) => html! { <span>{ ctx.init_data.auth_date }</span> },
Err(_) => html! { <div>{ "Загрузка контекста Telegram..." }</div> },
}
}
Реактивные хуки
В Yew хуки возвращают значение состояния напрямую (не сигнал), поэтому читайте поля прямо с него:
use telegram_webapp_sdk::yew::{use_safe_area, use_theme, use_viewport};
use yew::prelude::*;
#[function_component(Status)]
fn status() -> Html {
let viewport = use_viewport(); // ViewportState
let theme = use_theme(); // ThemeState
let safe = use_safe_area(); // SafeAreaState
html! {
<div>
{ viewport.height }
{ theme.color_scheme.clone().unwrap_or_default() }
{ safe.area.map(|i| i.top).unwrap_or(0.0) }
</div>
}
}
Компоненты
Компоненты Yew принимают обычные пропсы: BottomButton использует text /
color / text_color / on_click (всегда управляет кнопкой Main), а
BackButton и SettingsButton принимают проп visible: bool и
on_click: Callback<()>.
use telegram_webapp_sdk::yew::{BackButton, BottomButton, SettingsButton};
use yew::prelude::*;
#[function_component(App)]
fn app() -> Html {
let on_main = Callback::from(|_| {});
let on_back = Callback::from(|_| {});
let on_settings = Callback::from(|_| {});
html! {
<>
<BottomButton text="Отправить" color="#000" text_color="#fff" on_click={on_main} />
<BackButton visible={true} on_click={on_back} />
<SettingsButton visible={true} on_click={on_settings} />
</>
}
}
См. также
- Быстрый старт — vanilla-подход без фреймворка
- Мок и тестирование — рендер компонентов против мока
- Примеры — запускаемое демо на Trunk
Мок и тестирование
Фича mock устанавливает настраиваемый поддельный объект Telegram.WebApp на
window, что позволяет разрабатывать и тестировать вне клиента Telegram.
Включите её:
telegram-webapp-sdk = { version = "0.11", features = ["mock"] }
Установка мок-окружения
Мок находится в telegram_webapp_sdk::mock. Соберите MockTelegramConfig (он
реализует Default) и вызовите mock_telegram_webapp — он внедрит
window.Telegram.WebApp с замоканными initData, themeParams, platform и
version. Используйте только в debug-сборках.
use telegram_webapp_sdk::mock::{config::MockTelegramConfig, init::mock_telegram_webapp};
fn run() -> Result<(), wasm_bindgen::JsValue> {
let config = MockTelegramConfig::default();
mock_telegram_webapp(config)?;
// window.Telegram.WebApp теперь существует — SDK ведёт себя как внутри Telegram.
Ok(())
}
Настройка замоканных данных
MockTelegramConfig содержит опциональные поля для пользователя, данных
авторизации, всех цветов темы и платформы/версии. Замоканный пользователь — это
MockTelegramUser:
use telegram_webapp_sdk::mock::{
config::MockTelegramConfig, data::MockTelegramUser, init::mock_telegram_webapp,
};
fn run() -> Result<(), wasm_bindgen::JsValue> {
let config = MockTelegramConfig {
user: Some(MockTelegramUser {
id: 42,
first_name: "Alice".into(),
username: Some("alice".into()),
language_code: Some("en".into()),
..Default::default()
}),
platform: Some("android".into()),
version: Some("9.6".into()),
..Default::default()
};
mock_telegram_webapp(config)?;
Ok(())
}
Конфиг можно также загрузить из TOML-файла (тот же telegram-webapp.toml,
который telegram_app! читает в debug-сборках):
use telegram_webapp_sdk::mock::config::MockTelegramConfig;
let config = MockTelegramConfig::from_file("telegram-webapp.toml")?;
Ok::<(), std::io::Error>(())
Тестирование через wasm_bindgen_test
Поскольку SDK работает с глобальными объектами браузера, тесты выполняются в
headless-браузере через wasm-bindgen-test. Добавьте его в dev-зависимости:
[dev-dependencies]
wasm-bindgen-test = "0.3"
Настройте тесты на запуск в браузере и установите мок перед использованием SDK:
use telegram_webapp_sdk::{
core::init::init_sdk,
mock::{config::MockTelegramConfig, init::mock_telegram_webapp},
webapp::TelegramWebApp,
};
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn instance_is_available_after_mock() {
mock_telegram_webapp(MockTelegramConfig::default()).expect("mock installed");
init_sdk().expect("sdk initialized");
let app = TelegramWebApp::instance().expect("instance");
app.ready().expect("ready");
}
Запуск набора тестов на реальном браузерном движке:
# Chrome / Chromium
wasm-pack test --headless --chrome
# или Firefox
wasm-pack test --headless --firefox
Советы
- В коде приложения предпочитайте
TelegramWebApp::instance()(возвращаетOption), чтобы один и тот же бинарь корректно деградировал, когда нет ни Telegram, ни мока. - Все
wasm_bindgen_testразделяют одинwindow; устанавливайте мок в начале каждого теста, которому он нужен, а не полагайтесь на порядок выполнения. - Учтите, что
TelegramContext::initуспешно отрабатывает только один раз на поток — проектируйте тесты так, чтобы они не зависели от повторной инициализации глобального контекста.
См. также
- Быстрый старт — код, который вы тестируете
- Примеры —
examples/vanillaсобирается с фичейmock
Примеры
В репозитории есть несколько запускаемых примеров, встроенных в Cargo-воркспейс. Каждый показывает свой стиль интеграции — от полноценного Mini App на Trunk до обычного WASM-бинарника и серверной части полного стека.
demo/ — WASM-приложение на Trunk
Полноценное Mini App, собранное с фичами macros и mock. Использует
telegram_page! / telegram_router! для роутинга и включает компоненты и
страницы (demo/src/components, demo/src/pages). Так как включена фича mock,
демо работает в обычном браузере во время разработки.
cd demo
trunk serve # dev-сервер с автоперезагрузкой на http://localhost:8080
trunk build --release
Файл demo/index.html загружает telegram-web-app.js от Telegram и собранный
Trunk WASM-бандл.
examples/vanilla — без фреймворка
Пример на чистом WebAssembly (examples/vanilla/src/main.rs + ui.rs),
использующий SDK и DOM-хелперы напрямую, без Yew и Leptos. Зависит от крейта с
фичей mock, поэтому запускается самостоятельно. Хорошая отправная точка, если
нужен полный контроль над DOM.
cd examples/vanilla
trunk serve
examples/bots/rust_bot — Telegram-бот
Бот на teloxide
(examples/bots/rust_bot), который открывает демо Mini App через WebApp-кнопки и
принимает заказы, отправленные из приложения через sendData. Это серверная
часть — нативный бинарник, не WASM.
cd examples/bots/rust_bot
cp .env.example .env # добавьте свой TELOXIDE_TOKEN
cargo run
Требуется токен бота от @BotFather и URL WebApp по HTTPS.
examples/integration — полный стек
Пример из двух частей, показывающий round-trip фронтенд↔бэкенд:
examples/integration/frontend— WASM Mini App, отправляющее JSON-сообщение боту черезTelegramWebApp::send_data(...). (Этот член исключён из воркспейса и собирается отдельно через Trunk.)examples/integration/backend— бот на teloxide, принимающийweb_app_dataиз обновления, разбирающий JSON и отвечающий.
# терминал 1 — бэкенд
cd examples/integration/backend
cargo run
# терминал 2 — фронтенд
cd examples/integration/frontend
trunk serve
Поток данных: пользователь открывает Mini App → взаимодействует с UI →
приложение вызывает send_data → Telegram доставляет payload боту как
web_app_data → бот обрабатывает его и отвечает.
Сборка любого WASM-примера
Все браузерные примеры собираются под wasm32-unknown-unknown и обслуживаются
через Trunk:
rustup target add wasm32-unknown-unknown
cargo install trunk
См. также
- Быстрый старт — минимальная версия vanilla-примера
- Интеграция с фреймворками — паттерны Leptos/Yew из демо
- Мок и тестирование — фича
mock, позволяющая запускать эти примеры вне Telegram