Щоб перевірити вебхук бота 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
- Запустіть застосунок і переконайтеся, що
curl -i http://localhost:3000/webhooks/telegramдоходить до сервера, навіть якщо GET повертає 404. - Відкрийте другий термінал і запустіть
npx portpreview 3000. - Скопіюйте публічний HTTPS-домен і додайте до нього
/webhooks/telegram. - Продовжуйте працювати тунельний процес, поки 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. Для додаткової діагностики дотримуйтеся загального процесу налагодження локального вебхука.
