Testing Telegram bots locally
Table of contents
- Introduction
- The problem with setWebhook
- First solution: Use long polling
- Second solution: Proxy with ngrok
- Third solution: Forward port in VSCode
Introduction
Telegram bots are automated programs that operate entirely within the Telegram messaging app, designed to perform a wide range of tasks. They are particularly useful for someone like me who uses Telegram daily as their primary messaging app, as well as for communities and businesses looking to streamline communication with their members or customers on Telegram.
As a software developer, I have always found it exciting that the Bot API is open and available to anyone. However, I must admit that the development experience has not quite met my expectations. When testing your bot, you are required to deloy it to either a a production or staging server. This is necessary to receive updates from Telegram and to accurately test bot responses from end to end. The downside? This setup lacks the convenience of ad-hoc logging and the efficiency of fast code refreshes after making changes.
The problem with setWebhook
Webhook is the superior approach for getting updates from Telegram servers, however it requires a publicly available address for your bot and a SSL certificate, since Telegram servers make HTTPS POST requests to the registered URL or IP. This means two things:
- Your bot needs be deployed somewhere to be publicly available. localhost will not suffice here.
- A valid SSL certificate is required. localhost is also unsuitable this this case.
First solution: Use long polling
Long polling is the second approach for getting updates from Telegram servers. While it is less efficient than using webhooks, however it can serve as a practical alternative for local development environments. Unlike webhooks, long polling does not require you to have a server with a public IP or the setup of SSL certificates. You can test your bot locally on your development machine without worrying about these configurations. Moreover, it is straightforward to implement and understand. It is a matter of making regular HTTP requests to the Bot API, asking for any new updates since the last request.
- Disable webhook on your bot if present.
- Use the getUpdates method to fetch last updates from Telegram.
- Handle
offset
to query the most recent updates by including the highest updateID received + 1
. - Establish a polling interval between each
getUpdates
request.
Note: While long polling is excellent for development, consider switching to webhooks for production environments to benefit from real-time updates without the need to continuously poll the server.
Second solution: Proxy with ngrok
Ngrok is a reverse proxy tool that creates a secure tunnel from a public endpoint to a local development environment. This approach simplifies testing webhook-based applications, like Telegram bots, by bypassing the need for a public IP address or configuring SSL certificates, as ngrok provides these out of the box.
- Install ngrok on your machine via your preferred package manager. E.g.
npm install -g ngrok
. - Initiate a tunnel in your terminal
ngrok http {port}
. Where{port}
is your desired proxy port. - Configure your bot’s webhook to the URL provided by ngrok. It should look something like this:
https://12345678.ngrok.io
.
Note: The free tier of ngrok offers a sufficient number of requests for side projects, but for larger scale applications, you might encounter rate limits. Additionally, each time you initiate the free version of ngrok, it generates a new public URL. This dynamic nature necessitates updating your webhook URL in your Telegram bot settings each time you restart ngrok.
Third solution: Forward port in VSCode
VSCode offers a feature beneficial to Telegram bot developers working with webhooks: port forwarding. This functionality enables the exposure of local servers to the internet directly within the development environment, facilitating real-time testing and interaction without external tools like ngrok.
- Launch Visual Studio Code.
- Run your Telegram bot application on
{port}
. - Go to the Ports section.
- Select Forward a Port.
- Access the URL provided by VSCode, similar to
https://12345678-{port}.euw.devtunnels.ms
and authenticate if necessary. - Right-click on the port entry and switch Port Visiblity from Private to Public.
- Configure your bot’s webhook with URL provided by VSCode.
Although VSCode port forwarding may not be as immediate as ngrok, it is entirely free and maintains the same public URL across restarts.