Усі статті
Пакети оновлень чату в стилі Telegram переміщуються через безпечний тунель HTTPS до обробника бота, який працює на ноутбуці розробника.
Telegram Bot APIwebhookslocalhostbot development

Як протестувати вебхук Telegram-бота на localhost

Щоб перевірити вебхук бота Telegram на локальному хості, відкрийте свій локальний сервер за допомогою загальнодоступного тунелю HTTPS, зателефонуйте setWebhook за цією URL-адресою та перевіряйте заголовок секретного токена Telegram під час кожного запиту. Це дає вам реальне повідомлення, callback-query та оновлення членства без розгортання після кожної зміни коду. Повний цикл такий: запустіть обробник бота, запустіть npx portpreview 3000, зареєструйте отриману URL-адресу, надішліть боту повідомлення та перевірте запит локально.

Чому Telegram не може надсилати оновлення безпосередньо на локальний хост

API бота Telegram надсилає оновлення вебхука з інфраструктури Telegram на URL-адресу, доступну в Інтернеті. localhost, 127.0.0.1 та приватні адреси локальної мережі не можна маршрутизувати з цієї інфраструктури. localhost tunnel завершує HTTPS на публічній адресі та пересилає незмінений HTTP-запит на ваш локальний порт.

Боти Telegram можуть отримувати оновлення двома взаємовиключними способами: довгим опитуванням за допомогою getUpdates або веб-хуками. офіційне посилання setWebhook стверджує, що getUpdates недоступний, поки налаштовано вихідний вебхук. Якщо процес опитування все ще триває, зупиніть його, перш ніж оцінювати потік вебхуку.

Створення локальної кінцевої точки вебхука

У цьому прикладі Express обробник навмисно зберігається малим. Він перевіряє спільний секрет ще до того, як торкнеться оновлення, швидко підтверджує отримання та виносить обробку за межі шляху відповіді.

import express from 'express';
import crypto from 'node:crypto';

const app = express();
app.use(express.json({ limit: '1mb' }));

function sameSecret(received = '', expected = '') {
  const a = Buffer.from(received);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post('/webhooks/telegram', (req, res) => {
  const received = req.get('x-telegram-bot-api-secret-token') || '';
  if (!sameSecret(received, process.env.TELEGRAM_WEBHOOK_SECRET)) {
    return res.sendStatus(401);
  }

  const update = req.body;
  res.sendStatus(200);
  queueMicrotask(() => handleUpdate(update));
});

app.listen(3000, () => console.log('Listening on http://localhost:3000'));

Telegram надсилає серіалізований JSON Update. На відміну від постачальників на основі HMAC, функція Telegram secret_token не підписує тіло. Він поміщає вибране значення в X-Telegram-Bot-Api-Secret-Token. Маркер доводить, що відправник знає значення, використане під час реєстрації веб-хуку, але він не надає дайджест корисного навантаження. TLS захищає запит під час передавання.

Відкрийте кінцеву точку через HTTPS

  1. Запустіть застосунок і переконайтеся, що curl -i http://localhost:3000/webhooks/telegram доходить до сервера, навіть якщо GET повертає 404.
  2. Відкрийте другий термінал і запустіть npx portpreview 3000.
  3. Скопіюйте публічний HTTPS-домен і додайте до нього /webhooks/telegram.
  4. Продовжуйте працювати тунельний процес, поки Telegram надсилає оновлення.

API бота приймає URL-адреси веб-хуку HTTPS. У документації Telegram зазначено підтримку вебхуків на портах 443, 80, 88 і 8443; загальнодоступна кінцева точка керованого тунелю зазвичай використовує 443, навіть якщо локальний процес, що пересилається, прослуховує 3000.

Безпечно зареєструйте вебхук Telegram

Створіть випадковий секрет, який містить лише літери, цифри, підкреслення або дефіси. Telegram допускає 1–256 символів. Не використовуйте повторно маркер бота як це значення.

export TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)"

curl -sS -X POST \
  "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/setWebhook" \
  -d "url=https://YOUR-TUNNEL.portpreview.dev/webhooks/telegram" \
  -d "secret_token=${TELEGRAM_WEBHOOK_SECRET}" \
  -d 'allowed_updates=["message","callback_query"]' \
  -d "drop_pending_updates=true"

allowed_updates зменшує шум, тому перелічуйте там лише ті типи оновлень, які бот справді обробляє. drop_pending_updates=true корисний під час запуску нового локального сеансу, але він назавжди відкидає оновлення в черзі, тому пропустіть його, коли ці події важливі. Документація оновлення Telegram описує такі поля, як message, callback_query та my_chat_member.

Перевірте реєстрацію, перш ніж шукати помилки в коді

Використайте getWebhookInfo, щоб відрізнити помилки конфігурації від помилок обробника:

curl -sS "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getWebhookInfo"

Перевірте url, pending_update_count, last_error_message та last_error_date. Порожня URL-адреса означає, що реєстрація не збереглася. Зростання кількості очікувань зазвичай означає, що Telegram не може підключитися або ваша кінцева точка повертає статус не 2xx. Надіслати пряме повідомлення боту після реєстрації; просте відкриття чату не обов’язково створює оновлення.

Обробляти оновлення без повторних спроб

Підтвердити перед повільною роботою

Повернути відповідь 2xx, щойно запит буде автентифіковано та прийнято надовго. Експорт бази даних, виклики штучного інтелекту та API сторонніх розробників мають виконуватися асинхронно. Telegram повторює невдалі запити після відповідей, відмінних від 2xx, тому повільна синхронна робота може створити дублікати.

Дедуплікат з update_id

