Оновлення

Long polling

Long polling — основной способ забирать обновления без публичного HTTPS. Вы сами держите соединение открытым и тянете пачки Update методом getUpdates.

Как работает

Клиент вызывает getUpdates с параметром timeout (до 30). Если есть новые Update — сервер отвечает сразу. Если нет — соединение висит до timeout секунд и возвращает пустой массив. Это снимает нагрузку: вместо тысяч коротких запросов — один длинный.

$updates = telegramApi($token, 'getUpdates', [
    'timeout' => 25,
    'offset'  => $nextOffset,
    'allowed_updates' => ['message', 'callback_query'],
]);

foreach ($updates as $u) {
    processUpdate($u);
    $nextOffset = max($nextOffset, $u['update_id'] + 1);
}

Один процесс — один getUpdates

Bot API отдаёт Update только одному вызывающему. Если запустить два скрипта с getUpdates параллельно, они будут делить события и терять часть из них. Поэтому long polling подходит для одного воркера. Для горизонтального масштабирования переходите на webhook + очередь.

Обработка ошибок сети

Соединение может оборваться по таймауту PHP, разрыву TCP или HTTP 5xx. Нужен цикл с ретраями и экспоненциальной задержкой, иначе процесс «молотит» в бесконечном цикле и блокирует сервер.

$delay = 1;
while (true) {
    try {
        $updates = telegramApi($token, 'getUpdates', [
            'timeout' => 25,
            'offset'  => $nextOffset,
        ]);
        $delay = 1; // успех — сбрасываем задержку
        foreach ($updates as $u) {
            processUpdate($u);
            $nextOffset = max($nextOffset, $u['update_id'] + 1);
        }
    } catch (Throwable $e) {
        error_log('getUpdates failed: ' . $e->getMessage());
        sleep(min($delay, 30));
        $delay *= 2;
    }
}

Где запускать воркер

  • supervisord / systemd — стандарт для PHP-демона. Перезапуск при падении, логи в journald.
  • php -S или cron — не подходят: первый блокирует, второй даёт задержку до минуты.
  • screen / tmux — только для локальной разработки, в production потеряете процесс при перезагрузке.

Long polling vs Webhook

  • Long polling: не нужен HTTPS, простой запуск, легко дебажить. Минусы — один воркер, держит PHP-процесс, задержка до ~1 сек.
  • Webhook: масштабируется, работает за nginx/php-fpm, нет постоянного соединения. Требует валидный SSL.

Long polling хорош для разработки, MVP, тестов и ботов с небольшой нагрузкой (десятки сообщений в минуту). Как только появляется второй воркер или SLA выше 99% — переезжайте на webhook. Пошаговый переход — на странице «С polling на webhook».

Частые ошибки

  • Потерянный offset. Сохраняйте его в файл или БД, а не только в памяти: при рестарте процесса придётся обработать ту же пачку.
  • Зависший процесс. Без try/catch исключение в processUpdate убивает цикл — ставьте обработку ошибок вокруг каждого Update.
  • Игнорирование allowed_updates. По умолчанию Telegram шлёт все типы, что увеличивает payload. Фильтруйте: ['message', 'callback_query', 'inline_query'].

Дальше: Webhook — production-вариант с HTTPS endpoint и очередью.