Build a Telegram Bot with Node.js and Telegraf (Step-by-Step)

author

by umidjon gafforov

02 min read

Oct 11, 2025

alt

Share

Why Telegram bots with Node.js?

Node.js offers a huge ecosystem, simple async I/O, and great libraries like Telegraf. You can ship MVPs fast and scale later.

Prerequisites

  • Node.js 18+ and npm

  • A Telegram account

  • Basic JS knowledge

1) Create a bot in BotFather

  1. Search @BotFather in Telegram.

  2. Send /newbot, choose a name and a unique username.

  3. Copy the HTTP API token — keep it secret.

2) Project setup

mkdir tg-bot && cd tg-bot
npm init -y
npm i telegraf dotenv
echo "BOT_TOKEN=PASTE_YOUR_TOKEN" > .env echo "node_modules\n.env" >> .gitignore

Create index.js:

import 'dotenv/config';
import { Telegraf, Markup } from 'telegraf';

const bot = new Telegraf(process.env.BOT_TOKEN);

// Basic /start
bot.start((ctx) => {
 const name = ctx.from.first_name ?? 'friend';
 return ctx.reply(
 `Hi, ${name}! I am your Node.js bot.`,
 Markup.keyboard([['Help', 'About']]).resize()
);
});

// Text handler
bot.hears('Help', (ctx) =>
ctx.reply('Use /start or type "About" to learn more.')
);

bot.hears('About', (ctx) =>
ctx.reply('Built with Node.js + Telegraf. Open source friendly!')
);

// Command with parameters
bot.command('echo', (ctx) => {
 const msg = ctx.message.text.split(' ').slice(1).join(' ');
ctx.reply(msg || 'Send: /echo your text');
});

// Error boundary
bot.catch((err, ctx) => {
 console.error('Bot error:', err);
ctx.reply('Oops. Try again later.');
});

bot.launch();
console.log('Bot is running…');

// Graceful stop (for hosting)
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

Run:

node index.js

Send /start to your bot and test the buttons.

3) Middleware, scenes, and rate-limits

  • Middleware: bot.use(async (ctx, next) => { /* logging, auth */; await next(); })

  • Session: @telegraf/session to store per-user data.

  • Rate-limit: implement a simple map (userId → lastTime) or use packages like telegraf-ratelimit.

4) Webhooks vs long polling

  • Development: long polling (default) is simplest.

  • Production: prefer webhooks (less latency, fewer dropped updates).

// Example (Express) import express from 'express';
const app = express();

app.use(bot.webhookCallback('/tg-webhook'));
await bot.telegram.setWebhook('https://your-domain.com/tg-webhook');

app.listen(3000, () => console.log('Server 3000'));

5) Deployment (Railway/Render/VPS)

  • Set environment variable BOT_TOKEN in your host dashboard.

  • If using webhooks, expose HTTPS (custom domain or host URL).

  • Add graceful stop signals (already in the code).

6) Storing data

  • Start with SQLite or MongoDB:

npm i mongoose

import mongoose from 'mongoose';
await mongoose.connect(process.env.MONGO_URL);

7) Security checklist

  • Never hard-code tokens. Use .env.

  • Validate user input.

  • Handle errors with bot.catch.

  • Limit admin-only commands by checking ctx.from.id.

8) Next ideas

  • Payment + invoices

  • Mini-apps (WebApp) with React/Next.js

  • CRON jobs (node-cron) for reminders

Final words

With Telegraf, you can go from idea to production in hours. Start small, add tests and monitoring, and iterate.

Hali komment yo‘q. Birinchi bo‘ling!

Komment yozish uchun avval tizimga kiring

author

umidjon gafforov

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,

See all posts by this author