Кожне оновлення має update_id. Зберігайте оброблені ідентифікатори з терміном дії або примусово використовуйте унікальний ключ бази даних. Повторна спроба не повинна надсилати другу квитанцію про оплату, створювати повторюваний квиток або виконувати той самий зворотний виклик двічі.

Явно моделювати кожен тип оновлення

Не кожне оновлення містить message.text. Натискання кнопок надходять у полі callback_query; повідомлення на каналі та зміни членства мають інші поля. Розгалужтеся на поточному полі верхнього рівня та розглядайте невідомі типи як дійсні no-ops, а не як викидання.

Правила безпеки для тестування локального бота Telegram

  • Спочатку перевірте секретний заголовок. Відхиліть відсутні або неправильні значення перед реєстрацією або аналізом конфіденційних полів.
  • Не використовуйте маркери для URL-адрес і журналів. Маркер API бота в команді реєстрації є обліковими даними. Уникайте історії оболонок у спільних системах і повертайте відкритий маркер через BotFather.
  • Використовуйте маршрут, який неможливо вгадати, і секрет. Маршрут є глибоким захистом; секретний заголовок — це фактична перевірка програми.
  • Обмежити отримані дані. Повідомлення можуть містити імена, імена користувачів, номери телефонів, файли та текст приватної розмови. Відредагуйте журнали та видаліть локальні захоплення, коли закінчите.
  • Ніколи не вимикайте автентифікацію під час розробки. Загальнодоступний тунель є публічним. Місцевий код має здійснювати ті самі перевірки, що й виробництво.

Див. ширший посібник із безпеки локального тунелю, щоб дізнатися про методи керування доступом і збереження даних.

Усунення типових збоїв вебхука Telegram

Telegram повідомляє про помилку сертифіката або з’єднання

Використовуйте URL-адресу HTTPS тунелю, а не його локальну ціль HTTP. Переконайтеся, що тунель активний, а URL-адреса не змінилася. Якщо ви натомість використовуєте власний самопідписаний сертифікат, Telegram вимагатиме завантажити публічний сертифікат окремим файлом; керована TLS-точка позбавляє вас цього налаштування.

Кінцева точка повертає 401

Звірте секрет, переданий у setWebhook, зі змінною середовища, яку використовує процес. Імена заголовків нечутливі до регістру, але проксі-сервери або проміжне програмне забезпечення можуть видаляти спеціальні заголовки. Перевірте вхідні заголовки, не виводячи саме значення секрету в лог.

Запити не надходять

Запустіть getWebhookInfo, переконайтеся, що зареєстрований шлях точно відповідає вашому маршруту, і переконайтеся, що брандмауер не блокує локальне підключення тунелю. Якщо ви нещодавно користувалися опитуванням, переконайтеся, що URL-адресу вебхука тепер заповнено. Спровокуйте справжнє оновлення, написавши боту повідомлення.

Оновлення надходять повторно

Логуйте статус відповіді та час обробки. Винятки після отримання запиту можуть перетворити заплановані 200 на 500. Негайно поверніть 200, зробіть обробку ідемпотентною та використовуйте контрольоване відтворення вебхуку, а не чекайте повторних спроб постачальника під час налагодження.

Тестуйте callback-запити та файли, а не лише текст

Корисна матриця тестування бота охоплює більше, ніж message.text. Надішліть фото з підписом, поділіться контактом, відредагуйте повідомлення та натисніть кнопку inline-клавіатури. Для callback-запитів одразу викликайте answerCallbackQuery, щоб клієнт прибрав індикатор очікування, а повільнішу роботу виконуйте окремо. Оновлення файлів містять ідентифікатори; завантаження байтів є другою операцією API бота і не має затримувати відповідь вебхуку.

Зберігайте кріплення, створені з дезінфікованих оновлень для модульних тестів, але зберігайте повний транспортний шлях принаймні для одного тесту кожного підтримуваного типу. Пристосування доводить, що ваш диспетчер розуміє корисне навантаження; справжня тунельована доставка також підтверджує реєстрацію, TLS, заголовки, розбір тіла та поведінку підтвердження. Додаючи новий запис allowed_updates, зателефонуйте setWebhook ще раз і переконайтеся, що getWebhookInfo відображає заплановану конфігурацію.

Видалити вебхук після локального сеансу

curl -sS -X POST \
  "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/deleteWebhook" \
  -d "drop_pending_updates=false"

Видалення вебхуку дозволяє повернутися до getUpdates. Якщо URL-адреса тунелю зміниться під час наступного сеансу, знову зателефонуйте setWebhook. Для додаткової діагностики дотримуйтеся загального процесу налагодження локального вебхука.

Поширені запитання

Чи може Telegram надсилати вебхук бота безпосередньо на локальний хост?
No. Telegram не може направляти запити на localhost або приватну адресу локальної мережі. Використовуйте публічний тунель HTTPS, який пересилає запити на ваш локальний бот-сервер.
Як автентифікувати запити на вебхук-бот Telegram?
Передайте випадковий secret_token для setWebhook і порівняйте заголовок X-Telegram-Bot-Api-Secret-Token кожного запиту з цим значенням, використовуючи безпечне порівняння за часом.
Чому мій вебхук Telegram отримує повторювані оновлення?
Telegram повторює невдалу доставку. Швидко поверніть 2xx і видаліть дублікати роботи за допомогою update_id, щоб повторні спроби не повторювали побічних ефектів.
Чи можу я використовувати getUpdates, коли вебхук Telegram активний?
No. Telegram's Bot API не дозволяє getUpdates, поки налаштовано вихідний вебхук. Видаліть вебхук, перш ніж повернутися до тривалого опитування.