- Notifications
You must be signed in to change notification settings - Fork952
Modern Telegram Bot Framework for Node.js
License
telegraf/telegraf
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Bots are specialTelegram accounts designed to handle messages automatically.Users can interact with bots by sending them command messages in private or group chats.These accounts serve as an interface for code running somewhere on your server.
Telegraf is a library that makes it simple for you to develop your own Telegram bots using JavaScript orTypeScript.
- FullTelegram Bot API 7.1 support
- Excellent TypeScript typings
- Lightweight
- AWSλ/Firebase/Glitch/Fly.io/ Whatever ready
http/https/fastify/Connect.js/express.js
compatible webhooks- Extensible
const{ Telegraf}=require('telegraf')const{ message}=require('telegraf/filters')constbot=newTelegraf(process.env.BOT_TOKEN)bot.start((ctx)=>ctx.reply('Welcome'))bot.help((ctx)=>ctx.reply('Send me a sticker'))bot.on(message('sticker'),(ctx)=>ctx.reply('👍'))bot.hears('hi',(ctx)=>ctx.reply('Hey there'))bot.launch()// Enable graceful stopprocess.once('SIGINT',()=>bot.stop('SIGINT'))process.once('SIGTERM',()=>bot.stop('SIGTERM'))
const{ Telegraf}=require('telegraf')constbot=newTelegraf(process.env.BOT_TOKEN)bot.command('oldschool',(ctx)=>ctx.reply('Hello'))bot.command('hipster',Telegraf.reply('λ'))bot.launch()// Enable graceful stopprocess.once('SIGINT',()=>bot.stop('SIGINT'))process.once('SIGTERM',()=>bot.stop('SIGTERM'))
For additional bot examples see the newdocs repo
.
- Getting started
- API reference
- Telegram groups (sorted by number of members):
- GitHub Discussions
- Dependent repositories
To use theTelegram Bot API,you first have toget a bot accountbychatting with BotFather.
BotFather will give you atoken, something like123456789:AbCdefGhIJKlmNoPQRsTUVwxyZ
.
$ npm install telegraf
or
$ yarn add telegraf
or
$ pnpm add telegraf
Telegraf
instance represents your bot. It's responsible for obtaining updates and passing them to your handlers.
Start bylistening to commands andlaunching your bot.
ctx
you can see in every example is aContext
instance.Telegraf
creates one for each incoming update and passes it to your middleware.It contains theupdate
,botInfo
, andtelegram
for making arbitrary Bot API requests,as well as shorthand methods and getters.
This is probably the class you'll be using the most.
import{Telegraf}from'telegraf'import{message}from'telegraf/filters'constbot=newTelegraf(process.env.BOT_TOKEN)bot.command('quit',async(ctx)=>{// Explicit usageawaitctx.telegram.leaveChat(ctx.message.chat.id)// Using context shortcutawaitctx.leaveChat()})bot.on(message('text'),async(ctx)=>{// Explicit usageawaitctx.telegram.sendMessage(ctx.message.chat.id,`Hello${ctx.state.role}`)// Using context shortcutawaitctx.reply(`Hello${ctx.state.role}`)})bot.on('callback_query',async(ctx)=>{// Explicit usageawaitctx.telegram.answerCbQuery(ctx.callbackQuery.id)// Using context shortcutawaitctx.answerCbQuery()})bot.on('inline_query',async(ctx)=>{constresult=[]// Explicit usageawaitctx.telegram.answerInlineQuery(ctx.inlineQuery.id,result)// Using context shortcutawaitctx.answerInlineQuery(result)})bot.launch()// Enable graceful stopprocess.once('SIGINT',()=>bot.stop('SIGINT'))process.once('SIGTERM',()=>bot.stop('SIGTERM'))
import{Telegraf}from"telegraf";import{message}from'telegraf/filters';constbot=newTelegraf(token);bot.on(message("text"),ctx=>ctx.reply("Hello"));// Start webhook via launch method (preferred)bot.launch({webhook:{// Public domain for webhook; e.g.: example.comdomain:webhookDomain,// Port to listen on; e.g.: 8080port:port,// Optional path to listen for.// `bot.secretPathComponent()` will be used by defaultpath:webhookPath,// Optional secret to be sent back in a header for security.// e.g.: `crypto.randomBytes(64).toString("hex")`secretToken:randomAlphaNumericString,},});
UsecreateWebhook()
if you want to attach Telegraf to an existing http server.
import{createServer}from"http";createServer(awaitbot.createWebhook({domain:"example.com"})).listen(3000);
import{createServer}from"https";createServer(tlsOptions,awaitbot.createWebhook({domain:"example.com"})).listen(8443);
- AWS Lambda example integration
- Google Cloud Functions example integration
express
example integrationfastify
example integrationkoa
example integration- NestJS framework integration module
- Cloudflare Workers integration module
- Use
bot.handleUpdate
to write new integrations
If middleware throws an error or times out, Telegraf callsbot.handleError
. If it rethrows, update source closes, and then the error is printed to console and process terminates. If it does not rethrow, the error is swallowed.
Defaultbot.handleError
always rethrows. You can overwrite it usingbot.catch
if you need to.
ℹ️ In production,systemd
orpm2
can restart your bot if it exits for any reason.
Supported file sources:
Existing file_id
File path
Url
Buffer
ReadStream
Also, you can provide an optional name of a file asfilename
when you send the file.
bot.on('message',async(ctx)=>{// resend existing file by file_idawaitctx.replyWithSticker('123123jkbhj6b')// send fileawaitctx.replyWithVideo(Input.fromLocalFile('/path/to/video.mp4'))// send streamawaitctx.replyWithVideo(Input.fromReadableStream(fs.createReadStream('/path/to/video.mp4')))// send bufferawaitctx.replyWithVoice(Input.fromBuffer(Buffer.alloc()))// send url via Telegram serverawaitctx.replyWithPhoto(Input.fromURL('https://picsum.photos/200/300/'))// pipe url contentawaitctx.replyWithPhoto(Input.fromURLStream('https://picsum.photos/200/300/?random','kitten.jpg'))})
In addition toctx: Context
, each middleware receivesnext: () => Promise<void>
.
As in Koa and some other middleware-based libraries,await next()
will call next middleware and wait for it to finish:
import{Telegraf}from'telegraf';import{message}from'telegraf/filters';constbot=newTelegraf(process.env.BOT_TOKEN);bot.use(async(ctx,next)=>{console.time(`Processing update${ctx.update.update_id}`);awaitnext()// runs next middleware// runs after next middleware finishesconsole.timeEnd(`Processing update${ctx.update.update_id}`);})bot.on(message('text'),(ctx)=>ctx.reply('Hello World'));bot.launch();// Enable graceful stopprocess.once('SIGINT',()=>bot.stop('SIGINT'));process.once('SIGTERM',()=>bot.stop('SIGTERM'));
With this simple ability, you can:
- extract information from updates and then
await next()
to avoid disrupting other middleware, - like
Composer
andRouter
,await next()
for updates you don't wish to handle, - like
session
andScenes
,extend the context by mutatingctx
beforeawait next()
, - intercept API calls,
- reuseother people's code,
- do whateveryou come up with!
Telegraf is written in TypeScript and therefore ships with declaration files for the entire library.Moreover, it includes types for the complete Telegram API via thetypegram
package.While most types of Telegraf's API surface are self-explanatory, there's some notable things to keep in mind.
The exact shape ofctx
can vary based on the installed middleware.Some custom middleware might register properties on the context object that Telegraf is not aware of.Consequently, you can change the type ofctx
to fit your needs in order for you to have proper TypeScript types for your data.This is done through Generics:
import{Context,Telegraf}from'telegraf'// Define your own context typeinterfaceMyContextextendsContext{myProp?:stringmyOtherProp?:number}// Create your bot and tell it about your context typeconstbot=newTelegraf<MyContext>('SECRET TOKEN')// Register middleware and launch your bot as usualbot.use((ctx,next)=>{// Yay, `myProp` is now available here as `string | undefined`!ctx.myProp=ctx.chat?.first_name?.toUpperCase()returnnext()})// ...
About
Modern Telegram Bot Framework for Node.js