როცა webhook-ზე მომუშავე Telegram ბოტი განახლებების მიღებას წყვეტს, პასუხი თითქმის ყოველთვის ერთ API გამოძახებაშია: getWebhookInfo. ის გეუბნება, რომელ URL-ზე ფიქრობს Telegram, რომ უნდა მიაწოდოს განახლებები, რომელი IP მისამართი ამოხსნა, რამდენი განახლებაა რიგში და - ყველაზე სასარგებლო - რა ბოლო შეცდომა დააბრუნა შენმა სერვერმა, უბრალო ტექსტად. წაიკითხე url, pending_update_count და last_error_message ერთად და გაიგებ, ოთხიდან რომელია გატეხილი: რეგისტრაცია, TLS, HTTP პასუხი თუ შენი handler-ის სიჩქარე. გაასწორე ის ერთი რამ და რიგში მდგარი განახლებები თავისით დაიცლება.
ეს პოსტი თემის პრობლემების გადაჭრის ნაწილია. polling-სა და webhook-ს შორის არჩევანი, BotFather-ის პარამეტრები, ბიბლიოთეკის კოდი და deploy განხილულია პოსტში Telegram bot hosting: polling და webhook; აქ webhook უკვე დაყენებულია და რაღაც არ აღწევს დანიშნულების ადგილს.
დაიწყე getWebhookInfo-თი#
მას პარამეტრები არ სჭირდება და მუშაობს ნებისმიერი მანქანიდან, სადაც token გაქვს, ამიტომ შეგიძლია ლეპტოპიდან გაუშვა, სანამ ბოტი სხვაგან მუშაობს:
$ curl -s "https://api.telegram.org/bot$BOT_TOKEN/getWebhookInfo"გაფუჭებული webhook დაახლოებით ასე გამოიყურება (წასაკითხად დაფორმატებული):
{ "ok": true, "result": { "url": "https://bot.example.com/tg/hook", "has_custom_certificate": false, "pending_update_count": 37, "ip_address": "203.0.113.10", "last_error_date": 1760511600, "last_error_message": "Wrong response from the webhook: 404 Not Found", "max_connections": 40, "allowed_updates": ["message", "callback_query"] }}ველები ისე, როგორც Bot API განსაზღვრავს:
| ველი | რას გეუბნება |
|---|---|
url | სად აწვდის Telegram განახლებებს. ცარიელი ნიშნავს, რომ webhook არ არის - ბოტი polling რეჟიმშია |
has_custom_certificate | true, თუ setWebhook-ით სერტიფიკატი ატვირთე |
pending_update_count | მიწოდების მომლოდინე განახლებები |
ip_address | მისამართი, რომელზეც Telegram რეალურად აგზავნის |
last_error_date | ბოლო მიწოდების წარუმატებლობის Unix დრო |
last_error_message | ამ წარუმატებლობის ადამიანისთვის გასაგები ტექსტი |
last_synchronization_error_date | სინქრონიზაციის შეცდომა Telegram-ის შიგნით, შენს მხარეს არა |
max_connections | ერთდროულად დაშვებული მიწოდებები, 1-100 |
allowed_updates | განახლების ტიპები, რომლებზეც ბოტია გამოწერილი |
არასავალდებულო ველები უბრალოდ ქრება, როცა თქმელი არაფერი აქვთ, ამიტომ ჯანმრთელ webhook-ს ან საერთოდ არ აქვს last_error_* გასაღებები, ან მხოლოდ ძველი თარიღი აქვს. last_error_date წამებია epoch-იდან; Linux-ზე date -d @1760511600 მას წასაკითხად გადააქცევს, და პირველი, რაც უნდა გააკეთო, მისი მიმდინარე დროსთან შედარებაა. სამი დღის წინანდელი შეცდომა pending_update_count-ის ნულთან ერთად ისტორიაა და არა პრობლემა.
ველების ერთად წაკითხვა#
არცერთი ველი დიაგნოზს ცალკე არ სვამს. კომბინაციები სვამს:
| რას ხედავ | რას ნიშნავს |
|---|---|
url ცარიელია | webhook რეგისტრირებული არ არის. ვიღაცამ გამოიძახა deleteWebhook, ან poller-მა გაასუფთავა |
url არასწორია ან ძველია | მოძველებული რეგისტრაცია: ძველი hostname, ძველი path, staging URL |
| მთვლელი იზრდება, ახალი შეცდომაა | Telegram ვერ აწვდის და თავიდან ცდილობს |
| მთვლელი იზრდება, ახალი შეცდომა არ არის | მიწოდება წარმატებულია, მაგრამ შენი handler ძალიან ნელია |
| მთვლელი ნულია, შეცდომა არ არის, პასუხები არ არის | განახლებები მოდის; შეცდომა შენს კოდშია ან allowed_updates-შია |
პირველი რიგი უფრო მეტ ადამიანს ამახინჯებს, ვიდრე უნდა. რამდენიმე ბიბლიოთეკა deleteWebhook-ს იძახებს, როცა polling რეჟიმში უშვებ, ამიტომ ბოტის ლოკალურად ერთხელ გაშვება production token-ით "რაღაცის გასატესტად" ჩუმად შლის production webhook-ს. webhook უკან არ ბრუნდება, სანამ რამე ისევ არ გამოიძახებს setWebhook-ს. თუ შენი deploy webhook-ს მხოლოდ მაშინ არეგისტრირებს, როცა URL იცვლება, შესაძლოა ის თავისით არასდროს დაბრუნდეს.
ბოლო რიგი ის შემთხვევაა, სადაც getWebhookInfo ვერ დაგეხმარება, რადგან Telegram-ის მხრიდან ყველაფერი რიგზეა: მან განახლება გამოგზავნა, შენმა სერვერმა 200 უპასუხა, დასრულდა. ჯერ შეამოწმე allowed_updates - თუ იქ მხოლოდ message წერია, ღილაკების დაჭერები (callback_query) არასდროს მოვა, ხოლო chat_member განახლებები მხოლოდ მაშინ იგზავნება, როცა მათ აშკარად ითხოვ. შემდეგ შეამოწმე ლოგები; 200-ის გაგზავნის შემდეგ გადაყლაპული exception ზუსტად სიჩუმესავით გამოიყურება.
ip_address-ს ყოველ ჯერზე გადახედე. ეს არის მისამართი, რომელიც Telegram-მა შენი hostname-იდან ამოხსნა, და თუ ის არ არის ის სერვერი, რომელიც გგონია, DNS პრობლემა გაქვს: A record, რომელიც ისევ ძველ ჰოსტზე მიუთითებს, ან record, რომელსაც გავრცელება ჯერ არ დაუმთავრებია. Telegram-ის webhook მიწოდება მხოლოდ IPv4-ია - webhook-ის სახელმძღვანელო პირდაპირ ამბობს, რომ IPv6 მხარდაჭერილი არ არის - ამიტომ hostname-ს, რომელსაც მხოლოდ AAAA record აქვს, webhook-ების მიღება საერთოდ არ შეუძლია. DNS records, ახსნილი განმარტავს, როგორ შეამოწმო, რომელი record-ები აქვს სახელს რეალურად.
SSL შეცდომები#
ნებისმიერი last_error_message, რომელიც SSL error-ით იწყება, ნიშნავს, რომ Telegram-მა შენს მისამართს მიაღწია და TLS handshake უარყო. ტექსტი ჩვეულებრივ შეიცავს OpenSSL-ის შეცდომის სტრიქონს, მაგალითად certificate verify failed, და ზუსტი ფორმულირება იცვლებოდა Telegram-ის OpenSSL ვერსიის ცვლილებასთან ერთად, ამიტომ კოდს კი არა, აზრს მიჰყევი.
Telegram-ის გამოქვეყნებული მოთხოვნები მოკლეა და მკაცრი:
- TLS 1.2 ან უფრო ახალი. SSLv2, SSLv3, TLS 1.0 და 1.1 უარყოფილია.
- სერტიფიკატის CN ან SAN უნდა ემთხვეოდეს hostname-ს webhook URL-ში.
- სერვერმა უნდა გამოაგზავნოს სრული ჯაჭვი - შენი სერტიფიკატი პლუს ყველა intermediate.
- self-signed სერტიფიკატი მუშაობს მხოლოდ მაშინ, თუ მას
setWebhook-ისcertificateპარამეტრით ატვირთავ, რის შემდეგაცhas_custom_certificateაჩვენებსtrue-ს. - TLS საჭიროა ყველა დაშვებულ port-ზე, 80-ის ჩათვლით. port 80 დაშვებულია, უბრალო HTTP - არა.
გამოტოვებული intermediate კლასიკური შემთხვევაა. ბრაუზერები ხშირად ამას ფარავენ, რადგან intermediate-ებს კეშავენ ან თავად იზიდავენ, ამიტომ საიტი Chrome-ში კარგად გამოიყურება, მაშინ როცა Telegram, რომელიც არცერთს აკეთებს, მას უარყოფს. შეამოწმე ისე, როგორც მკაცრი კლიენტი შეამოწმებდა:
$ openssl s_client -connect bot.example.com:443 -servername bot.example.com </dev/null \ | grep -E "Verify return code|subject=|issuer="Verify return code: 0 (ok) არის ის, რაც გინდა. კოდი 21 (unable to verify the first certificate) არის გამოტოვებული ჯაჭვი: nginx-ში ეს ნიშნავს, რომ ssl_certificate სრული ჯაჭვის ფაილის ნაცვლად leaf სერტიფიკატზე მიუთითებს. Certbot ორივეს წერს და გამოსაყენებელია fullchain.pem. ვადაგასული სერტიფიკატი კოდ 10-ს იძლევა, ხოლო hostname-ის შეუსაბამობა subject= ხაზში ჩანს. SSL certificate errors, ახსნილი თითოეულს დეტალურად განიხილავს.
ერთი ნაკლებად აშკარა მიზეზი: თვეების წინ ატვირთული self-signed სერტიფიკატი, რომელიც მერე რეალურით ჩაანაცვლეს ხელახალი რეგისტრაციის გარეშე. Telegram ისევ ძველს იმახსოვრებს. გამოიძახე setWebhook ისევ certificate პარამეტრის გარეშე და has_custom_certificate ისევ false გახდება.
Wrong response from the webhook#
Wrong response from the webhook: <status> ნიშნავს, რომ TLS handshake წარმატებით დასრულდა და შენმა სერვერმა უპასუხა, ოღონდ არა 2xx-ით. Telegram 2xx-ის გარეთ ყველაფერს წარუმატებლობად თვლის და თავიდან ცდილობს. შეტყობინებაში მითითებული სტატუსი მინიშნებაა:
| სტატუსი | ჩვეულებრივი მიზეზი |
|---|---|
404 Not Found | რეგისტრირებულ URL-სა და შენს route-ს შორის path-ის შეუსაბამობა |
401 / 403 | შენი secret-token შემოწმება უარყოფს Telegram-ს (იხილე ქვემოთ) |
405 Method Not Allowed | route GET-ისთვისაა რეგისტრირებული; Telegram მხოლოდ POST-ს აგზავნის |
301 / 302 / 308 | გადამისამართება, რომელსაც Telegram წარუმატებლობად თვლის |
500 Internal Server Error | შენმა handler-მა შეცდომა გამოიწვია პასუხამდე |
502 / 503 / 504 | proxy მუშაობს, მის უკან აპი - არა |
404 თითქმის ყოველთვის არის ბოლოში slash, პრეფიქსი, ან token-ის მქონე path, რომელიც აღარ ემთხვევა, რადგან token გაუქმდა. შეადარე getWebhookInfo-დან მიღებული url სიმბოლო-სიმბოლო შენს კოდში არსებულ route-ს. ბიბლიოთეკები, რომლებიც route-ს url_path პარამეტრიდან აგებენ, ხოლო URL-ს - ცალკე webhook_url პარამეტრიდან, ადვილს ხდიან ერთის შეცვლას მეორის შეუცვლელად.
გადამისამართებები მოდის შენი აპის წინ მდგარი ფენიდან: გადამისამართება შიშველი დომენიდან www-ზე ან პირიქით, proxy, რომელიც ერთ path პრეფიქსს სხვაგან აგზავნის, ან framework, რომელიც ბოლოში slash-ს ამატებს. დაარეგისტრირე ზუსტი საბოლოო URL, ის, რომელიც გადამისამართების გარეშე პასუხობს.
5xx ჯგუფი სუფთად იყოფა. 500 შენი კოდიდან მოვიდა, ამიტომ stack trace შენს აპლიკაციის ლოგშია. 502 მოვიდა reverse proxy-დან, რაც ნიშნავს, რომ აპი გათიშულია, გაშვებისას ჩაიშალა, ან იქ უსმენს, სადაც proxy არ იყურება. ყველაზე ხშირი ფორმაა კონტეინერის შიგნით 127.0.0.1-ზე მიბმული აპი, მაშინ როცა proxy გარედან უკავშირდება, ან აპი, რომელიც hard-coded port-ზე უსმენს და ის არ არის port, რომელიც plan-მა გამოყო. რას აკეთებს reverse proxy რეალურად განმარტავს, რატომ შეიძლება proxy-ს და აპს სხვადასხვა აზრი ჰქონდეთ იმაზე, სად ცხოვრობს აპი.
500-ების კიდევ ერთი წყარო, რომელიც Telegram-ის პრობლემას ჰგავს: handler, რომელიც კონკრეტულ ერთ განახლებაზე ვარდება. Telegram თავიდან ცდილობს, handler ისევ ვარდება, და რადგან განახლება განაგრძობს წარუმატებლობას, რიგის დანარჩენი ნაწილი მის უკან იზრდება. ერთ დაზიანებულ შეტყობინებას შეუძლია ბოტი გააჩეროს, სანამ ეს განახლება არ მოიხსნება. შეფუთე განახლების დამუშავება ისე, რომ exception დაილოგოს და მოთხოვნას მაინც 200 მიეცეს.
Timeout-ები და კავშირის შეცდომები#
როცა შეტყობინება სტატუსზე კი არა, კავშირზე საუბრობს, Telegram-მა HTTP პასუხი საერთოდ ვერ მიიღო. ფორმულირება განსხვავდება, მაგრამ ოჯახები ესენია:
- Connection refused - მისამართი ამოიხსნა და ვიღაცამ უპასუხა, რომ ამ port-ზე არავინ უსმენს. proxy არ მუშაობს, ან URL-ში მითითებული port ღია არ არის.
- Connection timed out - პაკეტები არსად მივიდა. firewall ტრაფიკს აგდებს, IP არასწორია, ან სახლის router-ს port forward არ აქვს.
- Read timeout expired - კავშირი გაიხსნა და შენმა სერვერმა პასუხს ძალიან დიდხანს უყოყმანა. ეს ნელი handler-ია და არა ქსელის პრობლემა.
- Failed to resolve host - hostname-ს არ აქვს A record, რომლის გამოყენებაც Telegram-ს შეუძლია.
Telegram თავისი მიწოდების timeout-ს არ აქვეყნებს, ამიტომ რიცხვზე ნუ დააპროექტებ. დააპროექტე ისე, რომ პასუხს მილიწამები სჭირდებოდეს, რაც არ უნდა მოხდეს.
თუ შემომავალ ტრაფიკს წყაროს მისამართით ზღუდავ, Telegram-ის webhook სახელმძღვანელო ჩამოთვლის დიაპაზონებს, საიდანაც ის აწვდის: 149.154.160.0/20 და 91.108.4.0/22. იმავე გვერდზე წერია, რომ ისინი შეიძლება შეიცვალოს, ამიტომ მათგან აგებული allow-list არის ის, რასაც ხელახლა უნდა გადახედო, როცა მიწოდებები უცებ timeout-ზე გადადის. უმეტესობას secret token IP allow-list-ზე უკეთ ემსახურება. Firewall rules, რომლებიც მნიშვნელოვანია ამ კომპრომისს განიხილავს.
Port-ები და setWebhook-ის შეცდომები#
webhook-ები მიეწოდება ზუსტად ოთხ port-ზე: 443, 80, 88 და 8443. არა 3000, არა 5000, არა 8080. setWebhook ნებისმიერ სხვა port-ს რეგისტრაციისას bad webhook შეცდომით უარყოფს, ამიტომ თუ ამ შეცდომას ხედავ, მიწოდების წარუმატებლობამდე ჯერ ვერ მისულხარ. რეგისტრაციისას სხვა უარყოფები: URL, რომელიც HTTPS არ არის, და hostname, რომელიც არ ამოიხსნება.
URL-ში მითითებული port არის port, რომელსაც Telegram უკავშირდება და არა port, რომელზეც შენი აპი უსმენს. ჩვეულებრივი სქემაა reverse proxy, რომელიც TLS-ს 443-ზე ამთავრებს და აპის საკუთარ port-ზე გადააგზავნის:
თითოეული ისარი last_error_message-ის განსხვავებული ოჯახია, ამიტომ ეს ველი ძიებას ასე სწრაფად ავიწროებს. RE:NODE-ის app plan-ებზე ეს სქემა არის proxy slot: მიმართე A record ნაჩვენებ მისამართზე და სერტიფიკატი გაიცემა და ახლდება ავტომატურად 21-დღიან ფანჯარაში, TLS 443-ზე, ხოლო მოთხოვნა გადაიგზავნება port-ზე, რომელზეც შენი აპი უსმენს. აპი მაინც უნდა უსმენდეს 0.0.0.0-ზე და plan-ის port-ზე; ეს ნაწილი შენია. proxy-ის საკუთარ მანქანაზე გაშვება განხილულია nginx reverse proxy სახელმძღვანელოში.
setWebhook-ის ip_address პარამეტრი საშუალებას გაძლევს Telegram-ს ფიქსირებული IP მისცე, hostname-ის ამოხსნის ნაცვლად. TLS მაინც hostname-ის მიხედვით მოწმდება. ეს სასარგებლოა, როცა DNS გარდამავალ მდგომარეობაშია და ლოდინი არ შეგიძლია, და ხაფანგია, როცა დაგავიწყდება, რომ დაყენებული იყო და მერე ბოტს გადაიტან - ახალი A record მაშინ იგნორირდება. getWebhookInfo აჩვენებს იმ მისამართს, რომელიც გამოიყენება.
Backlog და drop_pending_updates#
სანამ მიწოდებები ჩავარდნილია, განახლებები რიგში დგას. Telegram მიუწოდებელ განახლებებს 24 საათამდე ინახავს, მიწოდებას თავიდან ცდილობს, და როგორც კი მიზეზს გამოასწორებ, backlog ერთბაშად მიეწოდება - max_connections-ით შეზღუდული, რომლის ნაგულისხმევი მნიშვნელობაა 40 ერთდროული მოთხოვნა. ამას ორი ეფექტი აქვს, რასაც ადამიანები არ ელოდებიან. ბოტი, რომელიც ღამის განმავლობაში გატეხილი იყო, გასწორებიდან წამებში პასუხობს ღამის განმავლობაში დაგროვილ შეტყობინებებს და პასუხობს საუბრებს, რომლებიც საათების წინ დასრულდა. და პატარა სერვერზე 40 ერთდროული მიწოდება საკმარისი დატვირთვაა timeout-ების მეორე ტალღის გამოსაწვევად.
როცა backlog უსარგებლოა, გადააგდე. setWebhook-იც და deleteWebhook-იც იღებს drop_pending_updates-ს:
$ curl -s "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" \ -d "url=https://bot.example.com/tg/hook" \ -d "secret_token=$WEBHOOK_SECRET" \ -d "max_connections=10" \ -d "drop_pending_updates=true"pending_update_count მყისვე ამის შემდეგ 0 უნდა აჩვენებდეს. გაითვალისწინე, რომ setWebhook მთელ კონფიგურაციას ანაცვლებს: ხელახალ რეგისტრაციაზე secret_token ან allowed_updates თუ გამოტოვე, ისინი აღარ იქნება. ყოველთვის გადაეცი სრული ნაკრები, რაც გინდა.
backlog-ს რეფლექსით ნუ გადააგდებ. ბოტისთვის, რომელიც შეკვეთებს, გადახდებს ან ფორმების გაგზავნას აფიქსირებს, ეს რიგში მდგარი განახლებები რეალური სამუშაოა და სწორი ნაბიჯია მიზეზის გასწორება, max_connections-ის შემცირება იმდენამდე, რასაც შენი სერვერი უმკლავდება, და მათი დაცლის დაცდა. დააკვირდი მთვლელის კლებას getWebhookInfo-ს განმეორებითი გამოძახებებით.
secret_token header#
secret_token არის სტრიქონი, რომელსაც თავად ირჩევ, 1-256 სიმბოლო A-Z, a-z, 0-9, _ და --დან, და setWebhook-ს გადასცემ. Telegram შემდეგ მას X-Telegram-Bot-Api-Secret-Token header-ში აგზავნის ყოველ მიწოდებაზე, ხოლო შენი handler ადარებს და უარყოფს ყველაფერს, რაც არ ემთხვევა. ეს იაფი და სწორი გზაა იმისთვის, რომ მხოლოდ Telegram-ს შეეძლოს შენს ბოტს განახლებები მიაწოდოს.
ის ასევე კონკრეტულ წარუმატებლობას იწვევს. შენი handler აბრუნებს 401-ს ან 403-ს, last_error_message აჩვენებს Wrong response from the webhook: 403 Forbidden-ს, და მიზეზი სამიდან ერთ-ერთია:
- secret შენს გარემოში შეიცვალა, მაგრამ
setWebhookახალი მნიშვნელობით არ გამოძახებულა. - ხელახალმა რეგისტრაციამ
secret_tokenგამოტოვა, ამიტომ Telegram ახლა header-ს საერთოდ არ აგზავნის. - შუაში მდგარი proxy უცნობ header-ებს აჭრის. იშვიათია, მაგრამ ღირს შემოწმება, თუ პირველი ორი გამორიცხულია.
სამივეს გამოსწორება ერთნაირია: დააყენე ცვლადი, გამოიძახე setWebhook იმავე მნიშვნელობით და შეამოწმე, რომ შენი გარემო და Telegram თანხმდებიან. secret getWebhookInfo-ში არ ჩანს, ამიტომ ერთადერთი დასტური წარმატებული მიწოდებაა. შეინახე ის token-ის გვერდით და არა repository-ში - მიზეზები environment variables და secrets პოსტშია.
უპასუხე სწრაფად, მერე დაამუშავე#
თუ pending_update_count შეცდომის გარეშე იზრდება, ან read timeout-ებს ხედავ, შენი handler თავის საქმეს პასუხამდე აკეთებს. ყოველი მიწოდება max_connections slot-ებიდან ერთს იკავებს, სანამ არ უპასუხებ. handler-ს, რომელიც გარე API-ს იძახებს, მონაცემთა ბაზაში წერს და ორ შეტყობინებას აგზავნის 200-ის დაბრუნებამდე, შეიძლება ორი წამი დასჭირდეს; შეტყობინებების ნაკადის დროს slot-ები ივსება, მიწოდებები რიგში დგას, და საბოლოოდ ზოგი timeout-ზე გადადის და თავიდან ეგზავნება - რაც დატვირთვას ზრდის.
გამოსწორება სტრუქტურულია: შეამოწმე secret, გადაეცი განახლება სხვას, უპასუხე 200 და სამუშაო მერე შეასრულე.
import asyncio, osfrom fastapi import FastAPI, Request, Responseapp = FastAPI()SECRET = os.environ["WEBHOOK_SECRET"]queue: asyncio.Queue = asyncio.Queue()@app.post("/tg/hook")async def hook(request: Request): if request.headers.get("X-Telegram-Bot-Api-Secret-Token") != SECRET: return Response(status_code=403) await queue.put(await request.json()) return Response(status_code=200)async def worker(): while True: update = await queue.get() try: await handle(update) # your bot logic except Exception as exc: print("update failed:", exc, flush=True)@app.on_event("startup")async def start_worker(): asyncio.create_task(worker())მეხსიერებაში მყოფი რიგი პროცესის გადატვირთვისას იმას კარგავს, რაც მასშია. ეს ჩატ-ბოტისთვის მისაღებია და არა იმისთვის, რაც გადახდებს იღებს. როცა სამუშაომ restart უნდა გადაიტანოს, ჩადე რეალურ რიგში; background jobs პატარა სერვერზე განიხილავს ვარიანტებს, რომლებიც ერთ plan-ს ეტევა. ზოგი ბიბლიოთეკა, მათ შორის grammY-ს webhookCallback, handler-ზე საკუთარ timeout-ს ადებს და როცა ის ამოიწურება, შენს მაგივრად პასუხობს - Telegram-ის timeout-ზე უკეთესია, მაგრამ ნიშანია, რომ handler ძალიან ნელია და არა გამოსავალი.
ასევე შეამცირე max_connections იმდენამდე, რამდენის პარალელურად გაშვებასაც სერვერი რეალურად შეძლებს. 0.5 ან 1 vCPU plan-ზე 40 ერთდროული მიწოდება ტევადობა კი არა, ჭიდილია. 5-დან 20-მდე ჩვეულებრივ პატიოსანი მნიშვნელობაა პატარა ბოტისთვის.
Polling-ზე დაბრუნება#
ზოგჯერ სწორი გამოსწორება webhook-ის გამოყენების შეწყვეტაა. თუ ბოტს რამდენიმე ასეული მომხმარებელი ჰყავს, დომენი არ გაქვს, ან დებაგავ და გინდა ტერმინალში განახლებების მოსვლა ნახო, polling უფრო მარტივია და არაფერს კარგავს, რაც მნიშვნელოვანია.
$ curl -s "https://api.telegram.org/bot$BOT_TOKEN/deleteWebhook" \ -d "drop_pending_updates=false"drop_pending_updates=false-ით (ნაგულისხმევია) რიგში მდგარი განახლებები რჩება და getUpdates მათ შემდეგ poll-ზე აწვდის. ამის შემდეგ getWebhookInfo ცარიელ url-ს აბრუნებს და polling მუშაობს. სანამ მას არ წაშლი, ყოველი getUpdates გამოძახება 409 conflict-ით ვარდება, რითაც ადამიანები აღმოაჩენენ, რომ დავიწყებული webhook ისევ რეგისტრირებულია. გაიხსენე საპირისპიროც: მოგვიანებით webhook-ზე დაბრუნებას ახალი setWebhook სჭირდება პარამეტრების სრული ნაკრებით, და deploy-მ მის შემდეგ getWebhookInfo უნდა შეამოწმოს და არა ივარაუდოს.
ჩეკლისტი თანმიმდევრობით#
როცა გვიანია და ბოტი ჩუმადაა, გაიარე ეს თანმიმდევრობით:
- გაუშვი
getWebhookInfo.urlდაყენებულია და არის თუ არა ზუსტად ის URL, რასაც შენი კოდი ემსახურება? ip_addressშენი სერვერია? თუ არა, გაასწორე DNS, ან გაასუფთავე ფიქსირებულიip_address.- წაიკითხე
last_error_date. შეცდომა ახალია? თუ არა, პრობლემა შენს კოდშია ანallowed_updates-შია. SSL error: შეამოწმე ჯაჭვი და hostnameopenssl s_client-ით.Wrong response: სტატუსი გეუბნება, path-ის, secret-ის, გადამისამართების თუ ჩამოვარდნილი აპის საქმეა.- კავშირის შეცდომები: შეამოწმე, რომ port ოთხიდან ერთ-ერთია, proxy მუშაობს და არაფერია firewall-ით დაბლოკილი.
- მთვლელი იზრდება შეცდომის გარეშე: ჯერ უპასუხე, მერე დაამუშავე, შეამცირე
max_connections. - გასწორდა და backlog მოძველებულია: ხელახლა დაარეგისტრირე
drop_pending_updates=true-ით.
აპლიკაციის ლოგი ღია გქონდეს, სანამ მუშაობ. როგორ წაიკითხო სერვერის console ვარაუდის გარეშე გეხმარება, გამოარჩიო მნიშვნელოვანი შეცდომები მათ გარშემო არსებული ხმაურისგან.
FAQ#
რატომ იზრდება pending_update_count, როცა შეცდომა არ არის?
Telegram წარმატებით აწვდის, მაგრამ შენი სერვერი ძალიან ნელა პასუხობს და ვერ ეწევა, ამიტომ მიწოდებები თავისუფალ კავშირის slot-ს ელოდება. დააბრუნე 200, როგორც კი მოთხოვნა დადასტურდება, სამუშაო background task-ში შეასრულე და max_connections დააყენე იმდენზე, რამდენის პარალელურად დამუშავებასაც შენი სერვერი ნამდვილად შეძლებს.
რამდენ ხანს ინახავს Telegram განახლებებს, რომლებიც ჩემმა webhook-მა ვერ მიიღო?
24 საათამდე. რაც უფრო ძველია, იგლიჯება, მიუხედავად იმისა, დროზე გაასწორე თუ არა webhook, ამიტომ ბოტი, რომელიც ორი დღე გათიშული იყო, პირველი დღის შეტყობინებებს ყოველ შემთხვევაში კარგავს.
შემიძლია webhook-ის გამოყენება port 3000-ზე ან 8080-ზე?
პირდაპირ - არა. Telegram მხოლოდ 443-ზე, 80-ზე, 88-ზე და 8443-ზე აწვდის, ხოლო setWebhook სხვა port-ებს უარყოფს. გაუშვი აპი ნებისმიერ port-ზე, რაც გინდა, და მის წინ 443-ზე reverse proxy დააყენე.
მიჰყვება თუ არა Telegram გადამისამართებებს ჩემს webhook-მდე?
ჩათვალე, რომ არა. 3xx პასუხი ფიქსირდება როგორც არასწორი პასუხი და მიწოდება თავიდან ხდება. დაარეგისტრირე ზუსტი საბოლოო URL, scheme-ის, host-ის და ბოლოში იმ slash-ის ჩათვლით, რომელსაც შენი framework ელის.
დამეკარგება შეტყობინებები deleteWebhook-ით?
არა, თუ drop_pending_updates=true-ს არ გადასცემ. მის გარეშე რიგში მდგარი განახლებები Telegram-ის მხარეს რჩება და პირველ getUpdates გამოძახებას გადაეცემა, 24-საათიანი ზღვრის ფარგლებში.
მჭირდება IP allow-list, თუ secret_token-ს ვიყენებ?
არა. secret token უკვე ადასტურებს, რომ მოთხოვნა Telegram-იდან მოვიდა, და არ ტყდება, როცა Telegram მისამართების დიაპაზონებს ცვლის. allow-list დამატებითი ფენაა და არა ჩანაცვლება, და სწორედ ის უფრო ხშირად იწვევს მომსახურების გაჩერებას.

