UNPKG

13.3 kBMarkdownView Raw
1<header>
2<img src="https://raw.githubusercontent.com/telegraf/telegraf/010e971f3c61c854605bf9a5af10a4925d4032fb/docs/header.png" style="background: #FFFFFF3F">
3
4[![Bot API Version](https://img.shields.io/badge/Bot%20API-v5.1-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api)
5![GitHub top language](https://img.shields.io/github/languages/top/telegraf/telegraf?style=flat-square)
6[![install size](https://flat.badgen.net/packagephobia/install/telegraf)](https://packagephobia.com/result?p=telegraf,node-telegram-bot-api)
7[![Russian chat](https://img.shields.io/badge/Russian%20chat-grey?style=flat-square&logo=telegram)](https://t.me/telegraf_ru)
8[![English chat](https://img.shields.io/badge/English%20chat-grey?style=flat-square&logo=telegram)](https://t.me/TelegrafJSChat)
9</header>
10
11## For 3.x users
12
13- [3.x docs](https://telegraf.js.org/v3)
14- [4.0 release notes](https://github.com/telegraf/telegraf/releases/tag/v4.0.0)
15
16## Introduction
17
18Bots are special [Telegram](https://telegram.org) accounts designed to handle messages automatically.
19Users can interact with bots by sending them command messages in private or group chats.
20These accounts serve as an interface for code running somewhere on your server.
21
22Telegraf is a library that makes it simple for you to develop your own Telegram bots using JavaScript or [TypeScript](https://www.typescriptlang.org/).
23
24### Features
25
26- Full [Telegram Bot API 5.1](https://core.telegram.org/bots/api) support
27- [Excellent TypeScript typings](https://github.com/telegraf/telegraf/releases/tag/v4.0.0)
28- [Lightweight](https://packagephobia.com/result?p=telegraf,node-telegram-bot-api)
29- [Firebase](https://firebase.google.com/products/functions/)/[Glitch](https://dashing-light.glitch.me)/[Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction)/[AWS **λ**](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html)/Whatever ready
30- `http/https/fastify/Connect.js/express.js` compatible webhooks
31- Extensible
32
33### Example
34
35```js
36const { Telegraf } = require('telegraf')
37
38const bot = new Telegraf(process.env.BOT_TOKEN)
39bot.start((ctx) => ctx.reply('Welcome'))
40bot.help((ctx) => ctx.reply('Send me a sticker'))
41bot.on('sticker', (ctx) => ctx.reply('👍'))
42bot.hears('hi', (ctx) => ctx.reply('Hey there'))
43bot.launch()
44
45// Enable graceful stop
46process.once('SIGINT', () => bot.stop('SIGINT'))
47process.once('SIGTERM', () => bot.stop('SIGTERM'))
48```
49
50```js
51const { Telegraf } = require('telegraf')
52
53const bot = new Telegraf(process.env.BOT_TOKEN)
54bot.command('oldschool', (ctx) => ctx.reply('Hello'))
55bot.command('hipster', Telegraf.reply('λ'))
56bot.launch()
57
58// Enable graceful stop
59process.once('SIGINT', () => bot.stop('SIGINT'))
60process.once('SIGTERM', () => bot.stop('SIGTERM'))
61```
62
63For additional bot examples see [`examples`](https://github.com/telegraf/telegraf/tree/develop/docs/examples) folder.
64
65### Resources
66
67- [Getting started](#getting-started)
68- [API reference](https://telegraf.js.org/modules.html)
69- Telegram groups (sorted by number of members):
70 * [Russian](https://t.me/telegraf_ru)
71 * [English](https://t.me/TelegrafJSChat)
72 * [Uzbek](https://t.me/telegrafJS_uz)
73 * [Ethiopian](https://t.me/telegraf_et)
74- [GitHub Discussions](https://github.com/telegraf/telegraf/discussions)
75- [Dependent repositories](https://libraries.io/npm/telegraf/dependent_repositories)
76
77## Getting started
78
79### Telegram token
80
81To use the [Telegram Bot API](https://core.telegram.org/bots/api),
82you first have to [get a bot account](https://core.telegram.org/bots)
83by [chatting with BotFather](https://core.telegram.org/bots#6-botfather).
84
85BotFather will give you a *token*, something like `123456789:AbCdfGhIJKlmNoQQRsTUVwxyZ`.
86
87### Installation
88
89```shellscript
90$ npm install telegraf
91```
92or
93```shellscript
94$ yarn add telegraf
95```
96or
97```shellscript
98$ pnpm add telegraf
99```
100
101### `Telegraf` class
102
103[`Telegraf`] instance represents your bot. It's responsible for obtaining updates and passing them to your handlers.
104
105Start by [listening to commands](https://telegraf.js.org/classes/telegraf.html#command) and [launching](https://telegraf.js.org/classes/telegraf.html#launch) your bot.
106
107### `Context` class
108
109`ctx` you can see in every example is a [`Context`] instance.
110[`Telegraf`] creates one for each incoming update and passes it to your middleware.
111It contains the `update`, `botInfo`, and `telegram` for making arbitrary Bot API requests,
112as well as shorthand methods and getters.
113
114This is probably the class you'll be using the most.
115
116
117<!--
118Here is a list of
119
120#### Known middleware
121
122- [Internationalization](https://github.com/telegraf/telegraf-i18n)—simplifies selecting the right translation to use when responding to a user.
123- [Redis powered session](https://github.com/telegraf/telegraf-session-redis)—store session data using Redis.
124- [Local powered session (via lowdb)](https://github.com/RealSpeaker/telegraf-session-local)—store session data in a local file.
125- [Rate-limiting](https://github.com/telegraf/telegraf-ratelimit)—apply rate limitting to chats or users.
126- [Bottleneck powered throttling](https://github.com/KnightNiwrem/telegraf-throttler)—apply throttling to both incoming updates and outgoing API calls.
127- [Menus via inline keyboards](https://github.com/EdJoPaTo/telegraf-inline-menu)—simplify creating interfaces based on menus.
128- [Stateless Questions](https://github.com/EdJoPaTo/telegraf-stateless-question)—create stateless questions to Telegram users working in privacy mode.
129- [Natural language processing via wit.ai](https://github.com/telegraf/telegraf-wit)
130- [Natural language processing via recast.ai](https://github.com/telegraf/telegraf-recast)
131- [Multivariate and A/B testing](https://github.com/telegraf/telegraf-experiments)—add experiments to see how different versions of a feature are used.
132- [Powerfull bot stats via Mixpanel](https://github.com/telegraf/telegraf-mixpanel)
133- [statsd integration](https://github.com/telegraf/telegraf-statsd)
134- [and more...](https://www.npmjs.com/search?q=telegraf-)
135-->
136
137#### Shorthand methods
138
139```js
140import { Telegraf } from 'telegraf'
141
142const bot = new Telegraf(process.env.BOT_TOKEN)
143
144bot.command('quit', (ctx) => {
145 // Explicit usage
146 ctx.telegram.leaveChat(ctx.message.chat.id)
147
148 // Using context shortcut
149 ctx.leaveChat()
150})
151
152bot.on('text', (ctx) => {
153 // Explicit usage
154 ctx.telegram.sendMessage(ctx.message.chat.id, `Hello ${ctx.state.role}`)
155
156 // Using context shortcut
157 ctx.reply(`Hello ${ctx.state.role}`)
158})
159
160bot.on('callback_query', (ctx) => {
161 // Explicit usage
162 ctx.telegram.answerCbQuery(ctx.callbackQuery.id)
163
164 // Using context shortcut
165 ctx.answerCbQuery()
166})
167
168bot.on('inline_query', (ctx) => {
169 const result = []
170 // Explicit usage
171 ctx.telegram.answerInlineQuery(ctx.inlineQuery.id, result)
172
173 // Using context shortcut
174 ctx.answerInlineQuery(result)
175})
176
177bot.launch()
178
179// Enable graceful stop
180process.once('SIGINT', () => bot.stop('SIGINT'))
181process.once('SIGTERM', () => bot.stop('SIGTERM'))
182```
183
184## Production
185
186### Webhooks
187
188```js
189const { Telegraf } = require('telegraf')
190const fs = require('fs')
191require('dotenv')
192
193const bot = new Telegraf(process.env.BOT_TOKEN)
194
195// TLS options
196const tlsOptions = {
197 key: fs.readFileSync('server-key.pem'),
198 cert: fs.readFileSync('server-cert.pem'),
199 ca: [
200 // This is necessary only if the client uses a self-signed certificate.
201 fs.readFileSync('client-cert.pem')
202 ]
203}
204
205// Set telegram webhook
206// The second argument is necessary only if the client uses a self-signed
207// certificate. Including it for a verified certificate may cause things to break.
208bot.telegram.setWebhook('https://server.tld:8443/secret-path', {
209 source: 'server-cert.pem'
210})
211
212// Start https webhook
213bot.startWebhook('/secret-path', tlsOptions, 8443)
214
215// Http webhook, for nginx/heroku users.
216bot.startWebhook('/secret-path', null, 5000)
217```
218
219Use `webhookCallback()` if you want to attach Telegraf to an existing http server.
220
221<!-- global bot, tlsOptions -->
222
223```js
224require('http')
225 .createServer(bot.webhookCallback('/secret-path'))
226 .listen(3000)
227
228require('https')
229 .createServer(tlsOptions, bot.webhookCallback('/secret-path'))
230 .listen(8443)
231```
232
233- [AWS Lambda example integration](https://github.com/telegraf/telegraf/blob/develop/docs/examples/aws-lambda.js)
234- [`express` example integration](https://github.com/telegraf/telegraf/blob/develop/docs/examples/express-webhook-bot.ts)
235- [`fastify` example integration](https://github.com/telegraf/telegraf/blob/develop/docs/examples/fastify-webhook-bot.js)
236- [Google Cloud Functions example integration](https://github.com/telegraf/telegraf/blob/develop/docs/examples/google-cloud-function.ts)
237- [`koa` example integration](https://github.com/telegraf/telegraf/blob/develop/docs/examples/koa-webhook-bot.js)
238- Use [`bot.handleUpdate`](https://telegraf.js.org/classes/telegraf.html#handleupdate) to write new integrations
239
240### Error handling
241
242If middleware throws an error or times out, Telegraf calls `bot.handleError`. If it rethrows, update source closes, and then the error is printed to console and process [hopefully](https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode) terminates. If it does not rethrow, the error is swallowed.
243
244Default `bot.handleError` always rethrows. You can overwrite it using `bot.catch` if you need to.
245
246⚠️ Always rethrow `TimeoutError`!
247
248⚠️ Swallowing unknown errors might leave the process in invalid state!
249
250ℹ️ In production, `systemd` or [`pm2`](https://www.npmjs.com/package/pm2) can restart your bot if it exits for any reason.
251
252## Advanced topics
253
254### Working with files
255
256Supported file sources:
257
258- `Existing file_id`
259- `File path`
260- `Url`
261- `Buffer`
262- `ReadStream`
263
264Also, you can provide an optional name of a file as `filename` when you send the file.
265
266<!-- global bot, fs -->
267
268```js
269bot.on('message', (ctx) => {
270 // resend existing file by file_id
271 ctx.replyWithSticker('123123jkbhj6b')
272
273 // send file
274 ctx.replyWithVideo({ source: '/path/to/video.mp4' })
275
276 // send stream
277 ctx.replyWithVideo({
278 source: fs.createReadStream('/path/to/video.mp4')
279 })
280
281 // send buffer
282 ctx.replyWithVoice({
283 source: Buffer.alloc()
284 })
285
286 // send url via Telegram server
287 ctx.replyWithPhoto('https://picsum.photos/200/300/')
288
289 // pipe url content
290 ctx.replyWithPhoto({
291 url: 'https://picsum.photos/200/300/?random',
292 filename: 'kitten.jpg'
293 })
294})
295```
296
297### Middleware
298
299In addition to `ctx: Context`, each middleware receives `next: () => Promise<void>`.
300
301As in Koa and some other middleware-based libraries,
302`await next()` will call next middleware and wait for it to finish:
303
304```js
305import { Telegraf } from 'telegraf'
306
307const bot = new Telegraf(process.env.BOT_TOKEN)
308
309bot.use(async (ctx, next) => {
310 console.time(`Processing update ${ctx.update.update_id}`)
311 await next() // runs next middleware
312 // runs after next middleware finishes
313 console.timeEnd(`Processing update ${ctx.update.update_id}`)
314})
315
316bot.on('text', (ctx) => ctx.reply('Hello World'))
317bot.launch()
318
319// Enable graceful stop
320process.once('SIGINT', () => bot.stop('SIGINT'))
321process.once('SIGTERM', () => bot.stop('SIGTERM'))
322```
323
324With this simple ability, you can:
325- extract information from updates and then `await next()` to avoid disrupting other middleware,
326- like [`Composer`] and [`Router`], `await next()` for updates you don't wish to handle,
327- like [`session`] and [`Scenes`], [extend the context](#extending-context) by mutating `ctx` before `await next()`,
328- [intercept API calls](https://github.com/telegraf/telegraf/discussions/1267#discussioncomment-254525),
329- reuse [other people's code](https://www.npmjs.com/search?q=telegraf-),
330- do whatever **you** come up with!
331
332[`Composer`]: https://telegraf.js.org/classes/composer.html
333[`Context`]: https://telegraf.js.org/classes/context.html
334[`Router`]: https://telegraf.js.org/classes/router.html
335[`session`]: https://telegraf.js.org/modules.html#session
336[`Scenes`]: https://telegraf.js.org/modules/scenes.html
337[`Telegraf`]: https://telegraf.js.org/classes/telegraf.html
338
339### Usage with TypeScript
340
341Telegraf is written in TypeScript and therefore ships with declaration files for the entire library.
342Moreover, it includes types for the complete Telegram API via the [`typegram`](https://github.com/KnorpelSenf/typegram) package.
343While most types of Telegraf's API surface are self-explanatory, there's some notable things to keep in mind.
344
345#### Extending `Context`
346
347The exact shape of `ctx` can vary based on the installed middleware.
348Some custom middleware might register properties on the context object that Telegraf is not aware of.
349Consequently, you can change the type of `ctx` to fit your needs in order for you to have proper TypeScript types for your data.
350This is done through Generics:
351
352```ts
353import { Context, Telegraf } from 'telegraf'
354
355// Define your own context type
356interface MyContext extends Context {
357 myProp?: string
358 myOtherProp?: number
359}
360
361// Create your bot and tell it about your context type
362const bot = new Telegraf<MyContext>('SECRET TOKEN')
363
364// Register middleware and launch your bot as usual
365bot.use((ctx, next) => {
366 // Yay, `myProp` is now available here as `string | undefined`!
367 ctx.myProp = ctx.chat?.first_name?.toUpperCase()
368 return next()
369})
370// ...
371```