13 β Webhook va running mode¶
β¬ οΈ Oldingi: 12 β Maxsus xususiyatlar Β· π README Β· Keyingi: 14 β To'lovlar va Telegram Stars β‘οΈ
Bu bobda: Botingiz Telegram'dan update'larni qanday qabul qiladi β ana shu masalani chuqur ko'ramiz. Ikki yo'l bor: polling (bot o'zi Telegram'dan "yangilik bormi?" deb so'rab turadi) va webhook (Telegram update'ni botning HTTPS manziliga o'zi itarib yuboradi). Avval ikkalasining ichki mexanikasini, afzallik/kamchiligini va qachon qaysi birini tanlashni tushunamiz. So'ng Nutgram'ning running mode tushunchasini o'rganamiz:
Polling,Webhook,SingleUpdate,Fakesinflari,setRunningMode()/getRunningMode()va$bot->run()ularni qanday boshqarishi. Keyin webhook'ni amalda sozlaymiz:setWebhook/deleteWebhook/getWebhookInfo, webhook endpoint (index.php, nginx + php-fpm orqali),secret_tokenbilan himoya (safeMode), SSL talablari vahash_equalsbilan doimiy-vaqtli taqqoslash. Oxirida pollingβwebhook o'rtasida xavfsiz almashish va tipik xatolar (502, "Webhook is already set", sekin javob) ko'rib chiqiladi.Halol eslatma (verifikatsiya): Running mode mantig'i β
Webhooksinfini yaratish,secretToken/safeMode(setSafeModefluent qaytishi),setRunningMode()->getRunningMode()reflektsiyasi,setWebhook/deleteWebhook/getWebhookInfometodlari mavjudligi,hash_equalsbilan token taqqoslash va webhook handler'iNutgram::fake()ostida β bularning hammasi offline, tokensiz, internetsiz HAQIQATAN ishga tushirilib tekshirildi (Nutgram 4.46, PHP 8.4; 22/22 tekshiruv o'tdi). Ammo jonli webhook β bu public HTTPS URL, real domen/SSL sertifikat va BotFather tokenini talab qiladi: shuning uchunsetWebhookchaqiruvi, nginx/php-fpm konfiguratsiyasi va Telegram'ning real POST so'rovi illustrativ β "jonli HTTPS hosting kerak" deb belgilangan. Kod va mantiq to'g'ri; faqat jonli yetkazib berish qismi o'zingizning serveringizda ko'rinadi.
1. Muammo: update qayerdan keladi?¶
Avvalgi boblarda biz handler yozdik (onCommand, onText, onCallbackQuery), klaviatura qurdik, conversation va middleware ishlatdik. Lekin bitta savol fonda turardi: handlergacha update qanday yetib keladi? Botingiz qayerdadir ishlab turishi va Telegram serveridan yangi xabarlarni olishi kerak. Buning ikki yo'li bor.
- Polling (so'rab-tortish, pull): botingiz Telegram'ga
getUpdatesso'rovini doimiy yuboradi: "men uchun yangilik bormi?". Telegram javob beradi (yangi update'lar yoki bo'sh ro'yxat), bot ularni qayta ishlaydi va yana so'raydi. Bu cheksiz halqa. Aynan shuni$bot->run()CLI'da bajaradi (1-bobdan beri ishlatib kelgan usul). - Webhook (itarish, push): siz Telegram'ga "har bir update'ni mana shu HTTPS manzilimga POST qilib yubor" deb aytasiz. Endi bot doimiy so'rab turmaydi β Telegram update kelishi bilan o'zi sizning serveringizga so'rov yuboradi. Bot esa oddiy veb-ilova kabi ishlaydi: so'rov keldi -> bitta update'ni qayta ishladi -> javob qaytardi -> tugadi.
Bu β "men do'konga har 5 daqiqada qo'ng'iroq qilib, buyurtma bormi deb so'rayman" (polling) va "do'kon menga buyurtma kelishi bilan o'zi qo'ng'iroq qiladi" (webhook) farqiga o'xshaydi. Ikkinchisi tezroq va resursni tejaydi, lekin sizda do'kon qo'ng'iroq qila oladigan doimiy raqam (public HTTPS URL) bo'lishi shart.
Polling va webhook bilan birinchi marta 1-bobda umumiy tanishgan edik. Bu bobda esa ichki mexanikani, Nutgram sinflarini va production sozlamasini chuqur ochamiz.
2. Polling chuqurroq¶
Polling β getUpdates metodiga asoslangan. Nutgram'ning Polling running mode sinfi soddalashtirilgan ko'rinishda quyidagicha ishlaydi (bu kontseptual ko'rinish β siz bu kodni yozmaysiz, Nutgram o'zi bajaradi):
<?php
// Polling running mode'ning soddalashtirilgan ichki mantig'i (illustrativ)
$offset = null;
while (true) {
// long polling: timeout soniyagacha kutadi, update kelsa darrov qaytaradi
$updates = $bot->getUpdates(
offset: $offset,
limit: 100,
timeout: 25, // long polling oynasi (soniya)
);
foreach ($updates as $update) {
$bot->processUpdate($update); // handlerlarni ishga tushiradi
$offset = $update->update_id + 1; // keyingi safar shu update'dan keyin
}
}
Bu yerda ikki muhim tushuncha bor:
offset(siljish): har bir update'daupdate_idbo'ladi.offsetni "oxirgi ko'rganupdate_id+ 1" qilib yuborsangiz, Telegram allaqachon olganlaringizni qayta yubormaydi β ya'nioffset"tasdiq" (acknowledge) vazifasini bajaradi. Buni Nutgram avtomatik boshqaradi.- Long polling:
timeoutparametri tufayligetUpdatesdarhol bo'sh javob qaytarmaydi β Telegram update kelguncha (yokitimeouttugaguncha) ulanishni ochiq ushlab turadi. Shu sabab "har soniyada minglab bo'sh so'rov" bo'lmaydi; bu long polling, oddiy "short polling" emas.
Polling'ning eng muhim cheklovi: bir vaqtda faqat bitta polling-jarayon ishlashi kerak. Agar ikki nusxa bir xil token bilan getUpdates chaqirsa, ular offset uchun "urishadi" va update'lar tartibsiz bo'linib ketadi (Telegram 409 Conflict qaytarishi mumkin). Shuningdek, polling doimiy ishlovchi jarayon talab qiladi β uni systemd/supervisor bilan tirik ushlab turish kerak (17-bobda batafsil).
Polling muhim plyusi: public URL ham, SSL ham, domen ham kerak emas. Noutbukingizda, lokalda, hatto NAT orqasida ham ishlaydi β chiquvchi ulanish yetarli. Shuning uchun rivojlanish uchun ideal.
3. Webhook chuqurroq¶
Webhook'da rollar teskari. Siz bir marta Telegram'ga aytasiz: "endi update'larni https://bot.example.uz/webhook manziliga POST qil". Shundan keyin har bir yangi update β bu sizning serveringizga keladigan bitta HTTP so'rov. So'rov tanasida (php://input) bitta update'ning JSON'i bo'ladi.
Yo'lni qadamma-qadam ko'ramiz:
- Foydalanuvchi botga xabar yozadi -> Telegram serveriga boradi.
- Telegram darhol
https://bot.example.uz/webhookmanziliga POST so'rovini yuboradi; tanasida update JSON, sarlavhada (agar siz so'ragan bo'lsangiz)X-Telegram-Bot-Api-Secret-Token. - nginx 443-portda (HTTPS) so'rovni qabul qiladi, SSL'ni hal qiladi va uni php-fpm'ga uzatadi.
- php-fpm
index.php'ni ishga tushiradi; uphp://input'dan JSON'ni o'qiydi. - Nutgram (
Webhookrunning mode) update'ni o'qiydi, kerak bo'lsasecret_token'ni tekshiradi va handler'ni ishga tushiradi. - Skript
200 OKqaytaradi va tugaydi. Telegram200ni oladi va update'ni "yetkazilgan" deb belgilaydi.
Eng muhim farq: webhook'da bot doimiy halqa emas. Har bir so'rov uchun PHP skripti yangidan ishga tushadi, bitta update'ni qayta ishlaydi va o'ladi β xuddi oddiy veb-sahifa kabi. Bu php-fpm modeliga juda mos: o'nlab so'rov bir vaqtda parallel ishlanaveradi, "yagona jarayon" cheklovi yo'q.
Telegram 200-javobini tez kutadi. Agar index.php sekin ishlasa (masalan, ichida minglab odamga broadcast qilsa), Telegram bu update'ni "yetkazilmadi" deb qayta-qayta yuborishi yoki webhook'ni "sog'lom emas" deb belgilashi mumkin. Qoida: webhook handler'i tez yopilsin; og'ir ish (broadcast, tashqi API, sekin DB-yozuv) navbatga (queue) qo'yilsin va alohida worker bajarsin (15-bob).
4. Nutgram running mode'lari¶
Polling ham, webhook ham bir xil narsani qiladi: update oladi va processUpdate() orqali handlerlarga uzatadi. Faqat update'ni qabul qilish usuli farq qiladi. Nutgram buni running mode degan tushuncha bilan ajratadi β bu processUpdates(Nutgram $bot) metodiga ega sinf. $bot->run() aslida shunchaki joriy running mode'ning processUpdates()'ini chaqiradi.
Nutgram'da to'rt running mode bor:
| Running mode | Sinf | Update qayerdan | Qachon |
|---|---|---|---|
| Polling | RunningMode\Polling |
getUpdates halqasi (CLI) |
Rivojlanish, kichik bot. CLI'da default |
| Webhook | RunningMode\Webhook |
php://input (HTTP POST) |
Production, public HTTPS server |
| SingleUpdate | RunningMode\SingleUpdate |
Bitta update'ni o'qiydi, halqasiz | cron / bir martalik qayta ishlash |
| Fake | RunningMode\Fake |
Test uchun soxta update'lar | Nutgram::fake() (16-bob) |
setRunningMode() rejimni o'rnatadi, getRunningMode() esa joriy rejim sinf nomini (string) qaytaradi. Buni offline tekshirib ko'rdik:
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\RunningMode\Webhook;
use SergiX44\Nutgram\RunningMode\Polling;
$bot = Nutgram::fake();
$bot->setRunningMode(new Webhook(secretToken: 'tok'));
echo $bot->getRunningMode(); // SergiX44\Nutgram\RunningMode\Webhook
$bot->setRunningMode(Polling::class);
echo $bot->getRunningMode(); // SergiX44\Nutgram\RunningMode\Polling
setRunningMode() ham instans (new Webhook(...)), ham sinf nomi (Polling::class) qabul qiladi. Instans kerak bo'lsa β masalan Webhook'ga secret_token uzatish uchun β yangi obyekt yarating; sozlama kerak bo'lmasa, sinf nomini bering yetarli.
Diqqat:
Pollingrunning mode faqat CLI'da (php bot.php) yaratiladi β konstruktori SAPI'ni tekshiradi va veb-so'rovdaRuntimeExceptiontashlaydi. Bu mantiqiy: veb-server ichida cheksiz halqa ishlatib bo'lmaydi. Webhook esa aksincha β u veb-so'rov ichida ishlaydi.
5. Webhook'ni o'rnatish: setWebhook¶
Telegram'ga "update'larni mana shu URL'ga yubor" deyish uchun bir marta setWebhook chaqiriladi. Bu metod tasdiqlangan imzoga ega:
setWebhook(
string $url,
?InputFile $certificate = null,
?string $ip_address = null,
?int $max_connections = null,
?array $allowed_updates = ...,
?bool $drop_pending_updates = null,
?string $secret_token = null
): ?bool
Odatda buni alohida bir martalik skript (yoki Artisan-uslubidagi komanda) sifatida yozasiz va deploy paytida bir marta ishga tushirasiz:
<?php
// set-webhook.php β bir marta ishga tushiriladigan skript
// ILLUSTRATIV: jonli ishlashi uchun haqiqiy token + public HTTPS URL kerak.
require __DIR__ . '/vendor/autoload.php';
use SergiX44\Nutgram\Nutgram;
$bot = new Nutgram($_ENV['TELEGRAM_TOKEN']);
$ok = $bot->setWebhook(
url: 'https://bot.example.uz/webhook',
secret_token: $_ENV['WEBHOOK_SECRET'], // Telegram har so'rovda shu sarlavhani qo'shadi
drop_pending_updates: true, // eski navbatdagi update'larni tashlab yubor
// allowed_updates: ['message', 'callback_query'], // faqat keraklilarini ol (ixtiyoriy)
);
var_dump($ok); // true β webhook o'rnatildi
Muhim parametrlar:
urlβ HTTPS bo'lishi shart (HTTP qabul qilinmaydi). Telegram faqat 443, 80, 88, 8443 portlarini qo'llaydi.secret_tokenβ 1β256 belgili maxfiy satr (AβZ aβz 0β9 _ -). Telegram har bir POST so'rovda uniX-Telegram-Bot-Api-Secret-Tokensarlavhasida qaytaradi. Bu β webhook'ingizga faqat Telegram so'rov yuborayotganini tasdiqlash usuli (6-bo'limda ishlatamiz). Tokenni.env'da saqlang.drop_pending_updates: trueβ ag'darilishdan oldin polling/eski rejimda yig'ilib qolgan update'larni tashlaydi (ko'pincha deploy paytida foydali).allowed_updatesβ faqat kerakli update turlarini cheklash; berilmasa Nutgram oqilona default ro'yxatni yuboradi.
HALOL: Bu skriptni RUN qilib "webhook o'rnatildi" deb tasdiqlay olmaymiz β
setWebhookTelegram'ga real tarmoq so'rovi yuboradi va public HTTPS URL hamda haqiqiy token talab qiladi. Metod imzosi va parametrlari esa o'rnatilgan Nutgram 4.46 manbasidan tekshirildi β xayoliy emas.
6. Webhook endpoint: index.php¶
Server tomonida webhook β bu oddiy bitta fayl: public/index.php. nginx + php-fpm uni har bir POST so'rovda ishga tushiradi. Bu fayl Nutgram'ni quradi, running mode'ni Webhook qilib o'rnatadi va $bot->run() chaqiradi:
<?php
// public/index.php β webhook endpoint
// ILLUSTRATIV jonli qism: nginx/php-fpm + public HTTPS kerak. Mantiq esa to'g'ri.
require __DIR__ . '/../vendor/autoload.php';
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\RunningMode\Webhook;
$bot = new Nutgram($_ENV['TELEGRAM_TOKEN']);
// 1) Webhook running mode + secret_token tekshiruvini yoqamiz
$bot->setRunningMode(
(new Webhook(secretToken: $_ENV['WEBHOOK_SECRET']))
->setSafeMode(true) // sarlavha mos kelmasa update e'tiborsiz qoldiriladi
);
// 2) Handlerlar β polling'dagi bilan AYNAN bir xil
$bot->onCommand('start', function (Nutgram $bot) {
$bot->sendMessage('Salom! Bu bot webhook orqali ishlayapti.');
});
// 3) run() β Webhook mode'da php://input dan bitta update'ni o'qib qayta ishlaydi
$bot->run();
E'tibor bering: handlerlar o'zgarmadi. Polling'dan webhook'ga o'tish β bu faqat "update qayerdan keladi" masalasi; bot mantig'i (handler, conversation, middleware) bir xil qoladi. Aynan shuning uchun rivojlanishni polling'da qilib, production'da webhook'ga o'tish oson.
setSafeMode(true) β Webhook sinfining ichki himoyasini yoqadi: kelgan so'rovdagi X-Telegram-Bot-Api-Secret-Token sarlavhasini siz bergan secretToken bilan solishtiradi; mos kelmasa update shunchaki tashlanadi (processUpdate chaqirilmaydi). Buni offline tasdiqladik:
<?php
use SergiX44\Nutgram\RunningMode\Webhook;
$wh = new Webhook(secretToken: 'super-secret-123');
var_dump($wh->isSafeMode()); // bool(false) β default o'chiq
$wh->setSafeMode(true);
var_dump($wh->isSafeMode()); // bool(true)
// setSafeMode fluent β o'zini qaytaradi, shuning uchun zanjirlash mumkin:
$wh = (new Webhook(secretToken: 'x'))->setSafeMode(true);
Eslatma β
secretToken(camelCase) konstruktor parametri.WebhookPHP sinfining konstruktor parametri nomisecretToken. Telegram tomonidagi (setWebhookmetodida) parametr esasecret_token(snake_case). Ikkalasiga ham bir xil qiymat bering β biri Telegram'ga "shu tokenni qaytar" deydi, ikkinchisi serverda "shu token kelganini tekshir" deydi.
7. secret_token bilan himoya va doimiy-vaqtli taqqoslash¶
Webhook URL'ingiz ochiq internetda. Agar kimdir uni topib qolsa, soxta "update" yuborib botingizni aldashga urinishi mumkin. secret_token aynan shundan himoya qiladi: faqat Telegram to'g'ri sarlavhani biladi.
setSafeMode(true) ichki tekshiruvni yoqadi, lekin tekshiruvni qo'lda ham yozish foydali β mantiqni tushunish va o'z endpoint'ingizda nazorat qilish uchun. Eng muhim qoida: tokenlarni hash_equals() bilan solishtiring, oddiy === bilan emas.
<?php
// Qo'lda secret_token tekshiruvi (Slim yoki sof PHP endpoint uchun)
$expected = $_ENV['WEBHOOK_SECRET'];
$received = $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] ?? '';
// hash_equals β DOIMIY VAQTLI taqqoslash: timing-attack'dan himoya qiladi
if (!hash_equals($expected, $received)) {
http_response_code(403);
exit; // Telegram emas β rad etamiz
}
Nega === emas? Oddiy satr taqqoslash birinchi farq qilgan belgida to'xtaydi β ya'ni taqqoslash vaqti to'g'ri belgilar soniga bog'liq. Hujumchi shu mikro-farqni o'lchab tokenni belgi-belgi tiklashga urinishi mumkin (timing attack). hash_equals() esa har doim bir xil vaqt sarflaydi. Buni tekshirdik:
<?php
$expected = 'my-secret-token';
var_dump(hash_equals($expected, 'my-secret-token')); // bool(true)
var_dump(hash_equals($expected, 'soxta')); // bool(false)
var_dump(hash_equals($expected, '')); // bool(false)
Maxfiy ma'lumotlarni (token, parol, HMAC) solishtirganda doim
hash_equals()ishlating. Bu xuddi Web AppinitData'ni tekshirgandagi qoida bilan bir xil (24-bobda batafsil).
8. SSL va nginx (production konturi)¶
Webhook albatta HTTPS bo'lishi kerak. Ikki yo'l:
- Ishonchli sertifikat (Let's Encrypt /
certbotorqali bepul) β eng keng tarqalgan. Telegram sertifikatni avtomatik ishonadi,setWebhook'da sertifikat yuborish shart emas. - Self-signed sertifikat β o'zingiz imzolagan; bu holda uni
setWebhook'gacertificate: InputFile::make('cert.pem')orqali yuborishingiz kerak. Production uchun tavsiya etilmaydi β Let's Encrypt osonroq va bepul.
nginx konfiguratsiyasining illustrativ namunasi (server tomonida, bu kitobdan tashqarida ishlaydi):
# /etc/nginx/sites-available/bot β ILLUSTRATIV (jonli server kerak)
server {
listen 443 ssl;
server_name bot.example.uz;
ssl_certificate /etc/letsencrypt/live/bot.example.uz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bot.example.uz/privkey.pem;
root /var/www/bot/public; # index.php shu yerda
index index.php;
location /webhook {
try_files $uri /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.4-fpm.sock; # php-fpm
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Oqim: https://bot.example.uz/webhook -> nginx (SSL'ni yechadi) -> php-fpm soketi -> index.php -> Nutgram. Telegram POST tanasi php://input'da, secret_token sarlavhasi $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN']'da bo'ladi.
HALOL: Bu nginx bloki va SSL sertifikatlari illustrativ β ularni jonli serverda (VPS, Let's Encrypt bilan) sinab ko'rasiz. Tokensiz/serversiz bu qismni RUN qilib bo'lmaydi. Production deploy'ning to'liq retsepti β 17-bobda.
9. Webhook holatini tekshirish va o'chirish¶
Webhook to'g'ri o'rnatilganini bilish uchun getWebhookInfo chaqiriladi β u joriy URL, kutilayotgan update'lar soni va oxirgi xatoni qaytaradi (debug uchun oltin):
<?php
// ILLUSTRATIV: jonli token + tarmoq kerak.
$info = $bot->getWebhookInfo();
echo $info->url; // 'https://bot.example.uz/webhook' yoki bo'sh
echo $info->pending_update_count; // kutilayotgan update'lar soni
echo $info->last_error_message ?? ''; // oxirgi xato (masalan, "Wrong response from the webhook: 502")
last_error_message β webhook ishlamayotganda birinchi qaraydigan joy. "502 Bad Gateway" -> php-fpm/nginx muammosi; "SSL error" -> sertifikat muammosi; bo'sh -> hammasi joyida.
Webhook'ni o'chirib, polling'ga qaytish uchun deleteWebhook:
<?php
// ILLUSTRATIV: jonli token + tarmoq kerak.
$bot->deleteWebhook(drop_pending_updates: true);
// Endi $bot->run() ni CLI'da polling sifatida ishlatish mumkin
Muhim qoida: bir bot bir vaqtning o'zida yo polling, yo webhook β ikkalasi birga emas. Agar webhook o'rnatilgan bo'lsa va siz getUpdates (polling) chaqirsangiz, Telegram 409 Conflict yoki "Conflict: can't use getUpdates method while webhook is active" xatosini qaytaradi. Polling'ga o'tishdan oldin avval deleteWebhook chaqiring.
10. Qachon polling, qachon webhook?¶
Qaror jadvali:
| Holat | Tavsiya |
|---|---|
| Lokalda rivojlanyapsiz, noutbukda | Polling β sozlash 0, darrov ishlaydi |
| Domen/SSL hali yo'q, foydalanuvchi kam | Polling |
| Production, public HTTPS domen bor | Webhook |
| Minglab foydalanuvchi, yuqori yuk | Webhook β kam resurs, kengayadi |
| Serverless / faqat HTTP so'rovga javob (cron emas) | Webhook |
| cron orqali vaqti-vaqti bilan update yig'ish | SingleUpdate |
| Avtomatik test | Fake (Nutgram::fake(), 16-bob) |
Amaliy yo'l ko'pchilik loyihalarda: rivojlanishda polling, deploy'da webhook. Kod bir xil β faqat index.php'da running mode'ni almashtirasiz va bir marta setWebhook ishlatasiz. Polling'dan webhook'ga (yoki teskari) o'tishda avval eskisini bekor qiling (deleteWebhook yoki polling jarayonini to'xtatish), so'ng yangisini yoqing β 409 Conflictdan shunday qochiladi.
11. SingleUpdate: cron uslubidagi rejim¶
SingleUpdate β kam ishlatiladigan, lekin foydali rejim. U Polling'dan meros oladi, lekin halqasiz: bitta update'ni o'qiydi, qayta ishlaydi va chiqadi. Bu β webhook o'rnatib bo'lmaydigan, lekin doimiy jarayon ham xohlamaydigan holatlar uchun (masalan, har daqiqada cron orqali "yangilik bormi?" deb tekshirish):
<?php
// run-once.php β cron har daqiqada ishga tushiradi (illustrativ; jonli token kerak)
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\RunningMode\SingleUpdate;
$bot = new Nutgram($_ENV['TELEGRAM_TOKEN']);
$bot->setRunningMode(SingleUpdate::class);
$bot->onCommand('start', fn (Nutgram $bot) => $bot->sendMessage('Salom!'));
$bot->run(); // bitta update'ni oladi va chiqadi
Bu webhook bilan polling o'rtasidagi "o'rta yo'l": doimiy jarayon kerak emas, public URL ham kerak emas, lekin javob real vaqtda emas β cron qadami bilan kechikadi.
12. Tipik xatolar va ularni hal qilish¶
409 Conflict/ "can't use getUpdates while webhook is active": webhook o'rnatilgan, lekin polling ham ishlayapti. Yechim:deleteWebhookchaqiring yoki webhook'da qoling.- Telegram 502/504 qaytaradi (
last_error_messageda): nginx php-fpm bilan bog'lanolmayapti yoki skript halok bo'ldi/sekin. php-fpm log'ini vafastcgi_passsoketini tekshiring. - Update'lar kelmayapti, lekin xato yo'q:
allowed_updatesda kerakli tur cheklanib qolganmi? Masalancallback_queryni qo'shmagan bo'lsangiz, inline tugma bosishlari kelmaydi.getWebhookInfo'daallowed_updatesni tekshiring. - Soxta so'rovlar:
secret_tokeno'rnatmagansiz.setSafeMode(true)+secretTokenbilan yoping. - Webhook sekin, Telegram qayta yuborayapti: og'ir ish (broadcast, tashqi API) handler ichida sinxron bajarilyapti. Uni navbatga (queue) ko'chiring (15-bob) β webhook tez
200qaytarsin. - HTTP URL ishlamayapti: Telegram faqat HTTPS qabul qiladi. SSL sertifikat o'rnating (Let's Encrypt).
Solishtirish (Python/aiogram): aiogram'da ekvivalent β
bot.set_webhook(...)vaaiohttp/ASGI server bilan endpoint, polling esadp.start_polling(bot). G'oya bir xil; faqat PHP'da webhook php-fpm so'rov-modeliga (har so'rov = yangi skript), aiogram'da esa doimiy ASGI jarayoniga tayanadi. Qarang ../tgbot-python/README.md.
Mashqlar¶
Oson¶
- Polling va webhook orasidagi asosiy farqni bir jumlada ayting: "kim kimga so'rov yuboradi?". Har biriga bittadan misol holat keltiring.
setRunningMode()ham instans, ham sinf nomi qabul qiladi.Pollinguchun qaysi shaklni ishlatish qulay,Webhook(secret_token bilan) uchun qaysi shaklni β va nega?Webhookrunning mode'nisecretToken: 'abc'bilan yarating vaisSafeMode()qiymatini tekshiring. Default qiymat qanaqa?setSafeMode(true)chaqiruvi nima qaytaradi? Nega bu "fluent" deb ataladi va u nimaga yordam beradi?- Telegram webhook uchun qaysi protokol (HTTP yoki HTTPS) talab qilinadi?
setWebhook'gahttp://...bersangiz nima bo'ladi? getWebhookInfoqaytargan ma'lumotda webhook ishlamayotganini debug qilish uchun qaysi maydon eng foydali?
O'rta¶
hash_equals($expected, $received)uchun uchta holatni tekshiruvchiassertyozing: to'g'ri token, soxta token, bo'sh satr. Nega===o'rnigahash_equalsishlatamiz?setRunningMode(new Webhook(...))->getRunningMode()to'liq sinf nomini (string) qaytaradi.Nutgram::fake()bilan buniassertorqali tasdiqlang (Webhook, keyin Polling).- Bir martalik
set-webhook.phpskriptini yozing:url,secret_token(.env'dan) vadrop_pending_updates: truebilansetWebhookchaqirsin. Nega bu alohida skript,index.phpichida emas? index.phpendpoint'da handler (onCommand('start', ...)) yozing va uniNutgram::fake()bilan offline tekshiring (hearText('/start')->reply()+assertReplyText). Handler webhook va polling'da bir xil ishlashini izohlang.allowed_updates: ['message', 'callback_query']bersangiz, qaysi update turlari kelmaydi? Bu nima uchun foydali (resurs/maxfiylik)?- Webhook'dan polling'ga xavfsiz o'tish ketma-ketligini yozing (qaysi metodlar, qaysi tartibda) va nega
409 Conflictdan shunday qochish mumkinligini tushuntiring.
Qiyin¶
- Sof PHP
validateWebhookRequest()funksiyasini yozing: u$_SERVERsarlavhasidansecret_tokenni oladi, kutilgan token bilanhash_equalsorqali solishtiradi, mos kelmasa403qaytaradi. Funksiyaniassertbilan (to'g'ri/soxta token) tekshiring ($_SERVERni qo'lda to'ldiring). - Webhook handler'i Telegram'ni kuttirmasligi uchun "og'ir ish"ni qanday ajratish kerakligini tushuntiring. Sxema yozing: webhook
200qaytaradi -> ish navbatga qo'yiladi -> alohida worker bajaradi. Nega sinxron broadcast webhook ichida yomon? getWebhookInfodan keladiganlast_error_message'ning uchta tipik qiymatini (502, SSL, conflict) sanab, har biriga sabab va yechim yozing.https/hostmavjudligini tekshiruvchivalidWebhookUrl(string $url): boolyozing (parse_urlbilan). Uni uchta holatda (https://...valid,http://...invalid, hostsiz invalid)assertbilan tasdiqlang.
Yechimlar
Oson 1. Polling β bot Telegram'ga "yangilik bormi?" deb so'rab turadi (getUpdates); misol: lokalda rivojlanish. Webhook β Telegram botning HTTPS URL'iga update'ni o'zi POST qiladi; misol: public domenli production bot.
Oson 2. Polling uchun sinf nomi qulay: setRunningMode(Polling::class) β qo'shimcha sozlama kerak emas. Webhook (secret_token bilan) uchun instans kerak: setRunningMode(new Webhook(secretToken: '...')) β chunki tokenni konstruktorga uzatish lozim.
Oson 3.
<?php
use SergiX44\Nutgram\RunningMode\Webhook;
$wh = new Webhook(secretToken: 'abc');
var_dump($wh->isSafeMode()); // bool(false) β default O'CHIQ
safeMode β false, ya'ni setSafeMode(true) chaqirmasangiz secret_token avtomatik tekshirilmaydi.
Oson 4. setSafeMode(true) β $this (ya'ni Webhook obyektining o'zini) qaytaradi. "Fluent" deyiladi, chunki natijani darrov zanjirlash mumkin: (new Webhook(secretToken: 'x'))->setSafeMode(true). Bu yangi obyektni yaratib, darhol sozlab, setRunningMode'ga bir qatorda uzatishga yordam beradi.
Oson 5. Faqat HTTPS. http://... bersangiz Telegram webhook'ni rad etadi (xato qaytaradi) β shifrlanmagan ulanish qabul qilinmaydi.
Oson 6. last_error_message β webhook'ning oxirgi xatosini matn ko'rinishida beradi (masalan "Wrong response from the webhook: 502"). pending_update_count ham foydali (navbat to'lib ketganini ko'rsatadi).
O'rta 1.
<?php
$expected = 'my-secret-token';
assert(hash_equals($expected, 'my-secret-token') === true);
assert(hash_equals($expected, 'soxta') === false);
assert(hash_equals($expected, '') === false);
hash_equals β doimiy vaqtli taqqoslash: u har doim bir xil vaqt sarflaydi, shu sabab timing-attack orqali tokenni belgi-belgi tiklab bo'lmaydi. === esa birinchi farqda to'xtaydi va vaqt sizib chiqishi mumkin.
O'rta 2.
<?php
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\RunningMode\Webhook;
use SergiX44\Nutgram\RunningMode\Polling;
$bot = Nutgram::fake();
$bot->setRunningMode(new Webhook(secretToken: 'tok'));
assert($bot->getRunningMode() === Webhook::class);
$bot->setRunningMode(Polling::class);
assert($bot->getRunningMode() === Polling::class);
O'rta 3.
<?php
// set-webhook.php
require __DIR__ . '/vendor/autoload.php';
use SergiX44\Nutgram\Nutgram;
$bot = new Nutgram($_ENV['TELEGRAM_TOKEN']);
$ok = $bot->setWebhook(
url: 'https://bot.example.uz/webhook',
secret_token: $_ENV['WEBHOOK_SECRET'],
drop_pending_updates: true,
);
var_dump($ok);
setWebhook faqat bir marta (deploy paytida) ishlatiladi. Agar uni har bir webhook so'rovida (index.php) chaqirsangiz β bu har bir update uchun Telegram'ga ortiqcha tarmoq so'rovi bo'lardi: sekin va keraksiz.
O'rta 4.
<?php
use SergiX44\Nutgram\Nutgram;
$bot = Nutgram::fake();
$bot->onCommand('start', fn (Nutgram $bot) => $bot->sendMessage('Salom! Webhook orqali.'));
$bot->hearText('/start')->reply();
$bot->assertReplyText('Salom! Webhook orqali.');
processUpdate -> handler oqimi bir xil.
O'rta 5. allowed_updates: ['message', 'callback_query'] bersangiz, faqat shu ikki tur keladi; edited_message, my_chat_member, chat_member, poll va boshqalar kelmaydi. Foydasi: keraksiz update'larni qabul qilmaslik -> kam tarmoq/resurs sarfi va maxfiylik (masalan a'zolik o'zgarishlarini olishni xohlamasangiz).
O'rta 6.
<?php
// 1) Webhook'ni o'chir (eskisini bekor qil)
$bot->deleteWebhook(drop_pending_updates: true);
// 2) Endi CLI'da polling: setRunningMode(Polling::class) -> $bot->run()
deleteWebhook chaqirilgani uchun Telegram'da webhook faol qolmaydi; shuning uchun getUpdates (polling) 409 Conflict bermaydi. Webhook va polling hech qachon bir vaqtda faol bo'lmasligi kerak.
Qiyin 1.
<?php
function validateWebhookRequest(string $expected): bool
{
$received = $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] ?? '';
if (!hash_equals($expected, $received)) {
http_response_code(403);
return false;
}
return true;
}
// Test (CLI'da $_SERVER'ni qo'lda to'ldiramiz)
$_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] = 'secret123';
assert(validateWebhookRequest('secret123') === true);
$_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] = 'soxta';
assert(validateWebhookRequest('secret123') === false);
unset($_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN']);
assert(validateWebhookRequest('secret123') === false); // header yo'q -> bo'sh -> false
Qiyin 2. Webhook handler'i Telegram'dan 200 javobini tez kutadi (bir necha soniya). Agar handler ichida minglab odamga sinxron sendMessage qilsangiz, skript uzoq ishlaydi, Telegram 200ni kutmay update'ni "yetkazilmadi" deb qayta yuboradi β natijada bir xil ish takror bajariladi (double-send) va webhook "sog'lom emas" deb belgilanishi mumkin. Yechim sxemasi:
Telegram POST -> index.php:
1) update'ni navbatga qo'y (DB/Redis queue) β tez
2) 200 OK qaytar (skript yopiladi)
Alohida worker (cron/daemon):
3) navbatdan oladi -> broadcast/og'ir ishni bajaradi
Qiyin 3.
- "Wrong response from the webhook: 502 Bad Gateway" β sabab: nginx php-fpm bilan bog'lanolmadi yoki skript halok bo'ldi. Yechim: fastcgi_pass soketi/portini, php-fpm xizmati ishlayotganini va PHP xato log'ini tekshiring.
- "SSL error" / "certificate verify failed" β sabab: SSL sertifikat noto'g'ri/muddati o'tgan/zanjir to'liq emas. Yechim: Let's Encrypt sertifikatini yangilang, fullchain.pem ishlating.
- "Conflict: can't use getUpdates while webhook is active" β sabab: webhook o'rnatilgan, lekin polling ham ishlayapti. Yechim: polling'ni to'xtating yoki deleteWebhook chaqiring.
Qiyin 4.
<?php
function validWebhookUrl(string $url): bool
{
$p = parse_url($url);
return ($p['scheme'] ?? '') === 'https' && !empty($p['host']);
}
assert(validWebhookUrl('https://bot.example.uz/webhook') === true);
assert(validWebhookUrl('http://bot.example.uz/webhook') === false); // https emas
assert(validWebhookUrl('https:///webhook') === false); // host yo'q
β¬ οΈ Oldingi: 12 β Maxsus xususiyatlar Β· π README Β· Keyingi: 14 β To'lovlar va Telegram Stars β‘οΈ