close icon
daily.dev platform

Discover more from daily.dev

Personalized news feed, dev communities and search, much better than what’s out there. Maybe ;)

Start reading - Free forever
Continue reading >

Building a Telegram Bot with Fastify

Building a Telegram Bot with Fastify
Author
Mahdhi Rezvi
Related tags on daily.dev
toc
Table of contents
arrow-down

🎯

In this article, we will be looking at how to build our first telegram bot with fastify. This bot will be able to crack random jokes through the telegram bot API. We will be using the Official Joke API created by David Katz to get our jokes. This is a simple API that returns a random joke.

Fastify is one of the fastest Node.js web frameworks out there. It was inspired by Express and Hapi but outperforms them when it comes to speed. Fastify is also open-sourced and focused on providing a better experience to developers with lower overhead. Fastify introduces a plugin architecture while Express uses a middleware architecture. Fastify also comes built-in with logging supported by Pino and is TypeScript ready.

Prerequisite

Before creating this application, you will need the following prerequisites.

  • Node.js installed and setup
  • Basic working knowledge of JavaScript
  • Telegram account created and application installed (mobile, desktop app, or even the web client)

Getting Started

It’s time to start building our application now.

Installing the necessary packages

Before we get started, we need to get all the necessary packages installed. I will use NPM. We also need to create our project first.


npm init -y
npm install axios dotenv fastify telebot

Before diving in, we should understand what task each of the packages that we installed the above step is responsible for.

  • Axios — a promise-based HTTP client for node.
  • Dotenv — a library that helps you load environment variables from a .env file into process.env
  • Fastify — a web framework for node.
  • Telebot — an easy to use library for writing telegram bots.

Setting up server skeleton

As we are now aware of all the background information of our application, let’s set up our server skeleton.

  • Create a server.js file with the basic server skeleton:

const fastify = require('fastify')({
   logger: true
});
const PORT = process.env.port || 3000;
// Insert bot code over here
const start = async () => {
   try {
       await fastify.listen(PORT);
   } catch (err) {
       fastify.log.error(err);
       process.exit(1);
   }
}
start();

  • Modify the package.json file:

{
 ...
 "scripts": {
  "start": "node server"
 },
 ...
}

  • Run npm start in your terminal and make sure there are no errors:

npm start

Building our bot

Initiating our bot with telegram

Before we can start writing code for our telegram bot, we need to create a bot first. Bots can be created with the help of a feature called “Bot Father”. Simply open telegram and search for @BotFather. Or you can click on this link to open a conversation with Bot Father.

BotFather is a bot that helps you create and manage bots. You can simply start the convo by clicking on the start button. If you encounter any issues when starting the conversation, make sure you try it from the telegram mobile application.

BotFather Screenshot

Click on /newbot or type /newbot and send. Follow the on-screen instructions to create your telegram bot. Once you have successfully created your telegram bot, BotFather will give you a telegram bot token. Make sure to keep it safe as we need it to code our bot.

Accessing the telegram bot token with env

  • Create a .env file in your root directory. This is where we will be storing our sensitive credentials.
  • Add the below contents to the .env file. Make sure to replace the token and name with your bot token and name.

TELEGRAM_BOT_TOKEN=<your-telegram-bot-token-here>
BOT_NAME=<your-telegram-bot-name-here>

  • Load the variables. Make sure the code is typed into where the comment // Insert bot code over here is typed. All of our bot-related code should be typed in this section.

require('dotenv').config();

Setting up our route for the homepage

In this step, we will set up a default route for our server. Even though our server is not meant to receive any HTTP requests, we will set up a default route. This will make sure if anyone visits our server mistakenly, they will know what it does.

  • Create a file under routes/default-route.js:

async function routes(fastify, options) {
fastify.get('/', async (request, reply) => {
       reply
           .code(200)
           .type('text/html')
           .send(`This is a telegram bot server created to tell you jokes. Open the telegram app and ask for a joke from the bot ${process.env.BOT_NAME}`);
   })
fastify.get('/*', async (request, reply) => {
       reply
           .redirect('/');
   })
}
module.exports = routes;

