In Telegram bot development, real-time responsiveness is key to delivering a good user experience. While long polling is a common method during initial development, webhooks are preferred for production due to their efficiency and real-time capabilities.
This guide walks through the steps to set up and test Telegram bot webhooks using Pinggy, a command-line tool that creates a secure public URL for your local server, simplifying webhook testing without needing external hosting.
What Are Telegram Bot Webhooks?
Telegram bots can receive updates using two methods:
- Long Polling: The bot periodically requests updates from Telegram.
- Webhooks: Telegram sends updates directly to a server endpoint you specify.
Webhooks offer several benefits over polling:
- Instant delivery of updates
- Reduced server load and bandwidth usage
- Better scalability for production environments
To use webhooks, your server must be publicly accessible over HTTPS, which can be a challenge during development. This is where tools like Pinggy are useful.
Step 1: Create a Telegram Bot
-
Start a chat and send
/newbot
-
Follow the prompts to set a name and username
You’ll receive a token that looks like
123456789:ABCDefGhIJKlmNoPQRsTUVwxyZ
Keep this token secure—it allows full control over your bot.
Step 2: Create a Local Webhook Server
Use Python and Flask to create a local server that receives JSON updates from Telegram.
from flask import Flask, request, jsonify
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/webhook', methods=['POST'])
def webhook():
update = request.get_json()
logging.info(f"Update received: {update}")
if 'message' in update:
chat_id = update['message']['chat']['id']
text = update['message'].get('text', '')
logging.info(f"Message from {chat_id}: {text}")
return jsonify({'status': 'ok'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Install Flask:
pip install flask
Run the server:
python telegram_webhook.py
This creates a local server at http://localhost:8000/webhook
.
Step 3: Expose Your Local Server Using Pinggy
To allow Telegram to reach your local server, expose it via Pinggy.
Run the following command:
ssh -p 443 -R0:localhost:8000 qr@a.pinggy.io
Pinggy will provide a public HTTPS URL such as:
https://abcdefghij.a.pinggy.link
Step 4: Register the Webhook
Tell Telegram where to send updates using the Bot API:
curl -X POST "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook" \
-d "url=https://abcdefghij.a.pinggy.link/webhook"
Replace <YOUR_BOT_TOKEN>
and the URL with your actual values. If successful, you should receive a confirmation response from Telegram.
Step 5: Test the Webhook
- Open Telegram and send a message to your bot.
- Check the terminal where your Flask server is running.
- You should see log entries showing the update payload and message content.
Example log:
INFO:root:Update received: {...}
INFO:root:Message from 123456789: Hello
Enhancing Your Webhook Server
To respond to messages, extend the server with message-sending capabilities.
import requests
def send_message(chat_id, text, token):
url = f"https://api.telegram.org/bot{token}/sendMessage"
payload = {"chat_id": chat_id, "text": text}
response = requests.post(url, json=payload)
return response.json()
You can integrate this function into the webhook handler to send replies based on user messages.
Conclusion
Webhooks provide a reliable and efficient mechanism for real-time bot communication. For developers testing on local machines, Pinggy offers a practical solution to expose local webhook endpoints securely and temporarily. This setup allows thorough testing before deploying to production environments.
That Pinggy trick for quick webhook testing is a real time saver, thanks for laying it out so clearly. Have you ever tried using tools like ngrok for this, or do you find Pinggy consistently smoother?