Telegraf.js
Telegraf.js is a modern, lightweight, and extensible framework for developing Telegram bots using Node.js. It provides full support for the Telegram Bot API, currently at version 7.1 (as of v4.16.0), offering a comprehensive set of tools for handling messages, commands, and various update types. The library is actively maintained, with frequent minor releases incorporating new Bot API features and bug fixes, ensuring compatibility with the latest Telegram platform capabilities. Key differentiators include excellent TypeScript typings, compatibility with serverless environments like AWS Lambda and Firebase Functions, and support for various webhook setups (HTTP/HTTPS, Fastify, Express). It aims for simplicity and extensibility, allowing developers to build complex bot logic efficiently. The current stable version is 4.16.3.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'session')
cause Attempting to access `ctx.session` when a session middleware has not been configured or when session data wasn't properly persisted due to an asynchronous issue (e.g., missing `await`).fixEnsure you have integrated a session middleware (e.g., `telegraf-session-local` or a custom one) and added it to your bot's middleware chain (`bot.use(sessionMiddleware)`). Also, check for missing `await` keywords in async middleware functions interacting with `ctx.session`. -
TypeError: Telegraf is not a constructor
cause Incorrectly importing Telegraf in a CommonJS environment or when mixing CJS `require` with ESM `import` syntax, leading to `Telegraf` being `undefined` or an object without the constructor.fixFor CommonJS, use `const { Telegraf } = require('telegraf')`. For ES Modules, use `import { Telegraf } from 'telegraf'`. Ensure your `package.json` `type` field is correctly set to 'module' for ESM or omitted/set to 'commonjs' for CJS. -
Error: 401: Unauthorized
cause The provided Telegram bot token is invalid, expired, or incorrect. This is an API-level error from Telegram.fixDouble-check your `BOT_TOKEN` environment variable or hardcoded string. Ensure it's the exact token provided by BotFather. Generate a new token if you suspect the current one is compromised or invalid. -
TypeError: ctx.reply is not a function
cause Accessing `ctx.reply` or similar methods outside of a valid `Context` object, or within a middleware where `ctx` might be partially typed/defined without the full `TelegrafContext` methods.fixEnsure the code accessing `ctx.reply` is within a middleware or handler function properly receiving a `Context` object from Telegraf. In TypeScript, verify `ctx` is typed as `Context` or a more specific `ComposerContext`.
Warnings
- breaking Telegraf v4.0.0 introduced significant breaking changes from the 3.x series, including a full rewrite with improved TypeScript support and a revised API for middleware and context handling. Code written for 3.x is not directly compatible with 4.x.
- gotcha Session state persistence can be tricky with asynchronous operations. If `EXPERIMENTAL_SESSION_CHECKS` environment variable is enabled, Telegraf will throw errors if session is accessed/assigned after the middleware chain is thought to have exhausted, often due to missing `await`s in async code. This can lead to session data not being saved.
- gotcha Prior to v4.15.3, there were known issues with media uploads (e.g., photos, documents) and `thumbnail` processing, where `sendPhoto` and similar methods might irrecoverably error or ignore thumbnails if passed invalid paths or due to internal bugs.
- deprecated Old patterns for importing `message` or other filters directly from 'telegraf' are incorrect. Filters are now explicitly located in the `telegraf/filters` sub-path.
Install
-
npm install telegraf -
yarn add telegraf -
pnpm add telegraf
Imports
- Telegraf
const Telegraf = require('telegraf').Telegrafimport { Telegraf } from 'telegraf' - message
import { message } from 'telegraf'import { message } from 'telegraf/filters' - Markup
import { Markup } from 'telegraf/markup'import { Markup } from 'telegraf' - Composer
const Composer = require('telegraf').Composerimport { Composer } from 'telegraf'
Quickstart
import { Telegraf } from 'telegraf';
import { message } from 'telegraf/filters';
const botToken = process.env.BOT_TOKEN ?? ''; // Ensure BOT_TOKEN is set as an environment variable
if (!botToken) {
console.error('BOT_TOKEN environment variable is not set. Please provide your Telegram bot token.');
process.exit(1);
}
const bot = new Telegraf(botToken);
bot.start((ctx) => ctx.reply('Welcome! Send me a message or a sticker.'));
bot.help((ctx) => ctx.reply('I can echo your messages and react to stickers!'));
bot.on(message('sticker'), (ctx) => ctx.reply('Nice sticker! 👍'));
bot.hears('hi', (ctx) => ctx.reply('Hey there! How can I help you?'));
bot.on(message('text'), (ctx) => ctx.reply(`You said: ${ctx.message.text}`));
bot.launch();
console.log('Bot launched. Press Ctrl+C to stop.');
// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));