Tous les articles
Paquets de mise à jour de chat de type télégramme transitant via un tunnel HTTPS sécurisé vers un gestionnaire de robot exécuté sur un ordinateur portable de développeur.
Telegram Bot APIwebhookslocalhostbot development

Tester un webhook de bot Telegram sur localhost

Pour tester un webhook de robot Telegram sur localhost, exposez votre serveur local avec un tunnel HTTPS public, appelez setWebhook avec cette URL et validez l'en-tête de jeton secret de Telegram à chaque demande. Cela vous donne de vrais messages, requêtes de rappel et mises à jour d'adhésion. sans déployer après chaque changement de code. La boucle complète est la suivante : exécutez le gestionnaire de bot, démarrez npx portpreview 3000, enregistrez l'URL résultante, envoyez un message à votre bot et inspectez la demande localement.

Pourquoi Telegram ne peut pas envoyer de mises à jour directement à localhost

L'API Bot de Telegram envoie les mises à jour des webhooks depuis l'infrastructure Telegram vers une URL accessible sur Internet. localhost, 127.0.0.1 et les adresses LAN privées ne sont pas routables à partir de cette infrastructure. Un localhost tunnel termine HTTPS à une adresse publique et transmet la requête HTTP inchangée à votre port local.

Les robots Telegram peuvent recevoir des mises à jour de deux manières mutuellement exclusives : une longue interrogation via getUpdates ou des webhooks. La référence officielle setWebhook indique que getUpdates n'est pas disponible lorsqu'un webhook sortant est configuré. Si un processus d'interrogation est toujours en cours, arrêtez-le avant de juger le flux du webhook.

Créer un point de terminaison de webhook local

Cet exemple Express maintient le gestionnaire intentionnellement petit. Il vérifie le secret partagé avant de toucher à la mise à jour, reconnaît rapidement et déplace le travail en dehors du chemin de réponse.

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 envoie un Update sérialisé en JSON. Contrairement aux fournisseurs basés sur HMAC, la fonctionnalité secret_token de Telegram ne signe pas le corps. Il place la valeur que vous avez choisie dans X-Telegram-Bot-Api-Secret-Token. Le jeton prouve que l'expéditeur connaît la valeur utilisée lors de l'enregistrement du webhook, mais il ne fournit pas de résumé de la charge utile. TLS protège la demande en transit.

Exposez le point de terminaison avec HTTPS

  1. Démarrez l'application et confirmez que curl -i http://localhost:3000/webhooks/telegram atteint le serveur, même si GET renvoie 404.
  2. Ouvrez un deuxième terminal et exécutez npx portpreview 3000.
  3. Copiez l'origine HTTPS publique et ajoutez /webhooks/telegram.
  4. Maintenez le processus de tunnel en cours pendant que Telegram fournit des mises à jour.

L'API Bot accepte les URL de webhook HTTPS. Telegram documente la prise en charge des webhooks sur les ports 443, 80, 88 et 8443 ; le point de terminaison public d'un tunnel géré utilise normalement 443 même lorsque le processus local transféré écoute sur 3000.

Enregistrez le webhook Telegram en toute sécurité

Créez un secret aléatoire contenant uniquement des lettres, des chiffres, des traits de soulignement ou des traits d'union. Le télégramme autorise 1 à 256 caractères. Ne réutilisez pas le jeton du bot avec cette valeur.

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 réduit le bruit et ne doit répertorier que les types de mises à jour gérés par le bot. drop_pending_updates=true est utile lors du démarrage d'une nouvelle session locale, mais il supprime définitivement les mises à jour en file d'attente, alors omettez-le lorsque ces événements sont importants. La Documentation de mise à jour de Telegram décrit des champs tels que message, callback_query et my_chat_member.

Confirmer l'enregistrement avant de déboguer le code

Utilisez getWebhookInfo pour séparer les échecs de configuration des échecs de gestionnaire :

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

Vérifiez url, pending_update_count, last_error_message et last_error_date. Une URL vide signifie que l'inscription n'a pas été respectée. Un nombre croissant d'attentes signifie généralement que Telegram ne peut pas se connecter ou que votre point de terminaison renvoie un statut non-2xx. Envoyez un message direct au bot après l'inscription ; le simple fait d'ouvrir le chat ne crée pas nécessairement une mise à jour.

Gérer les mises à jour sans provoquer de nouvelles tentatives

Acquitter avant un travail lent

Renvoyer une réponse 2xx dès que la demande est authentifiée et durablement acceptée. Les exportations de bases de données, les appels IA et les API tierces doivent s'exécuter de manière asynchrone. Telegram réessaye les demandes infructueuses après des réponses non-2xx, donc un travail synchrone lent peut créer des doublons.

Dédupliquer avec update_id

Chaque mise à jour a un update_id. Stockez les identifiants traités avec une fenêtre d’expiration ou appliquez une clé de base de données unique. Une nouvelle tentative ne doit pas envoyer un deuxième reçu de paiement, créer un ticket en double ou exécuter le même rappel deux fois.

Modélisez explicitement chaque type de mise à jour

Toutes les mises à jour ne contiennent pas message.text. Les boutons de rappel arrivent sous callback_query ; Les publications sur la chaîne et les modifications d'adhésion ont d'autres champs. Branchez-vous sur le champ de niveau supérieur actuel et traitez les types inconnus comme des non-opérations valides plutôt que de les lancer.

