How to set up webhook for telegram bot – full guide 2022

Learn how to use webhooks in your Telegram bot in development mode using telegraf library and Heroku

TL;DR We’ll use the Telegraf Nodejs library to make and deploy our telegram bot using the webhook method, which is more desirable and efficient, on Railway.app platform (FREE $5 credit/month).

Introduction

Telegram bots are third-party bots that run inside the telegram web and app infrastructure. Users can interact with the bots as a standalone app and can have their custom UI/UX like buttons, inline mode, etc. We’ll learn about webhook mode here only.

Bots can be used for tons of purposes like acting as a publishing medium, automating tasks, useful tools like searching for images, accepting payments from Telegram users, or creating any other custom tools you like. Opportunities are endless.

Bots can use two modes to send/receive information via Bot API.

  • Long-polling-mode
  • Webhook mode

We’ll learn about the webhook mode and how to use it to create a telegram bot, the right way. The long-polling mode is the default mode that you can use to run the bot locally for testing purposes.

Steps to follow

  1. Get a server to host your code (Railway.app, or any other provider like Heroku)
  2. Use the code below to set up the project as you want
  3. Make sure you put the API keys and bot token in the .ENV files (environment variables)
  4. Deploy the project on the server, add your ENV vars
  5. Set up your webhook, and optimize it for scale.
  6. Test the bot if it’s working properly (debug using logs)

Project setup

You need to have the bare bones done in order to use webhook so that we can check it works perfectly. We’re using the Telegraf library to build the bot here.

Basic code to get your bot up and running.

const { Telegraf } = require('telegraf')

const bot = new Telegraf(process.env.BOT_TOKEN)
bot.start((ctx) => ctx.reply('Welcome'))
bot.help((ctx) => ctx.reply('Send me a sticker'))
bot.on('sticker', (ctx) => ctx.reply('👍'))
bot.hears('hi', (ctx) => ctx.reply('Hey there'))
bot.launch() // Default long-polling mode

This code is the bare bones we need to start using webhooks, currently, this telegram bot uses long-polling mode which the telegraf library offers in default mode, which comes in handy when we’re developing the bot locally as webhook can’t work on the local environment.

You can use the .ENV file to store your environment variables aka project secrets that you don’t want to be exposed publically. For example, bot API token and/or other API keys.

Two-step process

Webhook specified in code

Use the code below to check if the environment is local or production.

let bot;
if(process.env.environment == "PRODUCTION"){ // if environment is "Production"
   bot = new Telegraf(process.env.MAIN_BOT_TOKEN);
   bot.startWebhook(`/${YOUR_BOT_TOKEN}`, null, 3000); // Setting webhook URL path
} else { // Else local
   bot = new Telegraf(config.TEST_BOT_TOKEN);
}

The above code looks if your environment is production or local, and setting the webhook only at PRODUCTION mode, there is a permanent way of setting the webhook via a get request. However, it’s your choice how you want to use it because it permanently sets your webhook to a particular URL you specify, better for scale. You can delete it as well.

Similarly, add this code at the end, it specifies your webhook domain URL that will receive the updates via the Bot API.

if(process.env.environment == "PRODUCTION"){
  bot.launch({
    webhook:{
        domain: process.env.DOMAIN,// Your domain URL (where server code will be deployed)
        port: process.env.PORT || 8000
    }
  }).then(() => {
    console.info(`The bot ${bot.botInfo.username} is running on server`);
  });
} else { // if local use Long-polling
  bot.launch().then(() => {
    console.info(`The bot ${bot.botInfo.username} is running locally`);
  });
}

If you’re using Railway.app, for example, the project URL will be something like https://your-app-name.up.railway.app that will be your domain name, now when you use the above code your webhook URL will be – https://your-app-name.up.railway.app/telegraf/<hashed string>

The Railway.app interface allows you to add your environment variables in the setting of your app, or if you’re using some other service they’ll provide you to add them for each app you deploy.

Suggested reading: How I got more than 3000+ telegram bot users overnight


Webhook optimization

Everything stays the same, but we’re just removing the bot.startWebhook(‘/secret-path’, tlsOptions, PORT) function.

This is just for optimization, as this code runs again every time you start your server. So instead, we’ll replace it with a get request and it will set our webhook permanently, if needed we can delete it too. Below is the URL, add the details, and open this link on your web browser after deploying your bot.

https://api.telegram.org/bot<bot_token>/setWebhook?url=<webhook_url>

bot_token: What you get from BotFather, abc:19802
webhook_url: Your primary domain/endpoint where your code is hosted, and exposed to the web (must be HTTPS), like
https://my-test-bot.up.railway.app/

For instance:
https://api.telegram.org/bot18459:AAEdaCGiM/setWebhook?url=https://my-test-bot.up.railway.app/

You’ll get a response back as “webhook was set”. If you want to make sure it’s done properly use this –
https://api.telegram.org/bot{bot_token}/getWebhookInfo

You’ll get a response back as such –

{
 "ok":true,
 "result": 
 {
   "url":"https://stars-at-peak-24.up.railway.app/telegraf/<hashed string>",
   "has_custom_certificate":false,
   "pending_update_count":0,
   "max_connections":40
 }
}

Conclusion

Make sure you’ve deployed the bot to the server before adding the webhook via the GET URL manually. Once set the bot will continue to work properly. If any problem arises first check the server logs on Railway, that will help you to debug your app, and see where the problem is. Contact/follow me on Twitter @zippytyro

Suggested reading: How I got more than 3000+ telegram bot users overnight