23 β Telegram Web App (Mini App) asoslari¶
β¬ οΈ Oldingi: 22 β Majburiy obuna Β· π README Β· Keyingi: 24 β Web App xavfsizligi: initData β‘οΈ
Bu bobda: botimizni matn va tugmalardan tashqariga olib chiqamiz β Telegram Web App (yoki Mini App) bilan tanishamiz. Bu β Telegram ilovasidan chiqmasdan ochiladigan to'liq HTML/JS veb-ilova: grafik, formalar, animatsiya, hamma narsa. Avval Mini App nima ekanini va nega kerakligini ko'ramiz, keyin uni ochuvchi tugmani uch xil yo'l bilan ulashni o'rganamiz β inline tugma (
InlineKeyboardButton::make(..., web_app: WebAppInfo::make(...))), reply tugma (KeyboardButton::make(..., web_app: ...)) va menyu tugma (setChatMenuButton(...)orqali βMenuButtonWebAppnewbilan quriladi, staticmakeemas). So'ngra frontend tomonidagitelegram-web-app.jsJS SDK bilan tanishamiz:ready(),expand(),themeParams,MainButton,BackButton,HapticFeedback,close(),initData. Va nihoyat reply-web_app tugmasidansendData()qilinganda bot tomondaonWebAppDatahandleri qanday ushlanishini ko'ramiz. Bobdagi tugma qurish, menyu tugma sozlash vaonWebAppDatarouting mantig'i offlineFakeNutgrambilan haqiqatan tekshirilgan (11 ta tasdiq 0 xato bilan o'tdi). Frontend HTML/JS namunasi va Mini App'ning Telegram ichida real ko'rinishi β bu jonli qism, faqat illustrativ ko'rsatilgan (uni ko'rish uchun HTTPS hosting va haqiqiy qurilma kerak). Mini App'ning xavfsizligi (initDatatekshirish) β 24-bob, to'liq backend β 25-bob mavzusi.
Mini App nima va nega kerak¶
Shu paytgacha bot bilan ikki narsa orqali muloqot qildik: xabarlar (matn, media) va tugmalar (reply/inline klaviatura). Bu kuchli, lekin cheklangan. Murakkab forma, jadval, kalendar, savat, real vaqtli o'yin yoki chiroyli dizaynli interfeysni faqat xabar va tugma bilan qurish noqulay β ba'zan deyarli imkonsiz.
Telegram Web App (rasman Mini App ham deyiladi) shu muammoni hal qiladi: u β sizning serveringizdagi oddiy HTML/CSS/JS veb-sahifa, lekin u brauzerda emas, balki Telegram ilovasining ichida, maxsus oynada (webview) ochiladi. Foydalanuvchi Telegram'dan chiqmaydi; u uchun bu xuddi botning bir qismidek tuyuladi.
Mini App'ning kuchi:
- To'liq veb-ilova β istalgan HTML/CSS/JS, framework (React, Vue, oddiy vanilla β farqi yo'q). Siz frontend dasturchi sifatida nima qila olsangiz, shuni Telegram ichida ko'rsatasiz.
- Telegram bilan integratsiya β maxsus JS SDK (
telegram-web-app.js) orqali ilova foydalanuvchining tilini, mavzu ranglarini (qora/oq rejim), kim ochganini (initData) biladi va Telegram tugmalarini (pastdagi katta "MainButton") boshqaradi. - Foydalanuvchi tanish muhitda qoladi β alohida brauzer ochilmaydi, login qilish shart emas (foydalanuvchi allaqachon Telegram'da).
Klassik misollar: do'kon kataloglari va savatlari, bron qilish kalendarlari, so'rovnomalar, "Hamster" uslubidagi clicker o'yinlar (kitobning kapston boyi β 26-bob).
Eng muhim tushuncha: Mini App ikki qismdan iborat. Frontend β bu sizning HTTPS serveringizdagi veb-sahifa (Telegram faqat uning URL'ini biladi). Backend β bu Telegram'dan kelgan ma'lumotni (initData) tekshiruvchi va haqiqiy ishni bajaruvchi server kodi. Bot esa faqat Mini App'ni ochuvchi tugmani beradi. Shu bobda biz aynan botning roliga β tugmani ulashga va sendData natijasini ushlashga β e'tibor qaratamiz; frontend va backend keyingi boblarda chuqurlashadi.
Eslatma: Mini App URL'i albatta HTTPS bo'lishi shart (lokal
localhostham qabul qilinmaydi β pastda lokal sinash usulini ko'rsatamiz). Bu Telegram talabi.
Mini App'ni ochuvchi tugmani ulashning 3 yo'li¶
Foydalanuvchi Mini App'ni ko'rishi uchun uni biror joydan ochishi kerak. Telegram uchta variant beradi va ularning hammasi WebAppInfo bilan ishlaydi.
WebAppInfo β bu shunchaki URL'ni o'rab beruvchi kichik obyekt:
<?php
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$info = WebAppInfo::make('https://example.com/app'); // URL doim HTTPS
Endi uni qaerga ulashni ko'ramiz.
1-yo'l: Inline tugma¶
Eng ko'p ishlatiladigan usul. Xabar tagidagi inline tugma bosilganda Mini App darhol ochiladi. (Inline klaviatura β 06-bob mavzusi.)
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->onCommand('dokon', function (Nutgram $bot) {
$keyboard = InlineKeyboardMarkup::make()
->addRow(
InlineKeyboardButton::make(
'Do\'konni ochish',
web_app: WebAppInfo::make('https://example.com/shop'),
),
);
$bot->sendMessage('Bizning do\'konimiz:', reply_markup: $keyboard);
});
Inline web_app tugmasi callback_query yubormaydi β u faqat Mini App'ni ochadi. Diqqat: bunday tugmadan sendData ishlamaydi (sendData faqat reply-tugmada β pastda ko'ramiz). Inline orqali ochilgan Mini App bilan bog'lanish initData orqali, serverga to'g'ridan-to'g'ri so'rov bilan amalga oshadi (24β25-boblar).
2-yo'l: Reply tugma¶
Reply klaviaturadagi tugma ham Mini App'ni ocha oladi. Farqi shundaki, faqat shu turdagi tugmadan ilova sendData() orqali botga to'g'ridan-to'g'ri ma'lumot qaytara oladi (bu bobning oxirgi qismi).
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Types\Keyboard\ReplyKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\KeyboardButton;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->onCommand('forma', function (Nutgram $bot) {
$keyboard = ReplyKeyboardMarkup::make(resize_keyboard: true)
->addRow(
KeyboardButton::make(
'Formani to\'ldirish',
web_app: WebAppInfo::make('https://example.com/form'),
),
);
$bot->sendMessage('Pastdagi tugma orqali formani oching:', reply_markup: $keyboard);
});
3-yo'l: Menyu tugma (setChatMenuButton)¶
Chatning pastki chap burchagidagi = (menyu) tugmasini Mini App'ni ochadigan qilib o'zgartirish mumkin. U doimo qo'l ostida turadi β foydalanuvchi xabar yozmasdan ham ilovani ochadi. Bu bot uchun global sozlama (yoki muayyan chat uchun chat_id bilan).
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->onCommand('menyu_ornat', function (Nutgram $bot) {
$bot->setChatMenuButton(
menu_button: new MenuButtonWebApp(
'Ilovani ochish',
WebAppInfo::make('https://example.com/app'),
),
);
$bot->sendMessage('Menyu tugmasi Mini App ochadigan qilib sozlandi.');
});
Diqqat β bu yerda tez-tez xato qilinadi: Nutgram'dagi aksariyat tiplar
Type::make(...)orqali quriladi (static). LekinMenuButtonWebAppβ istisno: uningmake()metodi static emas, shuning uchun uniMenuButtonWebApp::make(...)deb chaqirib bo'lmaydi. To'g'ri yo'l βnew MenuButtonWebApp($text, $webAppInfo). Buni bizReflectionMethodbilan tasdiqladik (pastdagi tekshiruv bo'limiga qarang).
setChatMenuButton argumentlari:
chat_idβ agar berilsa, faqat shu chatda; berilmasa, barcha shaxsiy chatlar uchun default menyu tugmasi o'zgaradi.menu_buttonβMenuButtonWebApp(Mini App),MenuButtonCommands(buyruqlar ro'yxati) yokiMenuButtonDefault(standart holatga qaytarish).
| Yo'l | Sinf / metod | sendData ishlaydimi? |
Qachon | Qayerda turadi |
|---|---|---|---|---|
| Inline | InlineKeyboardButton::make(web_app:) |
yo'q | aniq bir xabarga bog'liq harakat | xabar tagida |
| Reply | KeyboardButton::make(web_app:) |
ha | ilova botga to'g'ridan ma'lumot qaytarsa | input maydon ostida |
| Menyu | setChatMenuButton(new MenuButtonWebApp(...)) |
yo'q | doimiy "bosh ilova" | chat pastida (=) |
Frontend: telegram-web-app.js JS SDK¶
Mini App'ni Telegram bilan "gaplashadigan" qiladigan narsa β telegram-web-app.js skripti. Uni HTML'ingizning <head> qismiga shu maxsus URL'dan ulaysiz (o'zingiznikiga nusxalamang β Telegram doim yangilab turadi):
Bu skript global window.Telegram.WebApp obyektini beradi. Eng muhim a'zolari:
| A'zo | Vazifasi |
|---|---|
ready() |
Ilova yuklandi deb Telegram'ga xabar beradi (yuklanish ekranini olib tashlaydi). Birinchi navbatda chaqiring. |
expand() |
Oynani to'liq balandlikka kengaytiradi (default β yarim ekran). |
themeParams |
Telegram mavzu ranglari (bg_color, text_color, button_color ...) β ilovani qora/oq rejimga moslash uchun. |
colorScheme |
'light' yoki 'dark'. |
MainButton |
Pastdagi katta tugma: setText(), show(), hide(), onClick(), showProgress(). |
BackButton |
Yuqori chapdagi "orqaga" tugmasi: show(), hide(), onClick(). |
HapticFeedback |
Tebranish bilan javob: impactOccurred('medium'), notificationOccurred('success'). |
initData / initDataUnsafe |
Telegram bergan kirish ma'lumoti (kim ochgani, hash). initData serverda tekshiriladi β 24-bob. |
sendData(str) |
Ma'lumotni botga qaytaradi va ilovani yopadi (faqat reply-web_app tugmasidan ochilganda). |
close() |
Mini App oynasini yopadi. |
Eng oddiy, ishlaydigan frontend namunasi (illustrativ β uni HTTPS serverga qo'yib, tugma orqali ochish kerak):
<!DOCTYPE html>
<html lang="uz">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mini App namuna</title>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<style>
body {
font-family: sans-serif;
/* Telegram mavzu ranglarini ishlatamiz β qora/oq rejimga mos */
background: var(--tg-theme-bg-color, #ffffff);
color: var(--tg-theme-text-color, #000000);
padding: 16px;
}
input { width: 100%; padding: 10px; font-size: 16px; box-sizing: border-box; }
</style>
</head>
<body>
<h2>Buyurtma berish</h2>
<p>Ismingizni kiriting:</p>
<input id="ism" placeholder="Ism" />
<script>
const tg = window.Telegram.WebApp;
tg.ready(); // Telegram'ga "tayyorman" deymiz
tg.expand(); // to'liq balandlikka kengayamiz
// Pastdagi katta tugmani sozlaymiz
tg.MainButton.setText('Yuborish');
tg.MainButton.show();
tg.MainButton.onClick(function () {
const ism = document.getElementById('ism').value;
tg.HapticFeedback.impactOccurred('medium'); // yengil tebranish
// ma'lumotni botga qaytaramiz (faqat reply-web_app tugmada ishlaydi)
tg.sendData(JSON.stringify({ ism: ism }));
// sendData avtomatik ilovani yopadi
});
// "Orqaga" tugmasi β ilovani yopadi
tg.BackButton.onClick(() => tg.close());
</script>
</body>
</html>
Bu sahifa Telegram mavzu ranglariga moslashadi (var(--tg-theme-bg-color, ...)), pastda "Yuborish" tugmasini ko'rsatadi va bosilganda kiritilgan ismni botga qaytaradi.
Halol eslatma: bu frontend kodi token yoki HTTPS hostingsiz jonli ishlamaydi β
window.Telegramfaqat Telegram ichida ochilganda mavjud bo'ladi. Shuning uchun u illustrativ. Frontend mantiqini sinash uchun keyingi boblarda lokal HTTP server (php -S) va soxtainitDatabilan ishlaymiz.
Reply-web_app sendData -> onWebAppData¶
sendData() β Mini App'dan botga ma'lumot qaytarishning eng oddiy yo'li. Lekin u faqat reply klaviaturadagi web_app tugmasidan ochilgan ilovada ishlaydi (inline yoki menyu tugmada emas).
Jarayon quyidagicha:
- Foydalanuvchi reply-web_app tugmasini bosadi -> Mini App ochiladi.
- Ilovada JS
tg.sendData('order:42')chaqiradi. - Telegram Mini App'ni yopadi va botga maxsus xabar yuboradi β bu xabarda
web_app_datamaydoni bor. - Bot tomonda biz uni
onWebAppDatahandleri bilan ushlaymiz.
Bot tomonidagi kod:
<?php
use SergiX44\Nutgram\Nutgram;
$bot->onWebAppData(function (Nutgram $bot) {
// Mini App yuborgan ma'lumot message->web_app_data ichida
$payload = $bot->message()?->web_app_data;
$data = $payload->data; // sendData(...) ichidagi satr, masalan 'order:42'
$buttonText = $payload->button_text; // qaysi tugmadan ochilgani
$bot->sendMessage("Mini App'dan keldi: {$data}");
});
Ma'lumotga $bot->message()->web_app_data orqali kiramiz. U WebAppData obyekti bo'lib, ikki maydoni bor:
dataβsendData()ichida yuborilgan satr (odatda JSON, biz unijson_decodeqilamiz).button_textβ Mini App ochilgan tugmaning matni.
Diqqat (juda muhim):
web_app_dataβ bu mijozdan kelgan, ishonchsiz ma'lumot. Yomon niyatli foydalanuvchisendDataichiga istalgan narsani qo'yishi mumkin. Shuning uchun pul, ball yoki muhim holatga ta'sir qiluvchi har qanday amaldasendData'ga ishonmang β buning o'rniga ilovadan serveringizga to'g'ridan-to'g'ri so'rov yuboring va u yerdainitDatani tekshiring (24-bob).sendDataβ faqat oddiy, xavfsiz tanlov (masalan, tanlangan rang) uchun.
JSON yuborgan bo'lsangiz, uni xavfsiz dekod qilamiz:
<?php
use SergiX44\Nutgram\Nutgram;
$bot->onWebAppData(function (Nutgram $bot) {
$raw = $bot->message()?->web_app_data?->data ?? '';
$decoded = json_decode($raw, associative: true);
if (!is_array($decoded) || !isset($decoded['ism'])) {
$bot->sendMessage('Ma\'lumot noto\'g\'ri formatda.');
return;
}
$ism = (string) $decoded['ism'];
$bot->sendMessage("Rahmat, {$ism}! Ma'lumotingiz qabul qilindi.");
});
Offline tekshiruv: tugma quramiz va onWebAppData ni sinaymiz¶
Bu bobdagi bot mantig'i β WebAppInfo, uchta tugma turi, menyu tugma va onWebAppData routing β token va tarmoqsiz FakeNutgram bilan tekshirildi. Frontend HTML/JS esa jonli qism (uni faqat Telegram ichida ko'rish mumkin).
Avval tugma qurilishini va MenuButtonWebApp'ning new bilan ishlashini tekshiramiz:
<?php
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
// inline web_app tugmasi
$kb = InlineKeyboardMarkup::make()
->addRow(InlineKeyboardButton::make('Och', web_app: WebAppInfo::make('https://example.com/app')));
assert($kb->inline_keyboard[0][0]->web_app->url === 'https://example.com/app');
assert($kb->inline_keyboard[0][0]->callback_data === null); // web_app tugma callback yubormaydi
// MenuButtonWebApp::make() STATIC EMAS -> new ishlatish shart
$ref = new ReflectionMethod(MenuButtonWebApp::class, 'make');
assert($ref->isStatic() === false);
$menuBtn = new MenuButtonWebApp('Ilova', WebAppInfo::make('https://example.com/app'));
assert($menuBtn->text === 'Ilova');
assert($menuBtn->web_app->url === 'https://example.com/app');
echo "Tugmalar to'g'ri qurildi\n";
Endi onWebAppData handleri haqiqatan reply-web_app sendData xabariga ishlashini FakeNutgram bilan tekshiramiz. hearMessage([...]) bilan web_app_data maydonli xabarni "eshittiramiz":
<?php
use SergiX44\Nutgram\Nutgram;
$bot = Nutgram::fake();
$bot->onWebAppData(function (Nutgram $bot) {
$payload = $bot->message()?->web_app_data;
$bot->sendMessage("Qabul qilindi: {$payload->data}");
});
// Mini App sendData('order:42') qilgandek xabarni eshittiramiz
$bot->hearMessage([
'web_app_data' => ['data' => 'order:42', 'button_text' => 'Buyurtma'],
])->reply();
$bot->assertReplyText('Qabul qilindi: order:42');
echo "onWebAppData ishladi\n";
setChatMenuButton chaqiruvi haqiqatan Telegram'ga ketishini ham tasdiqlash mumkin:
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot = Nutgram::fake();
$bot->setChatMenuButton(
menu_button: new MenuButtonWebApp('Ilova', WebAppInfo::make('https://example.com/app')),
);
$bot->assertCalled('setChatMenuButton');
echo "setChatMenuButton chaqirildi\n";
Men shu bob uchun yozgan tekshiruv skripti (WebAppInfo::make, inline/reply web_app tugma, MenuButtonWebApp new bilan + makening static emasligi, setChatMenuButton chaqiruvi, onWebAppData routing va oddiy matn uni ishga tushirmasligi) β jami 11 ta tasdiq Nutgram 4.46 + PHP 8.4 da 0 xato bilan o'tdi. Bu kod naqshlarining haqiqatan ishlashini bildiradi.
Tekshirib bo'lmaydigan (halol illustrativ) qismlar: Mini App'ning Telegram ichida real render bo'lishi, telegram-web-app.js SDK'ning jonli ishlashi (ready/expand/MainButton), va real qurilmadan kelgan jonli sendData. Bularning hammasi public HTTPS hosting va haqiqiy Telegram ilovasini talab qiladi.
Mashqlar¶
Oson¶
/ilovakomandasiga bitta inline tugmali xabar yuboring; tugmahttps://example.com/appMini App'ini ochsin. Qaysi argument orqali (url:yokiweb_app:) berasiz?WebAppInfo::make(...)gahttp://(HTTPS emas) URL bersangiz, Telegram qabul qiladimi? Hujjat talabini ayting.- Reply klaviaturada
web_apptugmasi (Formani ochish) yuboring. Bunday tugma inline'dan qaysi muhim xususiyati bilan farq qiladi (sendDatahaqida o'ylang)? - Menyu tugmasini Mini App ochadigan qilib sozlang.
MenuButtonWebApp'niMenuButtonWebApp::make(...)deb yozsangiz nima bo'ladi va to'g'ri yo'l qaysi? telegram-web-app.jsfaylini HTML'ga qaysi URL'dan ulaysiz? Uni o'z serveringizga nusxalab qo'yish tavsiya etiladimi?- Frontend JS'da Mini App yuklangach birinchi chaqirilishi kerak bo'lgan metod qaysi (
ready/expand/close)? U nima qiladi?
O'rta¶
onWebAppDatahandleri yozing: kelganweb_app_data->datani o'qib, foydalanuvchigaMini App'dan keldi: ...deb javob bersin. Ma'lumotga qaysi yo'l orqali kirasiz ($bot->...)?- 7-mashqdagi handlerni
FakeNutgrambilan tekshiring:hearMessage(['web_app_data' => ['data' => 'salom', 'button_text' => 'Tugma']])->reply()qiling vaassertReplyTextbilan javobni tasdiqlang. - Mini App
sendData(JSON.stringify({rang: 'qizil'}))yuborgan deylik.onWebAppDataichida JSON'nijson_decodeqilib,rangqiymatini xavfsiz (massiv va kalit borligini tekshirib) chiqaring; noto'g'ri bo'lsaNoto'g'ri formatdeb javob bering. - Bitta xabarda
urltugmasi vaweb_apptugmasi birga bo'lgan inline klaviatura quring. Ikkalasidan qaysi biri botga signal yuboradi, qaysi biri shunchaki ochadi? setMenuForUser(Nutgram $bot, int $chatId, string $url)funksiyasini yozing: berilganchatIduchun (faqat shu chatda) Mini App ochadigan menyu tugmasini sozlasin.setChatMenuButton'ning qaysi argumentini ishlatasiz?- JS SDK'da
MainButtonniSotib olishmatni bilan ko'rsatib, bosilgandaHapticFeedbackbilan tebranish berib,tg.sendData(...)chaqiradigan frontend qism yozing (illustrativ β render shart emas).
Qiyin¶
- Kichik "ariza" oqimi quring:
/arizareply-web_app tugmasi (Ariza topshirish) yuborsin; Mini AppsendData(JSON.stringify({ism: 'Ali', tel: '+99890...'}))qilgan deb faraz qiling;onWebAppDataJSON'ni dekod qilib,ismvatelni alohida tekshirib, ikkalasi ham bo'lsaArizangiz qabul qilindi, Alidesin, aks holda xato xabarini bersin. Butun oqimniFakeNutgram(hearMessageweb_app_data bilan) tekshiring. - Bitta botda uchala ulanish yo'lini birga sozlang:
/dokoninline tugma bilan Mini App ochsin;/formareply-web_app tugma bilan;/menyu_ornatesa menyu tugmasini sozlasin. Uchala holatda bir xilWebAppInfo::make($url)ishlatib,$urlni bitta o'zgaruvchidan oling.MenuButtonWebApp'ni to'g'ri (newbilan) quring. onWebAppDataga kelgan ishonchsizdatani qanday "tozalash" (sanitize) kerakligini ko'rsatuvchi handler yozing: maksimal uzunlikni cheklang (masalan 256 belgi), JSON emasligini tekshiring va faqat oldindan ruxsat berilganactionqiymatlarini (['ha', 'yoq']) qabul qiling. Negaweb_app_data'ga ishonib bo'lmasligini izohda yozing va 24-bobga ishora qiling.
Yechimlar
1. web_app: argumenti orqali (url: shunchaki tashqi havola ochadi, Mini App emas):
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->onCommand('ilova', function (Nutgram $bot) {
$kb = InlineKeyboardMarkup::make()
->addRow(InlineKeyboardButton::make('Ochish', web_app: WebAppInfo::make('https://example.com/app')));
$bot->sendMessage('Ilova:', reply_markup: $kb);
});
2. Yo'q. WebAppInfo URL'i albatta HTTPS bo'lishi shart (http:// va localhost ham qabul qilinmaydi). Bu Telegram talabi β Mini App faqat xavfsiz ulanish orqali ochiladi.
3.
use SergiX44\Nutgram\Telegram\Types\Keyboard\ReplyKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\KeyboardButton;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->onCommand('forma', function (Nutgram $bot) {
$kb = ReplyKeyboardMarkup::make(resize_keyboard: true)
->addRow(KeyboardButton::make('Formani ochish', web_app: WebAppInfo::make('https://example.com/form')));
$bot->sendMessage('Forma:', reply_markup: $kb);
});
sendData() orqali botga to'g'ridan-to'g'ri ma'lumot qaytara oladi (onWebAppData bilan ushlaymiz). Inline web_app tugmada sendData ishlamaydi.
4.
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$bot->setChatMenuButton(
menu_button: new MenuButtonWebApp('Ilova', WebAppInfo::make('https://example.com/app')),
);
MenuButtonWebApp::make(...) deb yozsangiz xato bo'ladi β uning make() metodi static emas. To'g'ri yo'l β new MenuButtonWebApp($text, $webAppInfo).
5. https://telegram.org/js/telegram-web-app.js dan:
6. ready() β birinchi chaqiriladi. U Telegram'ga ilova yuklanib bo'lganini bildiradi va yuklanish ekranini (yopiq holatni) olib tashlaydi.
7.
$bot->onWebAppData(function (Nutgram $bot) {
$data = $bot->message()?->web_app_data?->data ?? '';
$bot->sendMessage("Mini App'dan keldi: {$data}");
});
$bot->message()->web_app_data->data orqali olinadi.
8.
$bot = Nutgram::fake();
$bot->onWebAppData(function (Nutgram $bot) {
$data = $bot->message()?->web_app_data?->data ?? '';
$bot->sendMessage("Mini App'dan keldi: {$data}");
});
$bot->hearMessage(['web_app_data' => ['data' => 'salom', 'button_text' => 'Tugma']])->reply();
$bot->assertReplyText("Mini App'dan keldi: salom");
9.
$bot->onWebAppData(function (Nutgram $bot) {
$raw = $bot->message()?->web_app_data?->data ?? '';
$decoded = json_decode($raw, associative: true);
if (!is_array($decoded) || !isset($decoded['rang'])) {
$bot->sendMessage('Noto\'g\'ri format');
return;
}
$bot->sendMessage("Tanlangan rang: {$decoded['rang']}");
});
10.
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$kb = InlineKeyboardMarkup::make()
->addRow(
InlineKeyboardButton::make('Sayt', url: 'https://ioqil.uz'),
InlineKeyboardButton::make('Ilova', web_app: WebAppInfo::make('https://example.com/app')),
);
url tashqi havolani, web_app Mini App'ni ochadi (faqat reply-web_app sendData qilsa botga keladi).
11.
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
function setMenuForUser(Nutgram $bot, int $chatId, string $url): void
{
$bot->setChatMenuButton(
chat_id: $chatId,
menu_button: new MenuButtonWebApp('Ilovani ochish', WebAppInfo::make($url)),
);
}
chat_id argumenti berilganda β faqat shu chatda; berilmasa, barcha shaxsiy chatlar uchun default o'zgaradi.
12.
const tg = window.Telegram.WebApp;
tg.ready();
tg.MainButton.setText('Sotib olish');
tg.MainButton.show();
tg.MainButton.onClick(function () {
tg.HapticFeedback.impactOccurred('medium');
tg.sendData(JSON.stringify({ action: 'buy' }));
});
13.
$bot->onCommand('ariza', function (Nutgram $bot) {
$kb = ReplyKeyboardMarkup::make(resize_keyboard: true)
->addRow(KeyboardButton::make('Ariza topshirish', web_app: WebAppInfo::make('https://example.com/ariza')));
$bot->sendMessage('Ariza:', reply_markup: $kb);
});
$bot->onWebAppData(function (Nutgram $bot) {
$raw = $bot->message()?->web_app_data?->data ?? '';
$d = json_decode($raw, associative: true);
if (!is_array($d) || empty($d['ism']) || empty($d['tel'])) {
$bot->sendMessage('Ma\'lumot to\'liq emas.');
return;
}
$bot->sendMessage("Arizangiz qabul qilindi, {$d['ism']}");
});
// FakeNutgram tekshiruvi:
$fake = Nutgram::fake();
// ... yuqoridagi onWebAppData handlerini $fake ga ulang ...
$fake->hearMessage(['web_app_data' => [
'data' => json_encode(['ism' => 'Ali', 'tel' => '+99890']),
'button_text' => 'Ariza topshirish',
]])->reply();
$fake->assertReplyText('Arizangiz qabul qilindi, Ali');
14.
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\Keyboard\ReplyKeyboardMarkup;
use SergiX44\Nutgram\Telegram\Types\Keyboard\KeyboardButton;
use SergiX44\Nutgram\Telegram\Types\Command\MenuButtonWebApp;
use SergiX44\Nutgram\Telegram\Types\WebApp\WebAppInfo;
$url = 'https://example.com/app';
$bot->onCommand('dokon', function (Nutgram $bot) use ($url) {
$kb = InlineKeyboardMarkup::make()
->addRow(InlineKeyboardButton::make('Do\'kon', web_app: WebAppInfo::make($url)));
$bot->sendMessage('Do\'kon:', reply_markup: $kb);
});
$bot->onCommand('forma', function (Nutgram $bot) use ($url) {
$kb = ReplyKeyboardMarkup::make(resize_keyboard: true)
->addRow(KeyboardButton::make('Forma', web_app: WebAppInfo::make($url)));
$bot->sendMessage('Forma:', reply_markup: $kb);
});
$bot->onCommand('menyu_ornat', function (Nutgram $bot) use ($url) {
$bot->setChatMenuButton(menu_button: new MenuButtonWebApp('Ilova', WebAppInfo::make($url)));
$bot->sendMessage('Menyu tugmasi sozlandi.');
});
15.
$bot->onWebAppData(function (Nutgram $bot) {
// web_app_data MIJOZDAN keladi β ISHONCHSIZ. Yomon niyatli foydalanuvchi
// bu yerga istalgan narsani qo'yishi mumkin. Shuning uchun har doim tekshiramiz.
// Muhim amallar uchun esa sendData EMAS, initData serverda tekshiriladi (24-bob).
$raw = $bot->message()?->web_app_data?->data ?? '';
if (mb_strlen($raw) > 256) { // uzunlikni cheklaymiz
$bot->sendMessage('Ma\'lumot juda uzun.');
return;
}
$d = json_decode($raw, associative: true);
if (!is_array($d) || !isset($d['action'])) { // JSON va kalitni tekshiramiz
$bot->sendMessage('Noto\'g\'ri format.');
return;
}
$ruxsat = ['ha', 'yoq'];
if (!in_array($d['action'], $ruxsat, strict: true)) { // oq ro'yxat (whitelist)
$bot->sendMessage('Ruxsat etilmagan amal.');
return;
}
$bot->sendMessage("Tanlov qabul qilindi: {$d['action']}");
});
β¬ οΈ Oldingi: 22 β Majburiy obuna Β· π README Β· Keyingi: 24 β Web App xavfsizligi: initData β‘οΈ