Règles de sécurité pour les tests de robots Telegram locaux

  • Validez d'abord l'en-tête secret. Rejetez les valeurs manquantes ou incorrectes avant de journaliser ou d'analyser les champs sensibles.
  • Gardez les jetons hors des URL et des journaux. Le jeton de l'API Bot dans la commande d'enregistrement est un identifiant. Évitez l'historique du shell sur les systèmes partagés et faites pivoter un jeton exposé via BotFather.
  • Utilisez un itinéraire indevinable et secret. L'itinéraire est une défense en profondeur ; l'en-tête secret est la vérification réelle de l'application.
  • Limiter les données capturées. Les messages peuvent contenir des noms, des noms d'utilisateur, des numéros de téléphone, des fichiers et du texte de conversation privée. Rédigez les journaux et supprimez les captures locales une fois terminé.
  • Ne désactivez jamais l'authentification en développement. Un tunnel public est public. Le code local doit exercer les mêmes contrôles que la production.

Voir le guide plus large de sécurité du tunnel localhost pour les pratiques de contrôle d'accès et de conservation des données.

Résoudre les échecs courants du webhook Telegram

Telegram signale une erreur de certificat ou de connexion

Utilisez l'URL HTTPS du tunnel, et non sa cible HTTP locale. Confirmez que le tunnel est actif et que l'URL n'a pas changé. Si vous fournissez plutôt votre propre certificat auto-signé, Telegram nécessite de télécharger le certificat public sous forme de fichier ; un point de terminaison TLS géré évite cette configuration.

Le point de terminaison renvoie 401

Comparez le secret transmis à setWebhook avec la variable d'environnement utilisée par le processus. Les noms d'en-tête ne sont pas sensibles à la casse, mais les proxys ou les middlewares peuvent supprimer les en-têtes personnalisés. Inspectez les en-têtes entrants sans imprimer la valeur secrète.

Aucune demande n'arrive

Exécutez getWebhookInfo, vérifiez que le chemin enregistré correspond exactement à votre itinéraire et assurez-vous qu'aucun pare-feu ne bloque la connexion locale du tunnel. Si vous avez récemment utilisé l'interrogation, confirmez que l'URL du webhook est désormais renseignée. Déclenchez une mise à jour réelle en envoyant un message au bot.

Les mises à jour arrivent à plusieurs reprises

État du journal et temps de réponse. Les exceptions après réception de la demande peuvent transformer un 200 prévu en 500. Renvoyez 200 rapidement, rendez le traitement idempotent et utilisez la relecture contrôlée du webhook plutôt que d'attendre les tentatives du fournisseur pendant le débogage.

Testez les requêtes et les fichiers de rappel, pas seulement le texte

Une matrice de test de robot utile couvre plus de message.text. Envoyez une photo avec une légende, partagez un contact, modifiez un message et appuyez sur un bouton du clavier en ligne. Pour les requêtes de rappel, appelez rapidement answerCallbackQuery afin que le client cesse d'afficher son indicateur de progression, puis effectuez un travail plus lent séparément. Les mises à jour de fichiers contiennent des identifiants ; le téléchargement des octets est une deuxième opération de l'API Bot et ne devrait pas retarder la réponse du webhook.

Conservez les appareils créés à partir de mises à jour nettoyées pour les tests unitaires, mais conservez le chemin de transport complet pour au moins un test de chaque type pris en charge. Un appareil prouve que votre répartiteur comprend une charge utile ; une véritable livraison tunnelisée prouve également le comportement d'enregistrement, de TLS, d'en-têtes, d'analyse du corps et d'accusé de réception. Lors de l'ajout d'une nouvelle entrée allowed_updates, appelez à nouveau setWebhook et vérifiez que getWebhookInfo reflète la configuration prévue.

Supprimer le webhook après la session locale

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

La suppression du webhook vous permet de revenir à getUpdates. Si l'URL du tunnel change lors de la prochaine session, appelez à nouveau setWebhook. Pour des diagnostics supplémentaires, suivez le workflow général de débogage du webhook local .

Questions fréquentes

Telegram peut-il envoyer un webhook de bot directement à localhost ?
Non. Telegram ne peut pas acheminer les requêtes vers un hôte local ou une adresse LAN privée. Utilisez un tunnel HTTPS public qui transmet les requêtes à votre serveur de robot local.
Comment authentifier les demandes de webhook du bot Telegram ?
Transmettez un secret_token aléatoire à setWebhook et comparez l'en-tête X-Telegram-Bot-Api-Secret-Token de chaque requête avec cette valeur à l'aide d'une comparaison sécurisée par le timing.
Pourquoi mon webhook Telegram reçoit-il des mises à jour en double ?
Telegram réessaye les livraisons infructueuses. Renvoyez rapidement 2xx et dédupliquez le travail par update_id afin que les nouvelles tentatives ne puissent pas répéter les effets secondaires.
Puis-je utiliser getUpdates lorsqu'un webhook Telegram est actif ?
Non. L'API Bot de Telegram n'autorise pas getUpdates lorsqu'un webhook sortant est configuré. Supprimez le webhook avant de revenir à une interrogation longue.