teh-bot 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1119 -436
  2. package/dist/index.mjs +4 -4
  3. package/package.json +2 -3
package/README.md CHANGED
@@ -4,27 +4,27 @@
4
4
  ![License](https://img.shields.io/badge/license-MIT-green)
5
5
  ![Node.js](https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen)
6
6
  ![npm](https://img.shields.io/badge/npm-teh--bot-red)
7
-
8
- A lightweight, high-performance, **zero-dependency** Telegram Bot API library for Node.js. Built with modern JavaScript standards supporting both **CommonJS** and **ES Modules (ESM)**, with full **TypeScript** support.
9
-
10
- ## Features
11
-
12
- - **Zero Dependencies** - No external packages required
13
- - ✅ **Dual Module Support** - Works with CommonJS (.cjs), ES Modules (.mjs), and TypeScript (.ts)
14
- - ✅ **Type-Safe** - Full TypeScript definitions included
15
- - ✅ **Lightweight** - Ultra-minimal footprint (~50KB)
16
- - ✅ **High-Performance** - Optimized for speed and efficiency
17
- - ✅ **Polling & Webhook** - Support for both update methods
18
- - ✅ **Event-Driven** - Chainable API with EventEmitter
19
- - ✅ **Middleware Support** - Extensible middleware system
20
- - ✅ **File Handling** - Easy file upload/download
21
- - ✅ **Media Support** - Photos, videos, audio, documents, stickers, animations, voice messages
7
+ ![Downloads](https://img.shields.io/badge/downloads-npm-brightgreen)
8
+ ![TypeScript](https://img.shields.io/badge/typescript-supported-blue)
9
+
10
+ A **zero-dependency**, lightweight, high-performance Telegram Bot API library for Node.js. Built with modern JavaScript standards supporting **CommonJS**, **ES Modules (ESM)**, and **TypeScript** with full type definitions.
11
+
12
+ ## Core Features
13
+
14
+ - ✅ **Zero Dependencies** - No external packages required, ultra-lightweight (~50KB)
15
+ - ✅ **Dual Module Format** - Works seamlessly with CommonJS (.cjs), ES Modules (.mjs), and TypeScript (.ts)
16
+ - ✅ **Full TypeScript Support** - Complete type definitions included (index.d.ts)
17
+ - ✅ **High Performance** - Optimized for speed with streaming file uploads
18
+ - ✅ **Event-Driven Architecture** - Built on Node.js EventEmitter with chainable API
19
+ - ✅ **Polling & Webhook Support** - Both long-polling and webhook update methods
20
+ - ✅ **Middleware System** - Extensible middleware chain for request processing
21
+ - ✅ **40+ API Methods** - Complete Telegram Bot API coverage
22
+ - ✅ **Context Helpers** - Easy ctx.send(), ctx.reply(), and media shortcuts
23
+ - ✅ **File Management** - Automatic file upload/download with streaming support
22
24
  - ✅ **Keyboard Builders** - Fluent API for inline and reply keyboards
23
- - ✅ **Full Telegram Bot API Support** - All official API methods implemented
24
- - ✅ **Chat Management** - Ban, restrict, promote members with ease
25
- - ✅ **Query Handling** - Inline queries, callback queries, poll answers
26
- - ✅ **Context Helpers** - Simple reply(), send(), and media methods
27
- - ✅ **Error Handling** - Comprehensive error information
25
+ - ✅ **Full Telegram Bot API Support** - All official methods with latest features
26
+ - ✅ **Payment Integration** - Invoices, shipping queries, pre-checkout queries
27
+ - ✅ **Advanced Features** - Reactions, stories, giveaways, business connections, web apps
28
28
 
29
29
  ## 📦 Installation
30
30
 
@@ -43,6 +43,11 @@ yarn add teh-bot
43
43
  pnpm add teh-bot
44
44
  ```
45
45
 
46
+ ### Using bun
47
+ ```bash
48
+ bun add teh-bot
49
+ ```
50
+
46
51
  ## 🚀 Quick Start
47
52
 
48
53
  ### CommonJS (.js)
@@ -59,11 +64,16 @@ bot.command('/start', async (ctx) => {
59
64
 
60
65
  bot.on('text', async (message, ctx) => {
61
66
  console.log('Message:', message.text);
67
+ await ctx.reply(`You said: ${message.text}`);
62
68
  });
63
69
 
64
70
  bot.on('polling_start', () => {
65
71
  console.log('✅ Bot started polling');
66
72
  });
73
+
74
+ bot.on('polling_error', (error) => {
75
+ console.error('❌ Polling error:', error);
76
+ });
67
77
  ```
68
78
 
69
79
  ### ES Modules (.mjs)
@@ -72,6 +82,8 @@ import TelegramBot from 'teh-bot';
72
82
 
73
83
  const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
74
84
  polling: true,
85
+ pollingInterval: 2000,
86
+ pollingTimeout: 60,
75
87
  });
76
88
 
77
89
  bot.command('/start', async (ctx) => {
@@ -81,10 +93,6 @@ bot.command('/start', async (ctx) => {
81
93
  bot.on('text', async (message, ctx) => {
82
94
  console.log('Message:', message.text);
83
95
  });
84
-
85
- bot.on('polling_start', () => {
86
- console.log('✅ Bot started polling');
87
- });
88
96
  ```
89
97
 
90
98
  ### TypeScript (.ts)
@@ -101,663 +109,1342 @@ bot.command('/start', async (ctx: Context) => {
101
109
 
102
110
  bot.on('text', async (message, ctx: Context) => {
103
111
  console.log('Message:', message.text);
104
- });
105
-
106
- bot.on('polling_start', () => {
107
- console.log('✅ Bot started polling');
112
+ await ctx.reply(`You said: ${message.text}`);
108
113
  });
109
114
  ```
110
115
 
111
116
  ## ⚙️ Configuration
112
117
 
113
- ### BotOptions
118
+ ### Bot Initialization Options
119
+
114
120
  ```javascript
115
121
  const bot = new TelegramBot(token, {
116
- // Polling
117
- polling: true, // Enable polling (default: false)
118
- pollingInterval: 1000, // Polling interval in ms (default: 1000)
119
- pollingTimeout: 30, // Long polling timeout (default: 30)
122
+ // === Polling Configuration ===
123
+ polling: true, // Enable polling mode (default: false)
124
+ pollingInterval: 1000, // Interval between polls in ms (default: 1000)
125
+ pollingTimeout: 30, // Long polling timeout in seconds (default: 30)
120
126
 
121
- // Webhook
122
- webhook: false, // Enable webhook (default: false)
127
+ // === Webhook Configuration ===
128
+ webhook: false, // Enable webhook mode (default: false)
123
129
  webhookPort: 3000, // Webhook server port (default: 3000)
124
- webhookPath: '/webhook', // Webhook path (default: '/webhook')
130
+ webhookPath: '/webhook', // Webhook endpoint path (default: '/webhook')
125
131
 
126
- // General
127
- requestTimeout: 30000, // Request timeout in ms (default: 30000)
128
- maxConnections: 40, // Max concurrent connections (default: 40)
129
- allowedUpdates: [], // Array of allowed update types (default: [])
130
- baseApiUrl: 'https://api.telegram.org', // Custom API URL (default)
132
+ // === Request Configuration ===
133
+ requestTimeout: 30000, // HTTP request timeout in ms (default: 30000)
134
+ maxConnections: 40, // Max concurrent API connections (default: 40)
135
+
136
+ // === Update Filtering ===
137
+ allowedUpdates: [ // Filter update types to receive
138
+ 'message',
139
+ 'callback_query',
140
+ 'inline_query'
141
+ ],
142
+
143
+ // === Custom API URL ===
144
+ baseApiUrl: 'https://api.telegram.org', // Custom Telegram API URL
131
145
  });
132
146
  ```
133
147
 
134
- ## 📚 API Reference
148
+ ---
149
+
150
+ ## 📚 Complete API Reference
135
151
 
136
- ### Core Methods
152
+ ### 1. Bot Management
137
153
 
138
- #### Sending Messages
154
+ #### Get Bot Information
155
+ ```javascript
156
+ // Get your bot's information
157
+ const me = await bot.getMe();
158
+ console.log(`Bot name: ${me.first_name}`);
159
+ console.log(`Bot username: ${me.username}`);
160
+ console.log(`Is bot: ${me.is_bot}`);
161
+ ```
139
162
 
163
+ #### Webhook Management
140
164
  ```javascript
141
- // Send text message
165
+ // Set webhook (replace polling with webhook)
166
+ await bot.setWebhook('https://example.com/webhook', {
167
+ certificate: fs.createReadStream('./cert.pem'),
168
+ max_connections: 40,
169
+ allowed_updates: ['message', 'callback_query']
170
+ });
171
+
172
+ // Get webhook info
173
+ const webhookInfo = await bot.getWebhookInfo();
174
+ console.log('Webhook URL:', webhookInfo.url);
175
+ console.log('Pending updates:', webhookInfo.pending_update_count);
176
+
177
+ // Delete webhook (revert to polling)
178
+ await bot.deleteWebhook();
179
+ ```
180
+
181
+ ---
182
+
183
+ ### 2. Message Sending
184
+
185
+ #### Text Messages
186
+ ```javascript
187
+ // Simple text message
142
188
  await bot.sendMessage(chatId, 'Hello!');
143
189
 
144
- // Send text with options
145
- await bot.sendMessage(chatId, 'Hello!', {
146
- parse_mode: 'HTML',
147
- reply_markup: keyboard,
190
+ // With formatting
191
+ await bot.sendMessage(chatId, '<b>Bold</b> <i>Italic</i> <code>Code</code>', {
192
+ parse_mode: 'HTML'
193
+ });
194
+
195
+ // With markdown
196
+ await bot.sendMessage(chatId, '*Bold* _Italic_ `Code`', {
197
+ parse_mode: 'Markdown'
198
+ });
199
+
200
+ // With link preview options
201
+ await bot.sendMessage(chatId, 'Check this out: https://example.com', {
202
+ link_preview_options: {
203
+ is_disabled: false,
204
+ prefer_small_media: true,
205
+ show_above_text: false
206
+ }
207
+ });
208
+
209
+ // With entities
210
+ await bot.sendMessage(chatId, 'Custom #hashtag @mention', {
211
+ entities: [
212
+ { type: 'hashtag', offset: 7, length: 8 },
213
+ { type: 'mention', offset: 16, length: 8 }
214
+ ]
215
+ });
216
+ ```
217
+
218
+ #### Media Messages
219
+
220
+ **Photos**
221
+ ```javascript
222
+ // Photo from URL
223
+ await bot.sendPhoto(chatId, 'https://example.com/photo.jpg', {
224
+ caption: 'Beautiful photo!',
225
+ parse_mode: 'HTML'
226
+ });
227
+
228
+ // Photo from file path
229
+ await bot.sendPhoto(chatId, './photo.jpg', {
230
+ caption: 'Local photo'
231
+ });
232
+
233
+ // Photo from Buffer
234
+ const photoBuffer = await fs.promises.readFile('./photo.jpg');
235
+ await bot.sendPhoto(chatId, photoBuffer, {
236
+ caption: 'From buffer'
237
+ });
238
+
239
+ // Photo from file ID (reuse previous upload)
240
+ await bot.sendPhoto(chatId, 'AgAC_file_id_string', {
241
+ caption: 'Cached photo'
242
+ });
243
+ ```
244
+
245
+ **Videos**
246
+ ```javascript
247
+ // Video with thumbnail
248
+ await bot.sendVideo(chatId, 'https://example.com/video.mp4', {
249
+ caption: 'Watch this video!',
250
+ duration: 120,
251
+ width: 1280,
252
+ height: 720,
253
+ thumbnail: './thumb.jpg',
254
+ parse_mode: 'HTML'
255
+ });
256
+
257
+ // Local video file
258
+ await bot.sendVideo(chatId, './video.mp4', {
259
+ caption: 'Local video',
260
+ supports_streaming: true
261
+ });
262
+ ```
263
+
264
+ **Audio**
265
+ ```javascript
266
+ // Audio file
267
+ await bot.sendAudio(chatId, 'https://example.com/song.mp3', {
268
+ title: 'Song Title',
269
+ performer: 'Artist Name',
270
+ duration: 180,
271
+ thumbnail: './album.jpg'
272
+ });
273
+
274
+ // Local audio
275
+ await bot.sendAudio(chatId, './music.mp3', {
276
+ caption: 'Great song!'
277
+ });
278
+ ```
279
+
280
+ **Documents**
281
+ ```javascript
282
+ // PDF document
283
+ await bot.sendDocument(chatId, 'https://example.com/file.pdf', {
284
+ caption: 'Important document',
285
+ parse_mode: 'HTML'
148
286
  });
149
287
 
150
- // Send media
151
- await bot.sendPhoto(chatId, photoBuffer, { caption: 'Photo!' });
152
- await bot.sendVideo(chatId, videoPath);
153
- await bot.sendAudio(chatId, audioBuffer);
154
- await bot.sendDocument(chatId, '/path/to/file.pdf');
155
- await bot.sendAnimation(chatId, animationUrl);
156
- await bot.sendVoice(chatId, voiceBuffer);
157
- await bot.sendVideoNote(chatId, videoNoteBuffer);
158
- await bot.sendSticker(chatId, stickerFileId);
288
+ // Local file
289
+ await bot.sendDocument(chatId, './report.pdf', {
290
+ caption: 'Report.pdf'
291
+ });
159
292
 
160
- // Send location
161
- await bot.sendLocation(chatId, latitude, longitude);
293
+ // Any file type
294
+ await bot.sendDocument(chatId, './archive.zip', {
295
+ caption: 'Compressed files'
296
+ });
297
+ ```
162
298
 
163
- // Send venue
164
- await bot.sendVenue(chatId, lat, lon, 'Title', 'Address');
299
+ **Animations (GIF)**
300
+ ```javascript
301
+ await bot.sendAnimation(chatId, 'https://example.com/animation.gif', {
302
+ caption: 'Cool animation!',
303
+ duration: 5,
304
+ width: 400,
305
+ height: 400
306
+ });
165
307
 
166
- // Send contact
167
- await bot.sendContact(chatId, '+1234567890', 'John');
308
+ await bot.sendAnimation(chatId, './animation.gif', {
309
+ thumbnail: './thumb.jpg'
310
+ });
311
+ ```
168
312
 
169
- // Send poll
170
- await bot.sendPoll(chatId, 'Question?', ['Option 1', 'Option 2', 'Option 3']);
313
+ **Voice Messages**
314
+ ```javascript
315
+ // Voice message (OGG format)
316
+ await bot.sendVoice(chatId, './voice.ogg', {
317
+ caption: 'Voice message',
318
+ duration: 30
319
+ });
171
320
 
172
- // Send dice/game
173
- await bot.sendDice(chatId);
321
+ // From URL
322
+ await bot.sendVoice(chatId, 'https://example.com/voice.ogg', {
323
+ duration: 45
324
+ });
325
+ ```
174
326
 
175
- // Send chat action (e.g., typing)
327
+ **Video Notes (Circular Videos)**
328
+ ```javascript
329
+ // Video note - must be square and short
330
+ await bot.sendVideoNote(chatId, './video_note.mp4', {
331
+ duration: 60,
332
+ length: 360 // width/height
333
+ });
334
+
335
+ // From URL
336
+ await bot.sendVideoNote(chatId, 'https://example.com/note.mp4');
337
+ ```
338
+
339
+ **Stickers**
340
+ ```javascript
341
+ // Send sticker by file ID
342
+ await bot.sendSticker(chatId, 'sticker_file_id');
343
+
344
+ // Send from URL
345
+ await bot.sendSticker(chatId, 'https://example.com/sticker.webp');
346
+
347
+ // Send from local file
348
+ await bot.sendSticker(chatId, './sticker.tgs');
349
+ ```
350
+
351
+ ---
352
+
353
+ ### 3. Location & Venue
354
+
355
+ #### Send Location
356
+ ```javascript
357
+ // Simple location
358
+ await bot.sendLocation(chatId, 40.7128, -74.0060, {
359
+ heading: 45, // Direction (0-360 degrees)
360
+ horizontal_accuracy: 50, // Accuracy in meters
361
+ proximity_alert_radius: 200 // Proximity alert distance
362
+ });
363
+ ```
364
+
365
+ #### Send Venue
366
+ ```javascript
367
+ await bot.sendVenue(chatId, 40.7128, -74.0060, 'Statue of Liberty', 'Liberty Island', {
368
+ foursquare_id: 'venue_id',
369
+ foursquare_type: 'landmark'
370
+ });
371
+ ```
372
+
373
+ #### Send Contact
374
+ ```javascript
375
+ await bot.sendContact(chatId, '+1-555-0100', 'John Doe', {
376
+ last_name: 'Doe',
377
+ vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL:+1-555-0100\nEND:VCARD'
378
+ });
379
+ ```
380
+
381
+ ---
382
+
383
+ ### 4. Polls & Quizzes
384
+
385
+ #### Create Poll
386
+ ```javascript
387
+ // Simple poll
388
+ await bot.sendPoll(chatId, 'Do you like Telegram?', ['Yes', 'No', 'Maybe'], {
389
+ is_anonymous: true,
390
+ allows_multiple_answers: true,
391
+ explanation: 'Most people like Telegram!',
392
+ open_period: 600 // Auto-closes after 10 minutes
393
+ });
394
+
395
+ // Quiz mode (single correct answer)
396
+ await bot.sendPoll(chatId, 'What is 2+2?', ['3', '4', '5'], {
397
+ type: 'quiz',
398
+ correct_option_id: 1, // Option index (0-based)
399
+ explanation: 'Simple math!',
400
+ explanation_parse_mode: 'HTML'
401
+ });
402
+ ```
403
+
404
+ #### Send Dice/Game
405
+ ```javascript
406
+ // Dice emoji - values 1-6
407
+ await bot.sendDice(chatId, {
408
+ emoji: '🎲' // or '🎯', '🏀', '⚽', '🎳', '🎮'
409
+ });
410
+ ```
411
+
412
+ ---
413
+
414
+ ### 5. Chat Actions
415
+
416
+ Send chat actions to show user what the bot is doing:
417
+
418
+ ```javascript
419
+ // Typing indicator
176
420
  await bot.sendChatAction(chatId, 'typing');
421
+
422
+ // Photo upload
423
+ await bot.sendChatAction(chatId, 'upload_photo');
424
+
425
+ // Video upload
426
+ await bot.sendChatAction(chatId, 'upload_video');
427
+
428
+ // Audio upload
429
+ await bot.sendChatAction(chatId, 'upload_audio');
430
+
431
+ // Document upload
432
+ await bot.sendChatAction(chatId, 'upload_document');
433
+
434
+ // Finding location
435
+ await bot.sendChatAction(chatId, 'find_location');
436
+
437
+ // Recording voice
438
+ await bot.sendChatAction(chatId, 'record_voice');
439
+
440
+ // Recording video
441
+ await bot.sendChatAction(chatId, 'record_video');
442
+
443
+ // Recording video note
444
+ await bot.sendChatAction(chatId, 'record_video_note');
445
+
446
+ // Choosing sticker
447
+ await bot.sendChatAction(chatId, 'choose_sticker');
177
448
  ```
178
449
 
179
- #### Message Management
450
+ ---
451
+
452
+ ### 6. Message Management
180
453
 
454
+ #### Forward Message
181
455
  ```javascript
182
- // Edit message
456
+ // Forward message from another chat
457
+ await bot.forwardMessage(chatId, sourceChatId, messageId, {
458
+ disable_notification: false
459
+ });
460
+ ```
461
+
462
+ #### Copy Message
463
+ ```javascript
464
+ // Copy message (creates new message, doesn't forward)
465
+ await bot.copyMessage(chatId, sourceChatId, messageId, {
466
+ caption: 'Optional new caption',
467
+ parse_mode: 'HTML'
468
+ });
469
+ ```
470
+
471
+ #### Edit Message Text
472
+ ```javascript
473
+ // Edit sent message
183
474
  await bot.editMessageText('New text', {
184
475
  chat_id: chatId,
185
476
  message_id: messageId,
186
477
  parse_mode: 'HTML',
478
+ link_preview_options: {
479
+ is_disabled: true
480
+ }
481
+ });
482
+
483
+ // Edit inline message (from inline query)
484
+ await bot.editMessageText('Updated text', {
485
+ inline_message_id: 'inline_id_12345',
486
+ parse_mode: 'HTML'
187
487
  });
488
+ ```
188
489
 
189
- // Edit caption
490
+ #### Edit Message Caption
491
+ ```javascript
492
+ // Edit media caption
190
493
  await bot.editMessageCaption({
191
494
  chat_id: chatId,
192
495
  message_id: messageId,
193
496
  caption: 'New caption',
497
+ parse_mode: 'HTML'
194
498
  });
499
+ ```
500
+
501
+ #### Edit Message Keyboard
502
+ ```javascript
503
+ // Update inline keyboard
504
+ const newKeyboard = TelegramBot.InlineKeyboard()
505
+ .text('New Button', 'new_callback_data')
506
+ .row()
507
+ .url('Google', 'https://google.com')
508
+ .build();
195
509
 
196
- // Edit reply markup
197
510
  await bot.editMessageReplyMarkup({
198
511
  chat_id: chatId,
199
512
  message_id: messageId,
200
- reply_markup: newKeyboard,
513
+ reply_markup: newKeyboard
201
514
  });
515
+ ```
202
516
 
203
- // Delete message
517
+ #### Delete Message
518
+ ```javascript
519
+ // Delete a message
204
520
  await bot.deleteMessage(chatId, messageId);
521
+ ```
522
+
523
+ ---
205
524
 
206
- // Forward message
207
- await bot.forwardMessage(chatId, fromChatId, messageId);
525
+ ### 7. Payments
208
526
 
209
- // Copy message
210
- await bot.copyMessage(chatId, fromChatId, messageId);
527
+ #### Send Invoice
528
+ ```javascript
529
+ // Create product invoice
530
+ await bot.sendInvoice(chatId, {
531
+ title: 'Telegram Premium',
532
+ description: 'Upgrade to Telegram Premium for more features!',
533
+ payload: 'premium_subscription_12345',
534
+ provider_token: 'your_stripe_token',
535
+ currency: 'USD',
536
+ prices: [
537
+ { label: 'Premium 1 Month', amount: 999 }, // Amount in cents
538
+ { label: 'Premium 3 Months', amount: 2499 }
539
+ ],
540
+ photo_url: 'https://example.com/premium.jpg',
541
+ photo_width: 800,
542
+ photo_height: 600,
543
+ need_email: true,
544
+ need_phone_number: true,
545
+ send_phone_number_to_provider: true
546
+ });
211
547
  ```
212
548
 
213
- #### Chat Management
549
+ #### Answer Shipping Query
550
+ ```javascript
551
+ bot.on('shipping_query', async (query, ctx) => {
552
+ const shippingOptions = [
553
+ {
554
+ id: 'standard',
555
+ title: 'Standard Delivery',
556
+ price_list: [
557
+ { label: 'Shipping', amount: 500 } // 5.00 USD
558
+ ]
559
+ },
560
+ {
561
+ id: 'express',
562
+ title: 'Express Delivery',
563
+ price_list: [
564
+ { label: 'Shipping', amount: 1500 } // 15.00 USD
565
+ ]
566
+ }
567
+ ];
568
+
569
+ // Check if shipping address is valid
570
+ const isValid = query.shipping_address.country_code === 'US';
571
+
572
+ if (isValid) {
573
+ await bot.answerShippingQuery(query.id, true, {
574
+ shipping_options: shippingOptions
575
+ });
576
+ } else {
577
+ await bot.answerShippingQuery(query.id, false, {
578
+ error_message: 'We only ship to the United States'
579
+ });
580
+ }
581
+ });
582
+ ```
214
583
 
584
+ #### Answer Pre-Checkout Query
215
585
  ```javascript
216
- // Get chat info
217
- const chat = await bot.getChat(chatId);
586
+ bot.on('pre_checkout_query', async (query, ctx) => {
587
+ // Validate order before payment
588
+ const isValid = validateOrder(query);
589
+
590
+ if (isValid) {
591
+ await bot.answerPreCheckoutQuery(query.id, true);
592
+ } else {
593
+ await bot.answerPreCheckoutQuery(query.id, false, {
594
+ error_message: 'Item out of stock'
595
+ });
596
+ }
597
+ });
598
+ ```
218
599
 
219
- // Get chat administrators
220
- const admins = await bot.getChatAdministrators(chatId);
600
+ #### Handle Successful Payment
601
+ ```javascript
602
+ bot.on('successful_payment', async (payment, ctx) => {
603
+ console.log('Payment received!');
604
+ console.log('Amount:', payment.total_amount);
605
+ console.log('Currency:', payment.currency);
606
+ console.log('Order ID:', payment.invoice_payload);
607
+
608
+ await ctx.send('✅ Payment successful! Thank you for your purchase!');
609
+ });
610
+ ```
611
+
612
+ ---
613
+
614
+ ### 8. Chat Management
615
+
616
+ #### Get Chat Information
617
+ ```javascript
618
+ // Get chat details
619
+ const chat = await bot.getChat(chatId);
620
+ console.log('Chat:', chat.title || chat.first_name);
621
+ console.log('Members:', chat.type);
622
+ console.log('Bio:', chat.bio);
221
623
 
222
624
  // Get chat member count
223
625
  const count = await bot.getChatMemberCount(chatId);
626
+ console.log('Members:', count);
224
627
 
225
- // Get specific chat member
628
+ // Get specific member info
226
629
  const member = await bot.getChatMember(chatId, userId);
630
+ console.log('Member status:', member.status);
631
+ console.log('Member:', member.user.first_name);
227
632
 
633
+ // Get all administrators
634
+ const admins = await bot.getChatAdministrators(chatId);
635
+ admins.forEach(admin => {
636
+ console.log(`${admin.user.first_name} - ${admin.status}`);
637
+ });
638
+ ```
639
+
640
+ #### Manage Chat Settings
641
+ ```javascript
228
642
  // Set chat title
229
- await bot.setChatTitle(chatId, 'New Title');
643
+ await bot.setChatTitle(chatId, 'New Group Name');
230
644
 
231
645
  // Set chat description
232
- await bot.setChatDescription(chatId, 'New Description');
646
+ await bot.setChatDescription(chatId, 'Group description and rules...');
233
647
 
234
- // Pin message
235
- await bot.pinChatMessage(chatId, messageId);
648
+ // Set chat photo
649
+ await bot.setChatPhoto(chatId, './group_photo.jpg');
236
650
 
237
- // Unpin message
238
- await bot.unpinChatMessage(chatId);
651
+ // Delete chat photo
652
+ await bot.deleteChatPhoto(chatId);
239
653
 
240
- // Unpin all messages
241
- await bot.unpinAllChatMessages(chatId);
242
-
243
- // Leave chat
244
- await bot.leaveChat(chatId);
654
+ // Get chat member info
655
+ const member = await bot.getChatMember(chatId, userId);
245
656
  ```
246
657
 
247
- #### Member Management
248
-
249
- ```javascript
250
- // Ban member
251
- await bot.banChatMember(chatId, userId);
658
+ ---
252
659
 
253
- // Unban member
254
- await bot.unbanChatMember(chatId, userId);
660
+ ### 9. Member Management
255
661
 
256
- // Restrict member
662
+ #### Restrict/Promote Members
663
+ ```javascript
664
+ // Restrict member (disable all permissions)
257
665
  await bot.restrictChatMember(chatId, userId, {
258
666
  can_send_messages: false,
259
667
  can_send_media_messages: false,
668
+ can_send_polls: false,
669
+ can_add_web_page_previews: false,
670
+ until_date: Math.floor(Date.now() / 1000) + 86400 // 24 hours
671
+ });
672
+
673
+ // Partially restrict (allow only text)
674
+ await bot.restrictChatMember(chatId, userId, {
675
+ can_send_messages: true,
676
+ can_send_media_messages: false,
677
+ can_send_polls: false,
678
+ can_add_web_page_previews: false
260
679
  });
261
680
 
262
- // Promote member
681
+ // Promote member to admin
263
682
  await bot.promoteChatMember(chatId, userId, {
264
- can_manage_chat: true,
683
+ can_change_info: true,
265
684
  can_delete_messages: true,
685
+ can_restrict_members: true,
686
+ can_pin_messages: true,
687
+ can_manage_topics: true,
688
+ is_anonymous: false
266
689
  });
690
+
691
+ // Set custom admin title
692
+ await bot.setChatAdministratorCustomTitle(chatId, userId, 'Cool Admin');
267
693
  ```
268
694
 
269
- #### File Management
695
+ #### Ban/Unban Members
696
+ ```javascript
697
+ // Ban member
698
+ await bot.banChatMember(chatId, userId, {
699
+ until_date: Math.floor(Date.now() / 1000) + 604800, // 7 days
700
+ revoke_messages: true // Delete all their messages
701
+ });
270
702
 
703
+ // Permanent ban
704
+ await bot.banChatMember(chatId, userId, {
705
+ revoke_messages: true
706
+ });
707
+
708
+ // Unban member
709
+ await bot.unbanChatMember(chatId, userId, {
710
+ only_if_banned: true
711
+ });
712
+ ```
713
+
714
+ #### Other Member Operations
271
715
  ```javascript
272
- // Get file info
273
- const file = await bot.getFile(fileId);
716
+ // Approve join request
717
+ await bot.approveChatJoinRequest(chatId, userId);
718
+
719
+ // Decline join request
720
+ await bot.declineChatJoinRequest(chatId, userId);
274
721
 
275
- // Download file
276
- await bot.downloadFile(fileId, '/path/to/save/file.jpg');
722
+ // Leave chat
723
+ await bot.leaveChat(chatId);
277
724
  ```
278
725
 
279
- #### Query Handling
726
+ ---
727
+
728
+ ### 10. Message Pinning
280
729
 
281
730
  ```javascript
282
- // Answer callback query
283
- await bot.answerCallbackQuery(callbackQueryId, {
284
- text: 'Button clicked!',
285
- show_alert: false,
731
+ // Pin message (all members see it)
732
+ await bot.pinChatMessage(chatId, messageId, {
733
+ disable_notification: false // Notify members
734
+ });
735
+
736
+ // Unpin specific message
737
+ await bot.unpinChatMessage(chatId, {
738
+ message_id: messageId
286
739
  });
287
740
 
288
- // Answer inline query
289
- await bot.answerInlineQuery(inlineQueryId, [
290
- {
291
- type: 'article',
292
- id: '1',
293
- title: 'Result',
294
- input_message_content: { message_text: 'Text' },
295
- },
296
- ]);
741
+ // Unpin all messages
742
+ await bot.unpinAllChatMessages(chatId);
297
743
  ```
298
744
 
299
- #### Bot Methods
745
+ ---
746
+
747
+ ### 11. Queries & Responses
300
748
 
749
+ #### Callback Query
301
750
  ```javascript
302
- // Get bot info
303
- const me = await bot.getMe();
751
+ bot.on('callback_query', async (query, ctx) => {
752
+ console.log('Button clicked:', query.data);
304
753
 
305
- // Get updates
306
- const updates = await bot.getUpdates();
754
+ // Answer callback (shows notification or toast)
755
+ await ctx.answerCallbackQuery({
756
+ text: 'Button was clicked!',
757
+ show_alert: false // Toast notification
758
+ });
307
759
 
308
- // Set webhook
309
- await bot.setWebhook('https://example.com/webhook');
760
+ // Edit message
761
+ await ctx.editMessageText('You clicked the button!');
762
+ });
763
+ ```
310
764
 
311
- // Delete webhook
312
- await bot.deleteWebhook();
765
+ #### Inline Query
766
+ ```javascript
767
+ bot.on('inline_query', async (query, ctx) => {
768
+ const results = [
769
+ {
770
+ type: 'article',
771
+ id: '1',
772
+ title: 'Result 1',
773
+ description: 'First search result',
774
+ input_message_content: {
775
+ message_text: 'Result 1 content'
776
+ }
777
+ },
778
+ {
779
+ type: 'photo',
780
+ id: '2',
781
+ photo_url: 'https://example.com/photo.jpg',
782
+ thumbnail_url: 'https://example.com/thumb.jpg'
783
+ }
784
+ ];
785
+
786
+ await bot.answerInlineQuery(query.id, results, {
787
+ cache_time: 300, // Cache 5 minutes
788
+ is_personal: false
789
+ });
790
+ });
791
+ ```
313
792
 
314
- // Get webhook info
315
- const info = await bot.getWebhookInfo();
793
+ #### Chosen Inline Result
794
+ ```javascript
795
+ bot.on('chosen_inline_result', async (result, ctx) => {
796
+ console.log('User selected inline result:', result.result_id);
797
+ console.log('Query was:', result.query);
798
+ });
316
799
  ```
317
800
 
318
- ### Context Methods (Available in Command Handlers & Events)
801
+ ---
319
802
 
320
- The `ctx` object provides convenient shorthand methods:
803
+ ### 12. File Management
321
804
 
805
+ #### Download File
322
806
  ```javascript
323
- bot.command('/start', async (ctx) => {
324
- // Send message
325
- await ctx.send('Hello!');
326
-
327
- // Reply to message
328
- await ctx.reply('Reply!');
329
-
330
- // Reply with media
331
- await ctx.replyWithPhoto(photoBuffer, { caption: 'Photo!' });
332
- await ctx.replyWithVideo(videoUrl);
333
- await ctx.replyWithAudio(audioBuffer);
334
- await ctx.replyWithDocument(docPath);
335
-
336
- // Answer callback query
337
- await ctx.answerCallbackQuery({ text: 'Done!' });
338
-
339
- // Edit message text
340
- await ctx.editMessageText('New text', {
341
- parse_mode: 'HTML',
342
- });
343
-
344
- // Access update data
345
- console.log(ctx.message?.text);
346
- console.log(ctx.chat?.id);
347
- console.log(ctx.from?.username);
348
- console.log(ctx.callbackQuery?.data);
349
- });
807
+ // Get file info
808
+ const file = await bot.getFile('file_id_from_message');
809
+ console.log('File path:', file.file_path);
810
+ console.log('File size:', file.file_size);
811
+
812
+ // Download file to disk
813
+ const destination = './downloaded_file.jpg';
814
+ await bot.downloadFile('file_id', destination);
815
+ console.log('Downloaded to:', destination);
350
816
  ```
351
817
 
352
- ## ⌨️ Keyboard Builders
818
+ #### Upload File
819
+ ```javascript
820
+ // Upload photo from local file
821
+ await bot.sendPhoto(chatId, './photo.jpg');
822
+
823
+ // Upload from URL
824
+ await bot.sendPhoto(chatId, 'https://example.com/photo.jpg');
353
825
 
354
- ### Inline Keyboard
826
+ // Upload from Buffer
827
+ const buffer = await fs.promises.readFile('./photo.jpg');
828
+ await bot.sendPhoto(chatId, buffer);
829
+ ```
355
830
 
831
+ ---
832
+
833
+ ### 13. Keyboard Builders
834
+
835
+ #### Inline Keyboard (Buttons with Actions)
356
836
  ```javascript
837
+ // Create inline keyboard
357
838
  const keyboard = TelegramBot.InlineKeyboard()
358
- .text('Button 1', 'btn1')
359
- .text('Button 2', 'btn2')
360
- .row()
839
+ .text('Button 1', 'callback_data_1')
840
+ .text('Button 2', 'callback_data_2')
841
+ .row() // New row
842
+ .url('Visit Website', 'https://example.com')
361
843
  .url('Google', 'https://google.com')
362
- .url('GitHub', 'https://github.com')
363
844
  .row()
364
- .switchInline('Search', 'query')
845
+ .text('Delete', 'delete_action')
365
846
  .build();
366
847
 
367
- await bot.sendMessage(chatId, 'Choose:', { reply_markup: keyboard });
848
+ await bot.sendMessage(chatId, 'Choose an action:', {
849
+ reply_markup: keyboard
850
+ });
368
851
  ```
369
852
 
370
- ### Reply Keyboard
371
-
853
+ #### Reply Keyboard (Regular Buttons)
372
854
  ```javascript
855
+ // Create reply keyboard
373
856
  const keyboard = TelegramBot.ReplyKeyboard()
374
- .text('Option 1')
375
- .text('Option 2')
857
+ .text('Button 1')
858
+ .text('Button 2')
376
859
  .row()
377
- .requestContact('Share Contact')
378
- .requestLocation('Share Location')
379
- .resize(true)
380
- .oneTime(true)
860
+ .text('Button 3')
861
+ .oneTime() // Disappears after use
381
862
  .build();
382
863
 
383
- await bot.sendMessage(chatId, 'Choose:', { reply_markup: keyboard });
864
+ await bot.sendMessage(chatId, 'Select an option:', {
865
+ reply_markup: keyboard
866
+ });
384
867
  ```
385
868
 
386
- ### Remove Keyboard
387
-
869
+ #### Remove Keyboard
388
870
  ```javascript
389
- await bot.sendMessage(chatId, 'Keyboard removed', {
390
- reply_markup: TelegramBot.RemoveKeyboard(),
871
+ // Hide keyboard
872
+ await bot.sendMessage(chatId, 'Keyboard hidden', {
873
+ reply_markup: TelegramBot.RemoveKeyboard()
391
874
  });
392
875
  ```
393
876
 
394
- ### Force Reply
395
-
877
+ #### Force Reply
396
878
  ```javascript
397
- await bot.sendMessage(chatId, 'Reply to me:', {
398
- reply_markup: TelegramBot.ForceReply(),
879
+ // Force user to reply to this message
880
+ await bot.sendMessage(chatId, 'Please reply to this message:', {
881
+ reply_markup: TelegramBot.ForceReply()
399
882
  });
400
883
  ```
401
884
 
402
- ## 🎯 Event Handling
885
+ ---
886
+
887
+ ### 14. Context Helpers
403
888
 
404
- ### Message Events
889
+ Context object provides convenient shortcuts:
405
890
 
406
891
  ```javascript
407
- // All messages
408
- bot.on('message', (message, ctx) => {});
892
+ bot.on('text', async (message, ctx) => {
893
+ // Send message to same chat
894
+ await ctx.send('Hello!');
409
895
 
410
- // Text messages
411
- bot.on('text', (message, ctx) => {});
896
+ // Reply to message (with reply_to_message_id)
897
+ await ctx.reply('Thanks for your message!');
412
898
 
413
- // Photo messages
414
- bot.on('photo', (message, ctx) => {});
899
+ // Send photo in reply
900
+ await ctx.replyWithPhoto('./photo.jpg', {
901
+ caption: 'Photo reply'
902
+ });
415
903
 
416
- // Video messages
417
- bot.on('video', (message, ctx) => {});
904
+ // Send video in reply
905
+ await ctx.replyWithVideo('./video.mp4', {
906
+ caption: 'Video reply'
907
+ });
418
908
 
419
- // Audio messages
420
- bot.on('audio', (message, ctx) => {});
909
+ // Send audio
910
+ await ctx.replyWithAudio('./song.mp3', {
911
+ title: 'Song'
912
+ });
421
913
 
422
- // Document messages
423
- bot.on('document', (message, ctx) => {});
914
+ // Send document
915
+ await ctx.replyWithDocument('./file.pdf');
424
916
 
425
- // Voice messages
426
- bot.on('voice', (message, ctx) => {});
917
+ // Edit callback query message
918
+ if (ctx.callbackQuery) {
919
+ await ctx.editMessageText('Updated message');
920
+ await ctx.answerCallbackQuery({
921
+ text: 'Updated!',
922
+ show_alert: false
923
+ });
924
+ }
925
+ });
926
+ ```
427
927
 
428
- // Sticker messages
429
- bot.on('sticker', (message, ctx) => {});
928
+ ---
430
929
 
431
- // Location messages
432
- bot.on('location', (message, ctx) => {});
930
+ ## 🎯 Event Listeners
433
931
 
434
- // Contact messages
435
- bot.on('contact', (message, ctx) => {});
932
+ Listen to different types of updates:
436
933
 
437
- // Edited messages
438
- bot.on('edited_message', (message, ctx) => {});
934
+ ```javascript
935
+ // === Message Events ===
936
+ bot.on('message', async (message, ctx) => {
937
+ console.log('New message:', message.text);
938
+ });
439
939
 
440
- // Channel posts
441
- bot.on('channel_post', (message, ctx) => {});
940
+ bot.on('text', async (message, ctx) => {
941
+ // Text messages only
942
+ });
442
943
 
443
- // Edited channel posts
444
- bot.on('edited_channel_post', (message, ctx) => {});
445
- ```
944
+ bot.on('photo', async (message, ctx) => {
945
+ // Photo messages
946
+ console.log('Photo received');
947
+ });
446
948
 
447
- ### Query Events
949
+ bot.on('video', async (message, ctx) => {
950
+ // Video messages
951
+ });
448
952
 
449
- ```javascript
450
- // Callback queries (from inline buttons)
451
- bot.on('callback_query', (query, ctx) => {
452
- console.log(query.data); // Button callback data
953
+ bot.on('audio', async (message, ctx) => {
954
+ // Audio messages
453
955
  });
454
956
 
455
- // Inline queries
456
- bot.on('inline_query', (query, ctx) => {
457
- console.log(query.query); // Search query
957
+ bot.on('document', async (message, ctx) => {
958
+ // Document messages
458
959
  });
459
960
 
460
- // Chosen inline result
461
- bot.on('chosen_inline_result', (result, ctx) => {});
462
- ```
961
+ bot.on('voice', async (message, ctx) => {
962
+ // Voice messages
963
+ });
463
964
 
464
- ### Poll Events
965
+ bot.on('sticker', async (message, ctx) => {
966
+ // Sticker messages
967
+ });
465
968
 
466
- ```javascript
467
- // Poll updates
468
- bot.on('poll', (poll, ctx) => {});
969
+ bot.on('location', async (message, ctx) => {
970
+ // Location messages
971
+ });
469
972
 
470
- // Poll answers
471
- bot.on('poll_answer', (answer, ctx) => {});
472
- ```
973
+ bot.on('contact', async (message, ctx) => {
974
+ // Contact messages
975
+ });
473
976
 
474
- ### Chat Member Events
977
+ // === Edit Events ===
978
+ bot.on('edited_message', async (message, ctx) => {
979
+ console.log('Message edited');
980
+ });
475
981
 
476
- ```javascript
477
- // Bot added/removed from chat
478
- bot.on('my_chat_member', (member, ctx) => {});
982
+ bot.on('edited_channel_post', async (post, ctx) => {
983
+ console.log('Channel post edited');
984
+ });
479
985
 
480
- // User added/removed from chat
481
- bot.on('chat_member', (member, ctx) => {});
482
- ```
986
+ // === Channel Events ===
987
+ bot.on('channel_post', async (message, ctx) => {
988
+ console.log('New channel post');
989
+ });
483
990
 
484
- ### System Events
991
+ // === Query Events ===
992
+ bot.on('callback_query', async (query, ctx) => {
993
+ console.log('Button clicked:', query.data);
994
+ });
485
995
 
486
- ```javascript
487
- // Update received
488
- bot.on('update', (update) => {});
996
+ bot.on('inline_query', async (query, ctx) => {
997
+ console.log('Inline query:', query.query);
998
+ });
999
+
1000
+ bot.on('chosen_inline_result', async (result, ctx) => {
1001
+ console.log('Result chosen:', result.result_id);
1002
+ });
1003
+
1004
+ // === Poll Events ===
1005
+ bot.on('poll', async (poll, ctx) => {
1006
+ console.log('Poll received');
1007
+ });
1008
+
1009
+ bot.on('poll_answer', async (answer, ctx) => {
1010
+ console.log('Poll answered');
1011
+ });
489
1012
 
490
- // Polling started
491
- bot.on('polling_start', () => {});
1013
+ // === Membership Events ===
1014
+ bot.on('my_chat_member', async (member, ctx) => {
1015
+ // Bot was added/removed from chat
1016
+ console.log('Status:', member.new_chat_member.status);
1017
+ });
492
1018
 
493
- // Polling stopped
494
- bot.on('polling_stop', () => {});
1019
+ bot.on('chat_member', async (member, ctx) => {
1020
+ // User status changed in chat
1021
+ console.log('User:', member.new_chat_member.user.first_name);
1022
+ });
495
1023
 
496
- // Polling error
497
- bot.on('polling_error', (error) => {});
1024
+ // === System Events ===
1025
+ bot.on('polling_start', () => {
1026
+ console.log('✅ Polling started');
1027
+ });
498
1028
 
499
- // Webhook started
500
- bot.on('webhook_start', (port) => {});
1029
+ bot.on('polling_stop', () => {
1030
+ console.log(' Polling stopped');
1031
+ });
501
1032
 
502
- // Webhook stopped
503
- bot.on('webhook_stop', () => {});
1033
+ bot.on('polling_error', (error) => {
1034
+ console.error('Polling error:', error);
1035
+ });
504
1036
 
505
- // Webhook error
506
- bot.on('webhook_error', (error) => {});
1037
+ bot.on('webhook_start', (port) => {
1038
+ console.log(`✅ Webhook listening on port ${port}`);
1039
+ });
507
1040
 
508
- // General error
509
- bot.on('error', (error) => {});
1041
+ bot.on('webhook_stop', () => {
1042
+ console.log(' Webhook stopped');
1043
+ });
1044
+
1045
+ bot.on('error', (error) => {
1046
+ console.error('Bot error:', error);
1047
+ });
510
1048
  ```
511
1049
 
512
- ## 🔧 Middleware
1050
+ ---
1051
+
1052
+ ## 🔌 Middleware System
1053
+
1054
+ Process updates with middleware chain:
513
1055
 
514
1056
  ```javascript
515
- // Logging middleware
1057
+ // Simple logging middleware
516
1058
  bot.use(async (ctx, next) => {
517
- console.log(`[${new Date().toISOString()}] Message from ${ctx.from?.username}`);
1059
+ console.log(`[${new Date().toISOString()}] User: ${ctx.from?.id}`);
518
1060
  await next();
519
1061
  });
520
1062
 
521
1063
  // Rate limiting middleware
522
- const userCalls = new Map();
1064
+ const userLimits = new Map();
1065
+
523
1066
  bot.use(async (ctx, next) => {
524
1067
  const userId = ctx.from?.id;
525
- if (!userId) return;
1068
+ const now = Date.now();
526
1069
 
527
- const calls = userCalls.get(userId) || 0;
528
- if (calls > 5) {
529
- await ctx.send('Rate limited!');
530
- return;
1070
+ if (!userLimits.has(userId)) {
1071
+ userLimits.set(userId, []);
1072
+ }
1073
+
1074
+ const times = userLimits.get(userId);
1075
+ times.push(now);
1076
+
1077
+ // Keep only last 10 requests
1078
+ const recentRequests = times.filter(t => now - t < 60000);
1079
+ userLimits.set(userId, recentRequests);
1080
+
1081
+ if (recentRequests.length > 30) {
1082
+ await ctx.send('Too many requests. Please wait.');
1083
+ return; // Don't call next()
531
1084
  }
532
1085
 
533
- userCalls.set(userId, calls + 1);
534
1086
  await next();
535
1087
  });
536
1088
 
537
- // Permission checking middleware
1089
+ // Auth check middleware
538
1090
  bot.use(async (ctx, next) => {
539
1091
  const allowedUsers = [123456789, 987654321];
540
- if (!allowedUsers.includes(ctx.from?.id || 0)) {
541
- await ctx.send('❌ Not authorized');
1092
+
1093
+ if (!allowedUsers.includes(ctx.from?.id)) {
1094
+ await ctx.send('You are not authorized');
542
1095
  return;
543
1096
  }
1097
+
1098
+ await next();
1099
+ });
1100
+
1101
+ // Error handling middleware
1102
+ bot.use(async (ctx, next) => {
1103
+ try {
1104
+ await next();
1105
+ } catch (error) {
1106
+ console.error('Error:', error);
1107
+ await ctx.send('An error occurred. Please try again.');
1108
+ }
1109
+ });
1110
+
1111
+ // Command prefix middleware
1112
+ bot.use(async (ctx, next) => {
1113
+ if (ctx.message?.text?.startsWith('!')) {
1114
+ ctx.isCommand = true;
1115
+ }
544
1116
  await next();
545
1117
  });
546
1118
  ```
547
1119
 
548
- ## 📋 Command Handling
1120
+ ---
549
1121
 
550
- ### Single Command
1122
+ ## 🎨 Advanced Examples
551
1123
 
1124
+ ### Example 1: Echo Bot
552
1125
  ```javascript
1126
+ const TelegramBot = require('teh-bot');
1127
+
1128
+ const bot = new TelegramBot(process.env.BOT_TOKEN, { polling: true });
1129
+
553
1130
  bot.command('/start', async (ctx) => {
554
- await ctx.send('Welcome!');
1131
+ await ctx.send('Send me anything and I will echo it back!');
555
1132
  });
556
1133
 
557
- bot.command('help', async (ctx) => { // With or without /
558
- await ctx.send('Need help?');
1134
+ bot.on('text', async (message, ctx) => {
1135
+ await ctx.reply(message.text);
559
1136
  });
560
1137
  ```
561
1138
 
562
- ### Multiple Commands
563
-
1139
+ ### Example 2: Calculator Bot
564
1140
  ```javascript
565
- bot.command(['/help', '/h', 'help'], async (ctx) => {
566
- await ctx.send('Here is help');
567
- });
568
- ```
1141
+ bot.command('/calculate', async (ctx) => {
1142
+ const keyboard = TelegramBot.InlineKeyboard()
1143
+ .text('➕', 'op_add')
1144
+ .text('➖', 'op_sub')
1145
+ .text('✖️', 'op_mul')
1146
+ .text('➗', 'op_div')
1147
+ .build();
569
1148
 
570
- ### Get Command Handler
1149
+ await ctx.send('Choose operation:', { reply_markup: keyboard });
1150
+ });
571
1151
 
572
- ```javascript
573
- const handler = bot.command('/start'); // Get without registering
574
- if (handler) {
575
- handler(ctx); // Call the handler
576
- }
1152
+ bot.on('callback_query', async (query, ctx) => {
1153
+ const operation = query.data.replace('op_', '');
1154
+
1155
+ if (operation === 'add') {
1156
+ // Handle addition
1157
+ }
1158
+
1159
+ await ctx.answerCallbackQuery({
1160
+ text: 'Operation selected!',
1161
+ show_alert: false
1162
+ });
1163
+ });
577
1164
  ```
578
1165
 
579
- ## 🌐 Webhook Mode
580
-
1166
+ ### Example 3: File Management Bot
581
1167
  ```javascript
582
- const bot = new TelegramBot(token, {
583
- webhook: true,
584
- webhookPort: 3000,
585
- webhookPath: '/webhook',
586
- });
587
-
588
- // Webhook events
589
- bot.on('webhook_start', (port) => {
590
- console.log(`✅ Webhook listening on port ${port}`);
1168
+ bot.command('/upload', async (ctx) => {
1169
+ await ctx.send('Send me a file to download');
591
1170
  });
592
1171
 
593
- bot.on('webhook_stop', () => {
594
- console.log('Webhook stopped');
1172
+ bot.on('document', async (message, ctx) => {
1173
+ const fileId = message.document.file_id;
1174
+
1175
+ // Download file
1176
+ await bot.downloadFile(fileId, `./downloads/${message.document.file_name}`);
1177
+
1178
+ await ctx.send('✅ File downloaded successfully!');
595
1179
  });
1180
+ ```
596
1181
 
597
- bot.on('webhook_error', (error) => {
598
- console.error('Webhook error:', error);
1182
+ ### Example 4: Quiz Bot
1183
+ ```javascript
1184
+ bot.command('/quiz', async (ctx) => {
1185
+ await bot.sendPoll(ctx.chat.id,
1186
+ 'What is the capital of France?',
1187
+ ['Paris', 'London', 'Berlin'],
1188
+ {
1189
+ type: 'quiz',
1190
+ correct_option_id: 0,
1191
+ explanation: 'Paris is the capital of France!'
1192
+ }
1193
+ );
599
1194
  });
600
-
601
- // Start webhook
602
- bot.startWebhook();
603
-
604
- // Stop webhook
605
- bot.stopWebhook();
606
1195
  ```
607
1196
 
608
- ## 🔄 Polling Mode
609
-
1197
+ ### Example 5: Admin Commands
610
1198
  ```javascript
611
- const bot = new TelegramBot(token, {
612
- polling: true,
613
- pollingInterval: 1000,
614
- pollingTimeout: 30,
1199
+ bot.command('/ban', async (ctx) => {
1200
+ if (!ctx.message?.reply_to_message) {
1201
+ await ctx.send('Reply to a message to ban that user');
1202
+ return;
1203
+ }
1204
+
1205
+ const userId = ctx.message.reply_to_message.from.id;
1206
+
1207
+ try {
1208
+ await bot.banChatMember(ctx.chat.id, userId, {
1209
+ revoke_messages: true
1210
+ });
1211
+
1212
+ await ctx.send('✅ User banned!');
1213
+ } catch (error) {
1214
+ await ctx.send('❌ Could not ban user: ' + error.message);
1215
+ }
615
1216
  });
616
1217
 
617
- // Start polling
618
- await bot.startPolling();
1218
+ bot.command('/promote', async (ctx) => {
1219
+ if (!ctx.message?.reply_to_message) {
1220
+ await ctx.send('Reply to a message to promote that user');
1221
+ return;
1222
+ }
619
1223
 
620
- // Stop polling
621
- bot.stopPolling();
1224
+ const userId = ctx.message.reply_to_message.from.id;
1225
+
1226
+ try {
1227
+ await bot.promoteChatMember(ctx.chat.id, userId, {
1228
+ can_delete_messages: true,
1229
+ can_restrict_members: true,
1230
+ can_pin_messages: true,
1231
+ can_manage_topics: true
1232
+ });
1233
+
1234
+ await ctx.send('✅ User promoted!');
1235
+ } catch (error) {
1236
+ await ctx.send('❌ Could not promote user: ' + error.message);
1237
+ }
1238
+ });
622
1239
  ```
623
1240
 
624
- ## 📤 Advanced Examples
1241
+ ---
625
1242
 
626
- ### Image Processing Bot
1243
+ ## 📊 Complete Method List
1244
+
1245
+ ### Message Methods
1246
+ - `sendMessage()` - Send text message
1247
+ - `sendPhoto()` - Send photo
1248
+ - `sendVideo()` - Send video
1249
+ - `sendAudio()` - Send audio
1250
+ - `sendDocument()` - Send document
1251
+ - `sendAnimation()` - Send animation (GIF)
1252
+ - `sendVoice()` - Send voice message
1253
+ - `sendVideoNote()` - Send video note
1254
+ - `sendSticker()` - Send sticker
1255
+ - `sendLocation()` - Send location
1256
+ - `sendVenue()` - Send venue
1257
+ - `sendContact()` - Send contact
1258
+ - `sendPoll()` - Send poll/quiz
1259
+ - `sendDice()` - Send dice game
1260
+ - `sendChatAction()` - Send typing indicator
1261
+
1262
+ ### Message Management
1263
+ - `forwardMessage()` - Forward message
1264
+ - `copyMessage()` - Copy message
1265
+ - `editMessageText()` - Edit message text
1266
+ - `editMessageCaption()` - Edit media caption
1267
+ - `editMessageReplyMarkup()` - Edit keyboard
1268
+ - `deleteMessage()` - Delete message
1269
+
1270
+ ### Chat Management
1271
+ - `getChat()` - Get chat info
1272
+ - `getChatAdministrators()` - Get admins
1273
+ - `getChatMemberCount()` - Get member count
1274
+ - `getChatMember()` - Get member info
1275
+ - `setChatTitle()` - Set chat title
1276
+ - `setChatDescription()` - Set chat description
1277
+ - `setChatPhoto()` - Set chat photo
1278
+ - `deleteChatPhoto()` - Delete chat photo
1279
+
1280
+ ### Member Management
1281
+ - `banChatMember()` - Ban member
1282
+ - `unbanChatMember()` - Unban member
1283
+ - `restrictChatMember()` - Restrict member
1284
+ - `promoteChatMember()` - Promote member
1285
+ - `setChatAdministratorCustomTitle()` - Set admin title
1286
+ - `approveChatJoinRequest()` - Approve join request
1287
+ - `declineChatJoinRequest()` - Decline join request
1288
+
1289
+ ### Message Pinning
1290
+ - `pinChatMessage()` - Pin message
1291
+ - `unpinChatMessage()` - Unpin message
1292
+ - `unpinAllChatMessages()` - Unpin all
1293
+
1294
+ ### Payments
1295
+ - `sendInvoice()` - Send payment invoice
1296
+ - `answerShippingQuery()` - Answer shipping
1297
+ - `answerPreCheckoutQuery()` - Answer pre-checkout
1298
+
1299
+ ### Query Responses
1300
+ - `answerCallbackQuery()` - Answer button click
1301
+ - `answerInlineQuery()` - Answer inline query
1302
+
1303
+ ### File Management
1304
+ - `getFile()` - Get file info
1305
+ - `downloadFile()` - Download file
1306
+
1307
+ ### Webhook
1308
+ - `setWebhook()` - Set webhook URL
1309
+ - `deleteWebhook()` - Delete webhook
1310
+ - `getWebhookInfo()` - Get webhook info
1311
+
1312
+ ### Bot
1313
+ - `getMe()` - Get bot info
1314
+ - `getUpdates()` - Get updates (polling)
1315
+ - `startPolling()` - Start long polling
1316
+ - `stopPolling()` - Stop polling
1317
+ - `startWebhook()` - Start webhook server
1318
+ - `stopWebhook()` - Stop webhook server
627
1319
 
628
- ```javascript
629
- const fs = require('fs');
1320
+ ---
630
1321
 
631
- bot.on('photo', async (message, ctx) => {
632
- const file = await bot.getFile(message.photo[message.photo.length - 1].file_id);
633
- await bot.downloadFile(file.file_id, './downloaded.jpg');
634
- await ctx.send('✅ Photo received and saved!');
1322
+ ## 💡 Best Practices
1323
+
1324
+ ### 1. Error Handling
1325
+ ```javascript
1326
+ bot.on('text', async (message, ctx) => {
1327
+ try {
1328
+ // Your code here
1329
+ await ctx.send('Hello!');
1330
+ } catch (error) {
1331
+ console.error('Error:', error);
1332
+ await ctx.send('An error occurred. Please try again.');
1333
+ }
635
1334
  });
636
1335
  ```
637
1336
 
638
- ### Interactive Menu
639
-
1337
+ ### 2. Rate Limiting
640
1338
  ```javascript
641
- bot.command('/menu', async (ctx) => {
642
- const keyboard = TelegramBot.InlineKeyboard()
643
- .text('Option A', 'opt_a')
644
- .text('Option B', 'opt_b')
645
- .row()
646
- .text('Back', 'back')
647
- .build();
1339
+ const rateLimits = new Map();
648
1340
 
649
- await ctx.send('Choose an option:', { reply_markup: keyboard });
650
- });
651
-
652
- bot.on('callback_query', async (query, ctx) => {
653
- switch (query.data) {
654
- case 'opt_a':
655
- await ctx.answerCallbackQuery({ text: 'You chose A!' });
656
- await ctx.editMessageText('✅ Option A selected');
657
- break;
658
- case 'opt_b':
659
- await ctx.answerCallbackQuery({ text: 'You chose B!' });
660
- await ctx.editMessageText('✅ Option B selected');
661
- break;
662
- case 'back':
663
- // Show menu again
664
- break;
1341
+ bot.use(async (ctx, next) => {
1342
+ const userId = ctx.from?.id;
1343
+ const now = Date.now();
1344
+
1345
+ if (!rateLimits.has(userId)) {
1346
+ rateLimits.set(userId, { count: 0, reset: now + 60000 });
665
1347
  }
1348
+
1349
+ const limit = rateLimits.get(userId);
1350
+ if (now > limit.reset) {
1351
+ limit.count = 0;
1352
+ limit.reset = now + 60000;
1353
+ }
1354
+
1355
+ if (limit.count++ > 10) {
1356
+ await ctx.send('Rate limited. Please wait.');
1357
+ return;
1358
+ }
1359
+
1360
+ await next();
666
1361
  });
667
1362
  ```
668
1363
 
669
- ### Survey Bot
670
-
1364
+ ### 3. Command Parsing
671
1365
  ```javascript
672
- bot.on('poll', async (poll, ctx) => {
673
- console.log(`Poll: ${poll.question}`);
674
- console.log(`Total voters: ${poll.total_voter_count}`);
675
- poll.options.forEach((opt, i) => {
676
- console.log(` ${i + 1}. ${opt.text}: ${opt.voter_count} votes`);
677
- });
678
- });
679
-
680
- bot.on('poll_answer', async (answer, ctx) => {
681
- console.log(`User ${answer.user.id} voted for options: ${answer.option_ids}`);
1366
+ bot.command(['/start', '/help', '/info'], async (ctx) => {
1367
+ const command = ctx.message.text.split(' ')[0];
1368
+
1369
+ if (command === '/start') {
1370
+ // Handle start
1371
+ } else if (command === '/help') {
1372
+ // Handle help
1373
+ }
682
1374
  });
683
1375
  ```
684
1376
 
685
- ### Auto-responder
686
-
1377
+ ### 4. Session Management
687
1378
  ```javascript
688
- const responses = {
689
- hello: '👋 Hello! How can I help?',
690
- hi: '👋 Hi there!',
691
- bye: '👋 Goodbye!',
692
- };
1379
+ const sessions = new Map();
1380
+
1381
+ function getSession(userId) {
1382
+ if (!sessions.has(userId)) {
1383
+ sessions.set(userId, {
1384
+ userId,
1385
+ state: 'idle',
1386
+ data: {}
1387
+ });
1388
+ }
1389
+ return sessions.get(userId);
1390
+ }
693
1391
 
694
1392
  bot.on('text', async (message, ctx) => {
695
- const text = message.text?.toLowerCase() || '';
696
- const response = responses[text];
697
- if (response) {
698
- await ctx.send(response);
1393
+ const session = getSession(ctx.from.id);
1394
+
1395
+ if (session.state === 'waiting_name') {
1396
+ session.data.name = message.text;
1397
+ session.state = 'idle';
1398
+ await ctx.send(`Hello ${session.data.name}!`);
699
1399
  }
700
1400
  });
701
1401
  ```
702
1402
 
703
- ## 🐛 Error Handling
704
-
1403
+ ### 5. Async File Operations
705
1404
  ```javascript
706
- bot.on('error', (error) => {
707
- console.error('Bot error:', {
708
- message: error.message,
709
- code: error.errorCode,
710
- response: error.response,
711
- });
712
- });
713
-
714
- bot.on('polling_error', (error) => {
715
- console.error('Polling error:', error.message);
716
- // Auto-reconnect happens automatically
1405
+ const fs = require('fs').promises;
1406
+
1407
+ bot.command('/export', async (ctx) => {
1408
+ try {
1409
+ await ctx.sendChatAction(ctx.chat.id, 'upload_document');
1410
+
1411
+ const data = await fs.readFile('./data.json');
1412
+ await bot.sendDocument(ctx.chat.id, data, {
1413
+ caption: 'Your data export'
1414
+ });
1415
+ } catch (error) {
1416
+ await ctx.send('Export failed: ' + error.message);
1417
+ }
717
1418
  });
718
-
719
- try {
720
- await bot.sendMessage(chatId, 'message');
721
- } catch (error) {
722
- console.error('Send failed:', error.message);
723
- }
724
1419
  ```
725
1420
 
726
- ## 📊 Telegram Bot API Coverage
727
-
728
- ### ✅ Implemented Features
1421
+ ---
729
1422
 
730
- - **Message Methods** - Send, edit, delete messages and media
731
- - ✅ **File Handling** - Upload, download files
732
- - ✅ **Chat Methods** - Get chat info, manage settings
733
- - ✅ **User Methods** - Get user info, manage members
734
- - ✅ **Keyboard & Buttons** - Inline and reply keyboards
735
- - ✅ **Queries** - Callback, inline, and poll queries
736
- - ✅ **Updates & Events** - Real-time event handling
737
- - ✅ **Polling & Webhooks** - Multiple update methods
738
- - ✅ **Media Types** - Photos, videos, audio, documents, stickers, animations, voice
739
- - ✅ **Admin Functions** - Ban, restrict, promote members
740
- - ✅ **Games & Polls** - Send polls and get answers
1423
+ ## 🐛 Troubleshooting
741
1424
 
742
- ## 🔌 Environment Setup
1425
+ ### Bot not receiving messages
1426
+ - Check if `polling: true` is set or webhook is properly configured
1427
+ - Verify the bot token is correct
1428
+ - Ensure the bot has been started with `/start` by the user
1429
+ - Check that `allowedUpdates` filter isn't blocking message updates
743
1430
 
744
- ### Get Your Bot Token
1431
+ ### File upload errors
1432
+ - Ensure file exists and is readable
1433
+ - Check file size limits (20MB for documents, 50MB for video)
1434
+ - Verify file format is supported
745
1435
 
746
- 1. Open Telegram and chat with [@BotFather](https://t.me/botfather)
747
- 2. Send `/newbot` command
748
- 3. Follow the instructions
749
- 4. Copy your token
1436
+ ### Webhook issues
1437
+ - Ensure HTTPS is used (not HTTP)
1438
+ - Certificate must be valid and not self-signed (unless using self-signed with setWebhook)
1439
+ - Telegram must be able to reach the webhook URL
1440
+ - Port 443 is recommended
750
1441
 
751
- ### Set Environment Variable
1442
+ ### Rate limiting
1443
+ - Telegram has rate limits: ~30 messages/second per bot
1444
+ - Implement backoff and queue system for high volume
1445
+ - Use middleware to throttle requests
752
1446
 
753
- ```bash
754
- export TELEGRAM_BOT_TOKEN="YOUR_TOKEN_HERE"
755
- ```
756
-
757
- Or in `.env` file:
758
- ```env
759
- TELEGRAM_BOT_TOKEN=your_token_here
760
- ```
1447
+ ---
761
1448
 
762
1449
  ## 📝 License
763
1450
 
@@ -765,18 +1452,14 @@ MIT License - See LICENSE file for details
765
1452
 
766
1453
  ## 🤝 Contributing
767
1454
 
768
- Contributions are welcome! Please feel free to submit a Pull Request.
1455
+ Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
769
1456
 
770
1457
  ## 📞 Support
771
1458
 
772
- For issues, questions, or suggestions:
773
- - GitHub Issues: [GitHub Issues](https://github.com/kazedevid/teh/issues)
774
- - Telegram Bot API Docs: [Official Docs](https://core.telegram.org/bots/api)
775
-
776
- ## 🙏 Acknowledgments
777
-
778
- Built with ❤️ for the Telegram Bot API community.
1459
+ - Report issues on GitHub
1460
+ - Check examples/ folder for code samples
1461
+ - Read full docs at api.telegram.org/bots/api
779
1462
 
780
1463
  ---
781
1464
 
782
- **Happy botting! 🤖**
1465
+ **Made with ❤️ by KazeDevID**