In the above code, we simply return a text when someone accesses our endpoint. We also make sure all routes are redirected to our base endpoint.

  • Register route in server.js file:

fastify.register(require('./routes/default-route'));

Add the above code into our server.js file.

Coding our bot

  • The main code that is responsible for the working of our bot:

const axios = require('axios').default;
const TeleBot = require('telebot');
const initBot = () => {
   const bot = new TeleBot(`${process.env.TELEGRAM_BOT_TOKEN}`);
   return bot;
}
const initBotMethods = (bot) => {
   bot.on(['/start', '/hello'], (msg) => {
       return msg.reply.text('Welcome!');
   });
bot.on(/(tell\s)?joke*/, async (msg) => {
       const result = await axios.get('https://official-joke-api.appspot.com/random_joke');
       if (result?.data) {
           return msg.reply.text(`${result.data.setup}\n\n ---${result.data.punchline}`);
       } else {
           return msg.reply.text("Let's retry that!");
       }
   });
}
const startBot = () => {
   const bot = initBot();
   initBotMethods(bot);
   bot.start();
}

The initBot method initializes our Telebot API with the telegram bot token.
The initBotMethods method defines the actions to be performed by our bot. On receiving the commands /start and /hello, it will send a greeting. If it receives a message containing “tell joke” or “joke”, it will send an HTTP request to our joke API, and receive a random joke. This random joke will be sent to the user via the bot API.
The startBot method simply calls these methods and starts the bot.

  • Call the startBot method just above the start method:

startBot();
start();

Finalizing our code

To finalize our code, let’s take all our require statements to the top. Your server.js file would be somewhat like this:


const fastify = require('fastify')({
   logger: true
});
const PORT = process.env.port || 3000;
require('dotenv').config();
const axios = require('axios').default;
const TeleBot = require('telebot');
fastify.register(require('./routes/default-route'));
const initBot = () => {
   const bot = new TeleBot(`${process.env.TELEGRAM_BOT_TOKEN}`);
   return bot;
}
const initBotMethods = (bot) => {
   bot.on(['/start', '/hello'], (msg) => {
       return msg.reply.text('Welcome!');
   });
bot.on(/(tell\s)?joke*/, async (msg) => {
       const result = await axios.get('https://official-joke-api.appspot.com/random_joke');
       if (result?.data) {
           return msg.reply.text(`${result.data.setup}\n\n ---${result.data.punchline}`);
       } else {
           return msg.reply.text("Let's retry that!");
       }
   });
}
const startBot = () => {
   const bot = initBot();
   initBotMethods(bot);
   bot.start();
}
const start = async () => {
   try {
       await fastify.listen(PORT);
   } catch (err) {
       fastify.log.error(err);
       process.exit(1);
   }
}
startBot();
start();

Testing our application

Since we have everything ready, we can now start testing our application.

  • Start the server:

npm start

  • Checking whether our endpoint is working. We’ll simply open the URL on our browser:
The bot on our browser

Awesome. The endpoint is working great. Now let’s check whether our actual bot is working.

  • Open a conversation with your bot through telegram. Similar to what we did with the BotFather bot, click on the start button to initiate a conversation. If you have any errors, make sure you try from a mobile application.
 conversation with the bot on telegram

The greeting worked. Now let’s try asking for a joke.

  • Ask a joke from the bot.
Joke asked from the bot

That’s awesome, isn’t it? Let’s try another query.

Another query from the bot

Surprisingly, it still returns a joke, even though we haven’t mentioned the word “tell”. This is because we have used regex to match the strings.

Conclusion

Telegram bots have a huge potential waiting to be explored and this article just touched on the basics. I believe you gained valuable knowledge regarding telegram bots and integrating them with fastify.

You can access the source code repository over here.

Why not level up your reading with

Stay up-to-date with the latest developer news every time you open a new tab.

Read more