# How to Build a Telegram Bot Using Typescript & Node.js

21 Dec 2022

By Eluda  
Engineering

## Introduction

In this tutorial, you’ll learn all the steps that go into building a dead-simple Telegram bot and hosting it on the cloud. It will greet people and apply ＦＡＮＣＹ text effects.

You’ll be writing code using the Typescript language and running it on the Node.js server environment.

And seeing as Telegram bots are built on an HTTP-based API, you’ll be using the [GrammY framework](https://grammy.dev/) for higher-level abstractions and a better programming experience.

### Prerequisites

Before writing any code, make sure to have the following programs installed on your computer:

- [Telegram client.](https://telegram.org/)
- [Node.js](https://nodejs.org/en/download/) v14+, NPM v6+, and cURL.
- VS Code, or any other IDE of choice.

You’ll be using [Cyclic](https://www.cyclic.sh/) to host this project on the cloud, so make sure to take advantage of the Free Forever tier.

And while you don’t have to be an expert in it, you should know a bit of Typescript. You’ll be using it to write all the code in this tutorial.

### Setup the Project

Downloading the starter files  
Start-up this project by cloning the final version into your computer:

```bash

```

And make sure to roll it back to its very first stage, so you can learn how to build the rest of it in this tutorial:

```bash

```

After that’s done, install the project’s dependencies:

```bash

```

#### Getting your Telegram bot API token

Using the Telegram client, start a conversation with the [@BotFather](https://telegram.me/BotFather).

Send it the following messages:

1. /newbot
2. Your bot name
3. Your bot username (can’t contain spaces and must end in “bot”)

After that, create a new file in the project’s root directory called `.env`. Paste the following line into that file, replacing `<YOUR-API-TOKEN>` with your bot’s API token that you just got from the last message with [@BotFather](https://telegram.me/BotFather).

```text

```

#### Initializing the Telegram bot

Create a new file called `bot.ts` in the `src/` directory. That’s where you’ll be writing code for the rest of this tutorial.

You’ll be using the [GrammY framework](https://grammy.dev/) to build this bot; it’s much easier this way instead of interacting directly with the [API routes](https://core.telegram.org/bots/api).

Head into the bot script and import the library in question:

```typescript

```

As you can see, the bot is created with the `TELEGRAM_TOKEN` variable that you just set in the `.env` file. After that, handle all message events by responding with a friendly robot introduction:

```typescript

```

Take note of the `parse_mode` parameter. It’s used to allow HTML tags in the message response, such as `<b>Commands</b>`.

And finally, start-up the bot by running one method:

```typescript

```

Follow that by executing the bot script:

```bash

```

And boom! You’ve got yourself a dead-simple bot running on your computer. You can test-it out by sending it a message on Telegram; you may want to follow the link previously given to you by [@BotFather](https://telegram.me/BotFather).

## Handle basic commands

Telegram bots can handle commands, which aren’t much different from ordinary messages. The syntax for such interactions follows the following format:

```typescript

```

Test it out by sending the `/start` message to your bot. Note that your program is automatically updated once you modify the bot script.

After that’s done, modify your bot to handle the `/yo` command. It will simply respond with the username of the sender:

```typescript

```

And since the `bot.on(“message”)` event handler is on top, it will catch all messages and the /start and /yo commands won’t have an effect. Please make sure to always keep it at the bottom of the file:

```typescript

```

## Build Inline Keyboards

Telegram bots can also respond with a set of buttons underneath the message. Let’s do a simple demonstration. Change the introductory response to also contain a button that links users to the [Cyclic](https://www.cyclic.sh/) website, the platform that we’ll use to deploy our bot to the cloud for free at the end of this tutorial:

```typescript

```

After this step, you may want to re-execute the bot script after interrupting it with the `Ctrl+C` keyboard combination:

```bash

```

#### A more advanced example

Let’s now do a more advanced example. Other inline keyboards may contain general buttons, whose actions can be handled to the furthest extent. Handle the `/effect`command, and make it apply bold, italic, and a bunch more effects to text:

```typescript

```

## Handle Inline Queries

Telegram bots support inline queries, a feature which enables them to be invoked from any chat within Telegram by calling them with their “@” username. Let’s use this to allow users to apply text effects in any conversation using your bot.

#### Enabling inline mode for your Telegram bot

By default, this feature comes disabled. Contact [@BotFather](https://telegram.me/BotFather) to enable it:

1. /mybots
2. Select your bot from the inline keyboard
3. Bot settings
4. Inline mode
5. Turn on

Handling the “effect” inline query Inline queries are generally handled by matching a RegEx pattern. We’ll listen for the “effect \[effect\] \[text\]” query and handle it by applying \[effect\] to \[text\]:

```typescript

```

## Polish the Telegram Bot

It’s often useful for Telegram bots to display a list of supported commands, and while we’re already doing that in the introductory message, there’s a more formal way of doing so, and it’s as simple as one command:

```typescript

```

Note that to see the new menu, you must restart your Telegram client.

Furthermore, professional bots come with a profile picture and a well-formed description. You can do all of that by contacting [@BotFather](https://telegram.me/BotFather):

1. Edit bot
2. Edit about / Edit description / Edit botpic

## Deploy the Telegram Bot to the Cloud

#### Long Polling vs Webhooks

There are two fundamentally different ways of deploying your Telegram bot to the web.

The first one is [Long Polling](https://grammy.dev/guide/deployment-types.html#how-does-long-polling-work), and we’ve already been using it in this tutorial by running `bot.start()`. With it, bots constantly send requests to the Telegram servers checking for new messages, and responding to them accordingly.

This approach is not compatible with the serverless architecture, as the latter expects applications to only run once, and only on-demand.

“Serverless means applications are only on for the time it takes to process individual requests. They are suspended immediately after each response is sent.” — [Cyclic docs](https://docs.cyclic.sh/serverless/on-demand).

The solution to this problem is deployment by [Webhooks](https://grammy.dev/guide/deployment-types.html#how-do-webhooks-work), an alternative strategy that makes the Telegram client itself contact your bot when there’s a new message. And while this comes with [its own drawbacks](https://grammy.dev/guide/deployment-types.html#webhook-reply), it’s fully compatible with serverless architecture.

#### Using Webhooks for deployment

By following the `NODE_ENV` environment variable, we can tell whether the bot instance is running in a development or a production stage. Replace the `bot.start()` command with the following:

```typescript

```

#### Pushing all files to a Github Repository

It’s imperative that we use a Github repository to store our bot files so we can deploy it to the cloud. After [creating a new repository](https://github.com/new) (either public or private), run the following commands to link it with your local Git instance, replacing `<YOUR-GH-REPO-LINK>` with your repo’s URL:

```bash

```

After that, stage, commit, and push your files to the new remote origin:

```bash

```

#### Deploying for free using Cyclic

After creating your Cyclic account, use it to deploy your new Telegram bot. It’s free forever, and no credit card is required.

Note that you must sign up using the same Github account that you used to create your bot’s repository.

Open your [Cyclic dashboard](https://app.cyclic.sh/#/), click on the Deploy button and switch to the “Link your own” tab. Search for your bot’s repo and click on the “Connect” button. Then sit back and watch it do all the work for you!

The final step is setting the same environment variables as you did in the `.env` file. Open your Cyclic deployment’s dashboard page, switch to the Variables page and set the appropriate values for the environment variables:

- NODE_ENV: production
- TELEGRAM_TOKEN: your bot’s API token (same as `.env` file)

#### Connecting your Telegram bot to your Cyclic server

You want to tell Telegram to send the Webhook requests to your Cyclic server. So conclude this project by copying your Cyclic deployment’s URL and running these commands:

```bash

```

And boom! Your bot’s now actively running on the cloud! You may stop your local development instance by pressing `Ctrl+C` and notice how your bot is still working.

## Conclusion

You’ve successfully reached the end of this tutorial! There are many more things you could add to this bot, including but not limited to games, error handling and internationalization.

You may also want to learn more about Telegram bots:

- [https://grammy.dev/guide/inline-queries.html](https://grammy.dev/guide/inline-queries.html)
- [https://grammy.dev/plugins/keyboard.html](https://grammy.dev/plugins/keyboard.html)
- [https://grammy.dev/guide/deployment-types.html](https://grammy.dev/guide/deployment-types.html)

And here are some resources to advance your knowledge about serverless computing:

- [Cyclic vs Heroku](https://www.cyclic.sh/vs-heroku)
- [Considerations for Serverless Active-Active: Routing](https://www.cyclic.sh/posts/considerations-for-serverless-active-active-routing/)
- [How to Fail at Serverless: Serverless is Stateless](https://www.cyclic.sh/posts/how-to-fail-at-serverless-serverless-is-stateless/)
- [Creating and Deploying a RESTful API on Serverless Infrastructure](https://docs.cyclic.sh/tutorials/rest-api-and-dynamodb/part-1)
