Nowy przewodnik skoncentrowany na Laravel pokazuje programistom, jak zapobiec przekroczeniom czasu oczekiwania (timeout), duplikowaniu akcji lub awariom botów Telegram pod obciążeniem poprzez zabezpieczenie webhooka, wykorzystanie Redis do zapewnienia idempotencji oraz przeniesienie ciężkich zadań do kolejek.

Dlaczego webhooki Telegrama wymagają czegoś więcej niż zwykłej trasy

Telegram przesyła każdą interakcję użytkownika z botem jako żądanie HTTP POST na URL określony przez programistę. Platforma oczekuje odpowiedzi 200 OK w ciągu kilku sekund; jeśli zajmie to więcej czasu, ponowi żądanie. Ponowienia oznaczają, że ten sam update_id może dotrzeć wielokrotnie, a jeśli bot zapisuje dane w bazie danych lub wywołuje zewnętrzne API wewnątrz żądania, może to prowadzić do tworzenia duplikatów wierszy, podwójnych wiadomości lub wystąpienia wyścigów (race conditions). W przypadku botów obsługujących dziesiątki lub setki wiadomości na sekundę, takie opóźnienie szybko staje się problemem.

1. Zabezpiecz punkt końcowy za pomocą tajnego nagłówka

Telegram dodaje nagłówek X-Telegram-Bot-Api-Secret-Token do każdego wywołania webhooka. Porównaj ten nagłówek z tajnym kluczem przechowywanym na serwerze — używając funkcji hash_equals w PHP, aby uniknąć ataków czasowych (timing attacks) — i odrzucaj każde żądanie, które nie pochodzi z Telegrama. W Laravelu umieść to sprawdzenie w middleware, aby weryfikacja odbyła się przed przetworzeniem danych przez kontroler.

2. Zapewnij idempotencję każdej aktualizacji za pomocą Redis

Każdy przychodzący ładunek (payload) zawiera unikalny update_id. Przewodnik sugeruje zapisanie tego ID w Redis z flagą NX (set-if-not-exists). Operacja zakończy się sukcesem tylko przy pierwszym wystąpieniu; ponowienie żądania wykryje, że klucz już istnieje, dzięki czemu webhook może natychmiast zwrócić 200 OK, sygnalizując Telegramowi, że aktualizacja została obsłużona. Ponieważ Redis działa w pamięci RAM, sprawdzenie nie dodaje praktycznie żadnych opóźnień, a klucz pozostaje w pamięci, aby wykrywać duplikaty.

3. Przekaż ciężkie zadania do procesów w tle

Nawet przy szybkim sprawdzeniu w Redis, logika biznesowa bota — zapisy do bazy danych, wywołania zewnętrznych API, komponowanie wiadomości — nigdy nie powinna być wykonywana wewnątrz żądania webhooka. Wyślij zadanie do kolejki Laravel (queued job) natychmiast po zweryfikowaniu webhooka i zapisaniu update_id. Wyślij odpowiedź HTTP błyskawicznie, pozwalając workerowi przetwarzać zadanie we własnym tempie. Dzięki temu bot zmieści się w limicie czasu odpowiedzi Telegrama i zapobiegnie ponawianiu żądań przez platformę.

Rozwiązania gotowe do produkcji

  • Respektuj limity zapytań (rate limits). Telegram zwraca błąd 429 Too Many Requests wraz z nagłówkiem Retry-After, gdy bot przekroczy limity zapytań na sekundę. Workerzy kolejki powinni odczytywać ten nagłówek i wstrzymać pracę przed ponowieniem nieudanego zadania.
  • Najpierw zapisz, potem odpowiedz. Najpierw zapisz wszelkie dane użytkownika w bazie danych; dopiero po skutecznym zatwierdzeniu (commit) bot powinien wysłać wiadomość potwierdzającą. Taka kolejność zapobiega sytuacjom, w których użytkownik otrzymuje wiadomość, ale odpowiadający jej rekord nigdy nie pojawia się w bazie.
  • Ograniczaj rozmiar payloadów callbacków. Telegram ogranicza callback_data do 64 bajtów. Przechowuj większe dane (blobs) w bazie danych, a w payloadzie przycisku przesyłaj jedynie identyfikator referencyjny, aby zmieścić się w limicie.

Podsumowując: uwierzytelnianie żądań, deduplikacja za pomocą Redis i odciążenie procesów poprzez kolejki pozwalają programistom Laravel budować boty Telegram, które odpowiadają natychmiast, mieszczą się w limitach zapytań i łatwo skalują się wraz ze wzrostem liczby użytkowników.