Skip to main content

Introduction

grammY makes it easy to create Telegram bots. Whether you’re a beginner or building at scale, grammY provides a simple yet powerful API that’s always up to date with the latest Telegram Bot API features. In this guide, you’ll create your first working bot in just a few minutes.
If you’re new to Telegram bots, read the official Introduction for Developers written by the Telegram team first.

Prerequisites

Before you begin, make sure you have:
  • Node.js (version 12.20.0 or higher) or Deno installed
  • A bot token from @BotFather

Getting Your Bot Token

1

Open BotFather

Visit @BotFather on Telegram.
2

Create a new bot

Send the /newbot command and follow the instructions.
3

Save your token

BotFather will give you a bot token. Keep it secret! You’ll need it in the next steps.

Creating Your First Bot

1

Create a new directory

mkdir my-telegram-bot
cd my-telegram-bot
2

Install grammY

npm install grammy
3

Create bot.js

Create a file called bot.js with the following code:
const { Bot } = require("grammy");

// Create a bot object
const bot = new Bot(""); // <-- place your bot token in this string

// Register listeners to handle messages
bot.on("message:text", (ctx) => ctx.reply("Echo: " + ctx.message.text));

// Start the bot (using long polling)
bot.start();
Replace the empty string with your actual bot token from BotFather.
4

Run your bot

node bot.js
Your bot is now running! Send it a message on Telegram and it will echo it back.

Understanding the Code

Let’s break down what each part of the code does:

Creating a Bot Instance

const bot = new Bot("YOUR_BOT_TOKEN");
This creates a new bot instance. The Bot class is the core of grammY and represents your bot. You must provide your bot token obtained from BotFather.

Listening for Messages

bot.on("message:text", (ctx) => ctx.reply("Echo: " + ctx.message.text));
This registers a listener for text messages. The ctx (context) object contains:
  • ctx.message - the incoming message
  • ctx.reply() - a method to send a reply
  • ctx.api - full access to the Telegram Bot API

Starting the Bot

bot.start();
This starts the bot using long polling, which continuously checks for new updates from Telegram.

Adding More Features

Now that you have a basic bot running, let’s add some common features:

Responding to Commands

import { Bot } from "grammy";

const bot = new Bot("YOUR_BOT_TOKEN");

// Handle the /start command
bot.command("start", (ctx) => {
  ctx.reply("Welcome! I'm your new bot. Send me any message!");
});

// Handle the /help command
bot.command("help", (ctx) => {
  ctx.reply("Send me a message and I'll echo it back!");
});

// Echo text messages
bot.on("message:text", (ctx) => {
  ctx.reply("Echo: " + ctx.message.text);
});

bot.start();

Handling Different Message Types

import { Bot } from "grammy";

const bot = new Bot("YOUR_BOT_TOKEN");

// Handle text messages
bot.on("message:text", (ctx) => {
  ctx.reply("You sent text: " + ctx.message.text);
});

// Handle photos
bot.on("message:photo", (ctx) => {
  ctx.reply("Nice photo!");
});

// Handle stickers
bot.on("message:sticker", (ctx) => {
  ctx.reply("Cool sticker!");
});

// Handle any other message type
bot.on("message", (ctx) => {
  ctx.reply("Got your message!");
});

bot.start();

Using the Bot API

import { Bot } from "grammy";

const bot = new Bot("YOUR_BOT_TOKEN");

bot.command("info", async (ctx) => {
  const chatId = ctx.chat.id;
  
  // Send a message
  await ctx.api.sendMessage(chatId, "Hello from the Bot API!");
  
  // Get chat information
  const chat = await ctx.api.getChat(chatId);
  ctx.reply(`This chat is called: ${chat.first_name || chat.title}`);
});

bot.start();

Error Handling

It’s important to handle errors gracefully:
import { Bot } from "grammy";

const bot = new Bot("YOUR_BOT_TOKEN");

bot.command("start", (ctx) => {
  ctx.reply("Hello!");
});

// Error handler
bot.catch((err) => {
  const ctx = err.ctx;
  console.error(`Error while handling update ${ctx.update.update_id}:`);
  const e = err.error;
  console.error("Error:", e);
});

bot.start();

Customizing Startup

You can customize how your bot starts:
import { Bot } from "grammy";

const bot = new Bot("YOUR_BOT_TOKEN");

bot.command("start", (ctx) => ctx.reply("Hello!"));

// Start with options
bot.start({
  onStart: (botInfo) => {
    console.log(`Bot @${botInfo.username} is running!`);
  },
  drop_pending_updates: true,  // Ignore old updates
  allowed_updates: ["message", "callback_query"],  // Only receive these update types
});

Best Practices

Keep your token secret! Never commit your bot token to version control. Use environment variables instead:
import { Bot } from "grammy";

const bot = new Bot(process.env.BOT_TOKEN!);
Then run your bot with:
BOT_TOKEN="your_token_here" node bot.js
Use TypeScript for better development experience. grammY has excellent TypeScript support with full type inference. Your code editor will provide helpful autocomplete and type checking.

Next Steps

Congratulations! You’ve created your first Telegram bot with grammY. Here’s what to explore next:
  • Learn about Context and all the methods available
  • Explore Middleware for handling complex logic
  • Check out Plugins to extend your bot’s capabilities
  • Learn about Deployment options for production

Resources

Build docs developers (and LLMs) love