TL;DR We’ll use the Telegraf Nodejs library to make and deploy our telegram bot using the webhook method, which is a more desirable and efficient way, on the Cyclic.sh platform (FREE $10 credit).
Cyclic is easy to use and offers a free tier and is affordable.
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
- Get a server to host your code (Cyclic platform, or any other provider like Heroku)
- Use the code below to set up the project as you want
- Make sure you put the API keys and bot token in the .ENV files (environment variables)
- Deploy the project on the server, add your ENV vars
- Set up your webhook, and optimize it for scale.
- 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);
}
PS: Make sure you set the environment variables in the project’s settings so it runs in production on whichever platform you use.
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 cyclic.sh, for example, the project URL will be something like https://your-app-name.cyclic.app/ which will be your domain name, now when you use the above code your webhook URL will look like this – https://your-app-name.cyclic.app/telegraf/<hashed string>
The cyclic.sh 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>&drop_pending_updates=true
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), for example – https://my-test-bot.cyclic.app
drop_pending_updates = To drop the pending updates, and preventing to receive them again and again.
For instance:
https://api.telegram.org/bot18459:AAEdaCGiM/setWebhook?url=https://my-test-bot.cyclic.app&drop_pending_updates=true
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.cyclic.app/telegraf/<hashed string>",
"has_custom_certificate":false,
"pending_update_count":0,
"max_connections":40
}
}
Important endpoints:
To set webhook –
https://api.telegram.org/bot<bot_token>/setWebhook?url=<webhook_url>&drop_pending_updates=true
To delete webhook –
https://api.telegram.org/bot{bot_token}/deleteWebhook
Get webhook information –
https://api.telegram.org/bot{bot_token}/getWebhookInfo
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 Cyclic/other platforms, 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