teh-bot 1.0.4 → 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.
package/README.md CHANGED
@@ -1,560 +1,1465 @@
1
- # teh-bot - Lightweight Telegram Bot API
2
-
3
- [![npm version](https://img.shields.io/npm/v/teh.svg)](https://www.npmjs.com/package/teh-bot)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- A lightweight, high-performance Telegram Bot API module with **zero dependencies**. Built for speed, stability, and simplicity.
7
-
8
- ## Features
1
+ # 🤖 Teh Bot - Lightweight Telegram Bot API Library
2
+
3
+ ![Version](https://img.shields.io/badge/version-1.0.5-blue)
4
+ ![License](https://img.shields.io/badge/license-MIT-green)
5
+ ![Node.js](https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen)
6
+ ![npm](https://img.shields.io/badge/npm-teh--bot-red)
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
24
+ - ✅ **Keyboard Builders** - Fluent API for inline and reply keyboards
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
+
29
+ ## 📦 Installation
30
+
31
+ ### Using npm
32
+ ```bash
33
+ npm install teh-bot
34
+ ```
9
35
 
10
- - **Zero Dependencies** - Only native Node.js modules
11
- - **High Performance** - Optimized HTTP requests with connection pooling
12
- - **Full API Coverage** - Complete Telegram Bot API implementation
13
- - **Event-Driven** - Built on Node.js EventEmitter
14
- - **Middleware Support** - Express-style middleware system
15
- - **Smart Rate Limiting** - Automatic request queuing and retry logic
16
- - **Both Polling & Webhooks** - Choose your preferred update method
17
- - **TypeScript Support** - Full TypeScript definitions included
18
- - **Small Bundle Size** - Minimal footprint for fast deployments
19
- - **Clean API** - Intuitive, chainable methods
36
+ ### Using yarn
37
+ ```bash
38
+ yarn add teh-bot
39
+ ```
20
40
 
21
- ## Installation
41
+ ### Using pnpm
42
+ ```bash
43
+ pnpm add teh-bot
44
+ ```
22
45
 
46
+ ### Using bun
23
47
  ```bash
24
- npm install teh-bot
48
+ bun add teh-bot
25
49
  ```
26
50
 
27
- ## Quick Start
51
+ ## 🚀 Quick Start
28
52
 
53
+ ### CommonJS (.js)
29
54
  ```javascript
30
55
  const TelegramBot = require('teh-bot');
31
56
 
32
- const bot = new TelegramBot('YOUR_BOT_TOKEN', {
33
- polling: true
57
+ const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
58
+ polling: true,
34
59
  });
35
60
 
36
- bot.command('start', async (ctx) => {
37
- await ctx.reply('Hello! Welcome to my bot!');
61
+ bot.command('/start', async (ctx) => {
62
+ await ctx.send('👋 Hello! I am Teh Bot!');
38
63
  });
39
64
 
40
65
  bot.on('text', async (message, ctx) => {
66
+ console.log('Message:', message.text);
41
67
  await ctx.reply(`You said: ${message.text}`);
42
68
  });
69
+
70
+ bot.on('polling_start', () => {
71
+ console.log('✅ Bot started polling');
72
+ });
73
+
74
+ bot.on('polling_error', (error) => {
75
+ console.error('❌ Polling error:', error);
76
+ });
43
77
  ```
44
78
 
45
- ## Table of Contents
79
+ ### ES Modules (.mjs)
80
+ ```javascript
81
+ import TelegramBot from 'teh-bot';
46
82
 
47
- - [Basic Usage](#basic-usage)
48
- - [Polling vs Webhooks](#polling-vs-webhooks)
49
- - [Sending Messages](#sending-messages)
50
- - [Keyboards](#keyboards)
51
- - [Commands](#commands)
52
- - [Middleware](#middleware)
53
- - [Events](#events)
54
- - [File Handling](#file-handling)
55
- - [Error Handling](#error-handling)
56
- - [API Reference](#api-reference)
83
+ const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
84
+ polling: true,
85
+ pollingInterval: 2000,
86
+ pollingTimeout: 60,
87
+ });
57
88
 
58
- ## Basic Usage
89
+ bot.command('/start', async (ctx) => {
90
+ await ctx.send('👋 Hello! I am Teh Bot!');
91
+ });
59
92
 
60
- ### Initializing the Bot
93
+ bot.on('text', async (message, ctx) => {
94
+ console.log('Message:', message.text);
95
+ });
96
+ ```
61
97
 
62
- ```javascript
63
- const TelegramBot = require('teh-bot');
98
+ ### TypeScript (.ts)
99
+ ```typescript
100
+ import TelegramBot, { Context } from 'teh-bot';
64
101
 
65
- const bot = new TelegramBot('YOUR_BOT_TOKEN', {
102
+ const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN || '', {
66
103
  polling: true,
67
- pollingInterval: 1000,
68
- pollingTimeout: 30
104
+ });
105
+
106
+ bot.command('/start', async (ctx: Context) => {
107
+ await ctx.send('👋 Hello! I am Teh Bot!');
108
+ });
109
+
110
+ bot.on('text', async (message, ctx: Context) => {
111
+ console.log('Message:', message.text);
112
+ await ctx.reply(`You said: ${message.text}`);
69
113
  });
70
114
  ```
71
115
 
72
- ### Options
116
+ ## ⚙️ Configuration
73
117
 
74
- - `polling` (boolean) - Enable long polling (default: false)
75
- - `pollingInterval` (number) - Polling interval in ms (default: 1000)
76
- - `pollingTimeout` (number) - Long polling timeout in seconds (default: 30)
77
- - `webhook` (boolean) - Enable webhook mode (default: false)
78
- - `webhookPort` (number) - Webhook server port (default: 3000)
79
- - `webhookPath` (string) - Webhook URL path (default: '/webhook')
80
- - `requestTimeout` (number) - HTTP request timeout in ms (default: 30000)
81
- - `allowedUpdates` (array) - List of update types to receive
118
+ ### Bot Initialization Options
82
119
 
83
- ## Polling vs Webhooks
120
+ ```javascript
121
+ const bot = new TelegramBot(token, {
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)
126
+
127
+ // === Webhook Configuration ===
128
+ webhook: false, // Enable webhook mode (default: false)
129
+ webhookPort: 3000, // Webhook server port (default: 3000)
130
+ webhookPath: '/webhook', // Webhook endpoint path (default: '/webhook')
131
+
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
145
+ });
146
+ ```
84
147
 
85
- ### Polling Mode
148
+ ---
86
149
 
150
+ ## 📚 Complete API Reference
151
+
152
+ ### 1. Bot Management
153
+
154
+ #### Get Bot Information
87
155
  ```javascript
88
- const bot = new TelegramBot(token, { polling: true });
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
+ ```
89
162
 
90
- bot.startPolling();
163
+ #### Webhook Management
164
+ ```javascript
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
+ });
91
171
 
92
- bot.on('polling_error', (error) => {
93
- console.error('Polling error:', error);
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
188
+ await bot.sendMessage(chatId, 'Hello!');
189
+
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
+ ]
94
215
  });
95
216
  ```
96
217
 
97
- ### Webhook Mode
218
+ #### Media Messages
98
219
 
220
+ **Photos**
99
221
  ```javascript
100
- const bot = new TelegramBot(token, {
101
- webhook: true,
102
- webhookPort: 8443,
103
- webhookPath: '/bot-webhook'
222
+ // Photo from URL
223
+ await bot.sendPhoto(chatId, 'https://example.com/photo.jpg', {
224
+ caption: 'Beautiful photo!',
225
+ parse_mode: 'HTML'
104
226
  });
105
227
 
106
- await bot.setWebhook('https://yourdomain.com/bot-webhook');
228
+ // Photo from file path
229
+ await bot.sendPhoto(chatId, './photo.jpg', {
230
+ caption: 'Local photo'
231
+ });
107
232
 
108
- bot.on('webhook_start', (port) => {
109
- console.log(`Webhook server started on port ${port}`);
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'
110
242
  });
111
243
  ```
112
244
 
113
- ## Sending Messages
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
+ });
114
256
 
115
- ### Text Messages
257
+ // Local video file
258
+ await bot.sendVideo(chatId, './video.mp4', {
259
+ caption: 'Local video',
260
+ supports_streaming: true
261
+ });
262
+ ```
116
263
 
264
+ **Audio**
117
265
  ```javascript
118
- await bot.sendMessage(chatId, 'Hello World!');
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
+ });
119
273
 
120
- await bot.sendMessage(chatId, '*Bold* and _italic_ text', {
121
- parse_mode: 'Markdown'
274
+ // Local audio
275
+ await bot.sendAudio(chatId, './music.mp3', {
276
+ caption: 'Great song!'
122
277
  });
278
+ ```
123
279
 
124
- await bot.sendMessage(chatId, '<b>Bold</b> and <i>italic</i> text', {
280
+ **Documents**
281
+ ```javascript
282
+ // PDF document
283
+ await bot.sendDocument(chatId, 'https://example.com/file.pdf', {
284
+ caption: 'Important document',
125
285
  parse_mode: 'HTML'
126
286
  });
287
+
288
+ // Local file
289
+ await bot.sendDocument(chatId, './report.pdf', {
290
+ caption: 'Report.pdf'
291
+ });
292
+
293
+ // Any file type
294
+ await bot.sendDocument(chatId, './archive.zip', {
295
+ caption: 'Compressed files'
296
+ });
297
+ ```
298
+
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
+ });
307
+
308
+ await bot.sendAnimation(chatId, './animation.gif', {
309
+ thumbnail: './thumb.jpg'
310
+ });
127
311
  ```
128
312
 
129
- ### Photos
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
+ });
320
+
321
+ // From URL
322
+ await bot.sendVoice(chatId, 'https://example.com/voice.ogg', {
323
+ duration: 45
324
+ });
325
+ ```
130
326
 
327
+ **Video Notes (Circular Videos)**
131
328
  ```javascript
132
- await bot.sendPhoto(chatId, 'https://example.com/image.jpg');
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
+ ```
133
338
 
134
- await bot.sendPhoto(chatId, '/path/to/local/image.jpg');
339
+ **Stickers**
340
+ ```javascript
341
+ // Send sticker by file ID
342
+ await bot.sendSticker(chatId, 'sticker_file_id');
135
343
 
136
- await bot.sendPhoto(chatId, 'file_id_from_telegram');
344
+ // Send from URL
345
+ await bot.sendSticker(chatId, 'https://example.com/sticker.webp');
137
346
 
138
- await bot.sendPhoto(chatId, photoBuffer);
347
+ // Send from local file
348
+ await bot.sendSticker(chatId, './sticker.tgs');
139
349
  ```
140
350
 
141
- ### Documents
351
+ ---
352
+
353
+ ### 3. Location & Venue
142
354
 
355
+ #### Send Location
143
356
  ```javascript
144
- await bot.sendDocument(chatId, '/path/to/document.pdf', {
145
- caption: 'Here is your document'
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
146
362
  });
147
363
  ```
148
364
 
149
- ### Other Media Types
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
+ ```
150
372
 
373
+ #### Send Contact
151
374
  ```javascript
152
- await bot.sendVideo(chatId, videoPath);
153
- await bot.sendAudio(chatId, audioPath);
154
- await bot.sendVoice(chatId, voicePath);
155
- await bot.sendSticker(chatId, stickerId);
156
- await bot.sendAnimation(chatId, gifPath);
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
+ });
157
379
  ```
158
380
 
159
- ### Location
381
+ ---
382
+
383
+ ### 4. Polls & Quizzes
160
384
 
385
+ #### Create Poll
161
386
  ```javascript
162
- await bot.sendLocation(chatId, latitude, longitude);
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
+ });
163
402
  ```
164
403
 
165
- ### Contact
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:
166
417
 
167
418
  ```javascript
168
- await bot.sendContact(chatId, '+1234567890', 'John Doe');
419
+ // Typing indicator
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');
169
448
  ```
170
449
 
171
- ### Poll
450
+ ---
451
+
452
+ ### 6. Message Management
172
453
 
454
+ #### Forward Message
173
455
  ```javascript
174
- await bot.sendPoll(chatId, 'What is your favorite color?', [
175
- 'Red',
176
- 'Blue',
177
- 'Green',
178
- 'Yellow'
179
- ]);
456
+ // Forward message from another chat
457
+ await bot.forwardMessage(chatId, sourceChatId, messageId, {
458
+ disable_notification: false
459
+ });
180
460
  ```
181
461
 
182
- ## Keyboards
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
+ ```
183
470
 
184
- ### Inline Keyboards
471
+ #### Edit Message Text
472
+ ```javascript
473
+ // Edit sent message
474
+ await bot.editMessageText('New text', {
475
+ chat_id: chatId,
476
+ message_id: messageId,
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'
487
+ });
488
+ ```
185
489
 
490
+ #### Edit Message Caption
186
491
  ```javascript
187
- const keyboard = TelegramBot.InlineKeyboard()
188
- .text('Button 1', 'callback_data_1')
189
- .text('Button 2', 'callback_data_2')
492
+ // Edit media caption
493
+ await bot.editMessageCaption({
494
+ chat_id: chatId,
495
+ message_id: messageId,
496
+ caption: 'New caption',
497
+ parse_mode: 'HTML'
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')
190
506
  .row()
191
- .url('Visit Website', 'https://example.com')
507
+ .url('Google', 'https://google.com')
192
508
  .build();
193
509
 
194
- await bot.sendMessage(chatId, 'Choose an option:', {
195
- reply_markup: keyboard
510
+ await bot.editMessageReplyMarkup({
511
+ chat_id: chatId,
512
+ message_id: messageId,
513
+ reply_markup: newKeyboard
196
514
  });
515
+ ```
197
516
 
198
- bot.on('callback_query', async (query, ctx) => {
199
- if (query.data === 'callback_data_1') {
200
- await ctx.answerCallbackQuery({ text: 'You clicked Button 1!' });
201
- await ctx.editMessageText('You selected Button 1');
517
+ #### Delete Message
518
+ ```javascript
519
+ // Delete a message
520
+ await bot.deleteMessage(chatId, messageId);
521
+ ```
522
+
523
+ ---
524
+
525
+ ### 7. Payments
526
+
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
+ });
547
+ ```
548
+
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
+ });
202
580
  }
203
581
  });
204
582
  ```
205
583
 
206
- ### Reply Keyboards
584
+ #### Answer Pre-Checkout Query
585
+ ```javascript
586
+ bot.on('pre_checkout_query', async (query, ctx) => {
587
+ // Validate order before payment
588
+ const isValid = validateOrder(query);
207
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
+ ```
599
+
600
+ #### Handle Successful Payment
208
601
  ```javascript
209
- const keyboard = TelegramBot.ReplyKeyboard()
210
- .text('Option 1')
211
- .text('Option 2')
212
- .row()
213
- .text('Option 3')
214
- .resize()
215
- .oneTime()
216
- .build();
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);
217
607
 
218
- await bot.sendMessage(chatId, 'Select an option:', {
219
- reply_markup: keyboard
608
+ await ctx.send(' Payment successful! Thank you for your purchase!');
220
609
  });
221
610
  ```
222
611
 
223
- ### Remove Keyboard
612
+ ---
613
+
614
+ ### 8. Chat Management
224
615
 
616
+ #### Get Chat Information
225
617
  ```javascript
226
- await bot.sendMessage(chatId, 'Keyboard removed', {
227
- reply_markup: TelegramBot.RemoveKeyboard()
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);
623
+
624
+ // Get chat member count
625
+ const count = await bot.getChatMemberCount(chatId);
626
+ console.log('Members:', count);
627
+
628
+ // Get specific member info
629
+ const member = await bot.getChatMember(chatId, userId);
630
+ console.log('Member status:', member.status);
631
+ console.log('Member:', member.user.first_name);
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}`);
228
637
  });
229
638
  ```
230
639
 
231
- ### Request Contact/Location
640
+ #### Manage Chat Settings
641
+ ```javascript
642
+ // Set chat title
643
+ await bot.setChatTitle(chatId, 'New Group Name');
644
+
645
+ // Set chat description
646
+ await bot.setChatDescription(chatId, 'Group description and rules...');
647
+
648
+ // Set chat photo
649
+ await bot.setChatPhoto(chatId, './group_photo.jpg');
650
+
651
+ // Delete chat photo
652
+ await bot.deleteChatPhoto(chatId);
653
+
654
+ // Get chat member info
655
+ const member = await bot.getChatMember(chatId, userId);
656
+ ```
657
+
658
+ ---
659
+
660
+ ### 9. Member Management
232
661
 
662
+ #### Restrict/Promote Members
233
663
  ```javascript
234
- const keyboard = TelegramBot.ReplyKeyboard()
235
- .requestContact('Share Contact')
236
- .row()
237
- .requestLocation('Share Location')
238
- .resize()
239
- .build();
664
+ // Restrict member (disable all permissions)
665
+ await bot.restrictChatMember(chatId, userId, {
666
+ can_send_messages: false,
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
+ });
240
672
 
241
- await bot.sendMessage(chatId, 'Please share your info:', {
242
- reply_markup: keyboard
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
679
+ });
680
+
681
+ // Promote member to admin
682
+ await bot.promoteChatMember(chatId, userId, {
683
+ can_change_info: true,
684
+ can_delete_messages: true,
685
+ can_restrict_members: true,
686
+ can_pin_messages: true,
687
+ can_manage_topics: true,
688
+ is_anonymous: false
689
+ });
690
+
691
+ // Set custom admin title
692
+ await bot.setChatAdministratorCustomTitle(chatId, userId, 'Cool Admin');
693
+ ```
694
+
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
243
701
  });
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
715
+ ```javascript
716
+ // Approve join request
717
+ await bot.approveChatJoinRequest(chatId, userId);
718
+
719
+ // Decline join request
720
+ await bot.declineChatJoinRequest(chatId, userId);
721
+
722
+ // Leave chat
723
+ await bot.leaveChat(chatId);
244
724
  ```
245
725
 
246
- ## Commands
726
+ ---
247
727
 
248
- ### Basic Commands
728
+ ### 10. Message Pinning
249
729
 
250
730
  ```javascript
251
- bot.command('start', async (ctx) => {
252
- await ctx.reply('Welcome! Use /help to see available commands.');
731
+ // Pin message (all members see it)
732
+ await bot.pinChatMessage(chatId, messageId, {
733
+ disable_notification: false // Notify members
253
734
  });
254
735
 
255
- bot.command('help', async (ctx) => {
256
- await ctx.reply('Available commands:\n/start - Start the bot\n/help - Show this message');
736
+ // Unpin specific message
737
+ await bot.unpinChatMessage(chatId, {
738
+ message_id: messageId
257
739
  });
740
+
741
+ // Unpin all messages
742
+ await bot.unpinAllChatMessages(chatId);
258
743
  ```
259
744
 
260
- ### Multiple Command Aliases
745
+ ---
746
+
747
+ ### 11. Queries & Responses
261
748
 
749
+ #### Callback Query
262
750
  ```javascript
263
- bot.command(['info', 'about'], async (ctx) => {
264
- await ctx.reply('Bot information...');
751
+ bot.on('callback_query', async (query, ctx) => {
752
+ console.log('Button clicked:', query.data);
753
+
754
+ // Answer callback (shows notification or toast)
755
+ await ctx.answerCallbackQuery({
756
+ text: 'Button was clicked!',
757
+ show_alert: false // Toast notification
758
+ });
759
+
760
+ // Edit message
761
+ await ctx.editMessageText('You clicked the button!');
265
762
  });
266
763
  ```
267
764
 
268
- ### Command with Arguments
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
+ ```
269
792
 
793
+ #### Chosen Inline Result
270
794
  ```javascript
271
- bot.on('text', async (message, ctx) => {
272
- if (message.text.startsWith('/greet')) {
273
- const args = message.text.split(' ').slice(1);
274
- const name = args.join(' ') || 'stranger';
275
- await ctx.reply(`Hello, ${name}!`);
276
- }
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);
277
798
  });
278
799
  ```
279
800
 
280
- ## Middleware
801
+ ---
281
802
 
282
- ### Basic Middleware
803
+ ### 12. File Management
283
804
 
805
+ #### Download File
284
806
  ```javascript
285
- bot.use(async (ctx, next) => {
286
- console.log('Received update:', ctx.update.update_id);
287
- await next();
288
- });
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);
289
811
 
290
- bot.use(async (ctx, next) => {
291
- ctx.startTime = Date.now();
292
- await next();
293
- const duration = Date.now() - ctx.startTime;
294
- console.log(`Request took ${duration}ms`);
812
+ // Download file to disk
813
+ const destination = './downloaded_file.jpg';
814
+ await bot.downloadFile('file_id', destination);
815
+ console.log('Downloaded to:', destination);
816
+ ```
817
+
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');
825
+
826
+ // Upload from Buffer
827
+ const buffer = await fs.promises.readFile('./photo.jpg');
828
+ await bot.sendPhoto(chatId, buffer);
829
+ ```
830
+
831
+ ---
832
+
833
+ ### 13. Keyboard Builders
834
+
835
+ #### Inline Keyboard (Buttons with Actions)
836
+ ```javascript
837
+ // Create inline keyboard
838
+ const keyboard = TelegramBot.InlineKeyboard()
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')
843
+ .url('Google', 'https://google.com')
844
+ .row()
845
+ .text('Delete', 'delete_action')
846
+ .build();
847
+
848
+ await bot.sendMessage(chatId, 'Choose an action:', {
849
+ reply_markup: keyboard
295
850
  });
296
851
  ```
297
852
 
298
- ### Authentication Middleware
853
+ #### Reply Keyboard (Regular Buttons)
854
+ ```javascript
855
+ // Create reply keyboard
856
+ const keyboard = TelegramBot.ReplyKeyboard()
857
+ .text('Button 1')
858
+ .text('Button 2')
859
+ .row()
860
+ .text('Button 3')
861
+ .oneTime() // Disappears after use
862
+ .build();
299
863
 
864
+ await bot.sendMessage(chatId, 'Select an option:', {
865
+ reply_markup: keyboard
866
+ });
867
+ ```
868
+
869
+ #### Remove Keyboard
300
870
  ```javascript
301
- const AUTHORIZED_USERS = [123456789, 987654321];
871
+ // Hide keyboard
872
+ await bot.sendMessage(chatId, 'Keyboard hidden', {
873
+ reply_markup: TelegramBot.RemoveKeyboard()
874
+ });
875
+ ```
302
876
 
303
- bot.use(async (ctx, next) => {
304
- if (ctx.from && AUTHORIZED_USERS.includes(ctx.from.id)) {
305
- await next();
306
- } else {
307
- await ctx.reply('You are not authorized to use this bot.');
308
- }
877
+ #### Force Reply
878
+ ```javascript
879
+ // Force user to reply to this message
880
+ await bot.sendMessage(chatId, 'Please reply to this message:', {
881
+ reply_markup: TelegramBot.ForceReply()
309
882
  });
310
883
  ```
311
884
 
312
- ### Logging Middleware
885
+ ---
886
+
887
+ ### 14. Context Helpers
888
+
889
+ Context object provides convenient shortcuts:
313
890
 
314
891
  ```javascript
315
- bot.use(async (ctx, next) => {
316
- const user = ctx.from?.username || ctx.from?.id || 'unknown';
317
- const message = ctx.message?.text || 'no text';
318
- console.log(`[${new Date().toISOString()}] ${user}: ${message}`);
319
- await next();
892
+ bot.on('text', async (message, ctx) => {
893
+ // Send message to same chat
894
+ await ctx.send('Hello!');
895
+
896
+ // Reply to message (with reply_to_message_id)
897
+ await ctx.reply('Thanks for your message!');
898
+
899
+ // Send photo in reply
900
+ await ctx.replyWithPhoto('./photo.jpg', {
901
+ caption: 'Photo reply'
902
+ });
903
+
904
+ // Send video in reply
905
+ await ctx.replyWithVideo('./video.mp4', {
906
+ caption: 'Video reply'
907
+ });
908
+
909
+ // Send audio
910
+ await ctx.replyWithAudio('./song.mp3', {
911
+ title: 'Song'
912
+ });
913
+
914
+ // Send document
915
+ await ctx.replyWithDocument('./file.pdf');
916
+
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
+ }
320
925
  });
321
926
  ```
322
927
 
323
- ## Events
928
+ ---
929
+
930
+ ## 🎯 Event Listeners
324
931
 
325
- ### Message Events
932
+ Listen to different types of updates:
326
933
 
327
934
  ```javascript
328
- bot.on('message', (message, ctx) => {
329
- console.log('New message:', message);
935
+ // === Message Events ===
936
+ bot.on('message', async (message, ctx) => {
937
+ console.log('New message:', message.text);
330
938
  });
331
939
 
332
940
  bot.on('text', async (message, ctx) => {
333
- console.log('Text message:', message.text);
941
+ // Text messages only
334
942
  });
335
943
 
336
944
  bot.on('photo', async (message, ctx) => {
337
- console.log('Photo received:', message.photo);
945
+ // Photo messages
946
+ console.log('Photo received');
947
+ });
948
+
949
+ bot.on('video', async (message, ctx) => {
950
+ // Video messages
951
+ });
952
+
953
+ bot.on('audio', async (message, ctx) => {
954
+ // Audio messages
338
955
  });
339
956
 
340
957
  bot.on('document', async (message, ctx) => {
341
- console.log('Document received:', message.document);
958
+ // Document messages
342
959
  });
343
960
 
344
- bot.on('video', async (message, ctx) => {
345
- console.log('Video received:', message.video);
961
+ bot.on('voice', async (message, ctx) => {
962
+ // Voice messages
346
963
  });
347
964
 
348
965
  bot.on('sticker', async (message, ctx) => {
349
- await ctx.reply('Nice sticker!');
966
+ // Sticker messages
350
967
  });
351
968
 
352
969
  bot.on('location', async (message, ctx) => {
353
- const { latitude, longitude } = message.location;
354
- await ctx.reply(`You are at: ${latitude}, ${longitude}`);
970
+ // Location messages
355
971
  });
356
972
 
357
973
  bot.on('contact', async (message, ctx) => {
358
- await ctx.reply(`Contact received: ${message.contact.first_name}`);
974
+ // Contact messages
359
975
  });
360
- ```
361
-
362
- ### Update Events
363
976
 
364
- ```javascript
365
- bot.on('edited_message', (message, ctx) => {
977
+ // === Edit Events ===
978
+ bot.on('edited_message', async (message, ctx) => {
366
979
  console.log('Message edited');
367
980
  });
368
981
 
982
+ bot.on('edited_channel_post', async (post, ctx) => {
983
+ console.log('Channel post edited');
984
+ });
985
+
986
+ // === Channel Events ===
987
+ bot.on('channel_post', async (message, ctx) => {
988
+ console.log('New channel post');
989
+ });
990
+
991
+ // === Query Events ===
369
992
  bot.on('callback_query', async (query, ctx) => {
370
- await ctx.answerCallbackQuery();
993
+ console.log('Button clicked:', query.data);
371
994
  });
372
995
 
373
996
  bot.on('inline_query', async (query, ctx) => {
374
997
  console.log('Inline query:', query.query);
375
998
  });
376
- ```
377
999
 
378
- ### Error Events
1000
+ bot.on('chosen_inline_result', async (result, ctx) => {
1001
+ console.log('Result chosen:', result.result_id);
1002
+ });
379
1003
 
380
- ```javascript
381
- bot.on('error', (error) => {
382
- console.error('Bot error:', error);
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
+ });
1012
+
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
+ });
1018
+
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
+ });
1023
+
1024
+ // === System Events ===
1025
+ bot.on('polling_start', () => {
1026
+ console.log('✅ Polling started');
1027
+ });
1028
+
1029
+ bot.on('polling_stop', () => {
1030
+ console.log('❌ Polling stopped');
383
1031
  });
384
1032
 
385
1033
  bot.on('polling_error', (error) => {
386
1034
  console.error('Polling error:', error);
387
1035
  });
388
1036
 
389
- bot.on('webhook_error', (error) => {
390
- console.error('Webhook error:', error);
1037
+ bot.on('webhook_start', (port) => {
1038
+ console.log(`✅ Webhook listening on port ${port}`);
1039
+ });
1040
+
1041
+ bot.on('webhook_stop', () => {
1042
+ console.log('❌ Webhook stopped');
1043
+ });
1044
+
1045
+ bot.on('error', (error) => {
1046
+ console.error('Bot error:', error);
391
1047
  });
392
1048
  ```
393
1049
 
394
- ## File Handling
1050
+ ---
1051
+
1052
+ ## 🔌 Middleware System
395
1053
 
396
- ### Download Files
1054
+ Process updates with middleware chain:
397
1055
 
398
1056
  ```javascript
399
- bot.on('document', async (message, ctx) => {
400
- const fileId = message.document.file_id;
1057
+ // Simple logging middleware
1058
+ bot.use(async (ctx, next) => {
1059
+ console.log(`[${new Date().toISOString()}] User: ${ctx.from?.id}`);
1060
+ await next();
1061
+ });
1062
+
1063
+ // Rate limiting middleware
1064
+ const userLimits = new Map();
401
1065
 
1066
+ bot.use(async (ctx, next) => {
1067
+ const userId = ctx.from?.id;
1068
+ const now = Date.now();
1069
+
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()
1084
+ }
1085
+
1086
+ await next();
1087
+ });
1088
+
1089
+ // Auth check middleware
1090
+ bot.use(async (ctx, next) => {
1091
+ const allowedUsers = [123456789, 987654321];
1092
+
1093
+ if (!allowedUsers.includes(ctx.from?.id)) {
1094
+ await ctx.send('You are not authorized');
1095
+ return;
1096
+ }
1097
+
1098
+ await next();
1099
+ });
1100
+
1101
+ // Error handling middleware
1102
+ bot.use(async (ctx, next) => {
402
1103
  try {
403
- await bot.downloadFile(fileId, './downloads/document.pdf');
404
- await ctx.reply('File downloaded successfully!');
1104
+ await next();
405
1105
  } catch (error) {
406
- await ctx.reply('Failed to download file.');
1106
+ console.error('Error:', error);
1107
+ await ctx.send('An error occurred. Please try again.');
407
1108
  }
408
1109
  });
1110
+
1111
+ // Command prefix middleware
1112
+ bot.use(async (ctx, next) => {
1113
+ if (ctx.message?.text?.startsWith('!')) {
1114
+ ctx.isCommand = true;
1115
+ }
1116
+ await next();
1117
+ });
409
1118
  ```
410
1119
 
411
- ### Get File Info
1120
+ ---
1121
+
1122
+ ## 🎨 Advanced Examples
412
1123
 
1124
+ ### Example 1: Echo Bot
413
1125
  ```javascript
414
- const file = await bot.getFile(fileId);
415
- console.log('File path:', file.file_path);
416
- console.log('File size:', file.file_size);
1126
+ const TelegramBot = require('teh-bot');
1127
+
1128
+ const bot = new TelegramBot(process.env.BOT_TOKEN, { polling: true });
1129
+
1130
+ bot.command('/start', async (ctx) => {
1131
+ await ctx.send('Send me anything and I will echo it back!');
1132
+ });
1133
+
1134
+ bot.on('text', async (message, ctx) => {
1135
+ await ctx.reply(message.text);
1136
+ });
1137
+ ```
1138
+
1139
+ ### Example 2: Calculator Bot
1140
+ ```javascript
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();
1148
+
1149
+ await ctx.send('Choose operation:', { reply_markup: keyboard });
1150
+ });
1151
+
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
+ });
417
1164
  ```
418
1165
 
419
- ## Error Handling
1166
+ ### Example 3: File Management Bot
1167
+ ```javascript
1168
+ bot.command('/upload', async (ctx) => {
1169
+ await ctx.send('Send me a file to download');
1170
+ });
1171
+
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!');
1179
+ });
1180
+ ```
420
1181
 
421
- ### Try-Catch Pattern
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
+ );
1194
+ });
1195
+ ```
422
1196
 
1197
+ ### Example 5: Admin Commands
423
1198
  ```javascript
424
- bot.command('start', async (ctx) => {
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
+
425
1207
  try {
426
- await ctx.reply('Welcome!');
1208
+ await bot.banChatMember(ctx.chat.id, userId, {
1209
+ revoke_messages: true
1210
+ });
1211
+
1212
+ await ctx.send('✅ User banned!');
427
1213
  } catch (error) {
428
- console.error('Failed to send message:', error);
1214
+ await ctx.send(' Could not ban user: ' + error.message);
429
1215
  }
430
1216
  });
431
- ```
432
1217
 
433
- ### Global Error Handler
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
+ }
434
1223
 
435
- ```javascript
436
- bot.on('error', (error) => {
437
- if (error.code === 403) {
438
- console.error('Bot was blocked by user');
439
- } else if (error.code === 429) {
440
- console.error('Rate limit exceeded');
441
- } else {
442
- console.error('Unexpected error:', error);
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);
443
1237
  }
444
1238
  });
445
1239
  ```
446
1240
 
447
- ## API Reference
448
-
449
- ### Bot Methods
450
-
451
- #### Message Methods
452
- - `sendMessage(chatId, text, options)` - Send text message
453
- - `sendPhoto(chatId, photo, options)` - Send photo
454
- - `sendAudio(chatId, audio, options)` - Send audio
455
- - `sendDocument(chatId, document, options)` - Send document
456
- - `sendVideo(chatId, video, options)` - Send video
457
- - `sendAnimation(chatId, animation, options)` - Send animation/GIF
458
- - `sendVoice(chatId, voice, options)` - Send voice message
459
- - `sendVideoNote(chatId, videoNote, options)` - Send video note
460
- - `sendSticker(chatId, sticker, options)` - Send sticker
461
- - `sendLocation(chatId, latitude, longitude, options)` - Send location
462
- - `sendVenue(chatId, latitude, longitude, title, address, options)` - Send venue
463
- - `sendContact(chatId, phoneNumber, firstName, options)` - Send contact
464
- - `sendPoll(chatId, question, options, params)` - Send poll
465
- - `sendDice(chatId, options)` - Send dice
466
- - `sendChatAction(chatId, action)` - Send chat action
467
-
468
- #### Edit Methods
469
- - `editMessageText(text, options)` - Edit message text
470
- - `editMessageCaption(options)` - Edit message caption
471
- - `editMessageReplyMarkup(options)` - Edit reply markup
472
- - `deleteMessage(chatId, messageId)` - Delete message
473
-
474
- #### Forward Methods
475
- - `forwardMessage(chatId, fromChatId, messageId, options)` - Forward message
476
- - `copyMessage(chatId, fromChatId, messageId, options)` - Copy message
477
-
478
- #### Chat Methods
479
- - `getChat(chatId)` - Get chat info
480
- - `getChatAdministrators(chatId)` - Get chat administrators
481
- - `getChatMemberCount(chatId)` - Get member count
482
- - `getChatMember(chatId, userId)` - Get chat member
483
- - `setChatTitle(chatId, title)` - Set chat title
484
- - `setChatDescription(chatId, description)` - Set chat description
485
- - `pinChatMessage(chatId, messageId, options)` - Pin message
486
- - `unpinChatMessage(chatId, options)` - Unpin message
487
- - `unpinAllChatMessages(chatId)` - Unpin all messages
488
- - `leaveChat(chatId)` - Leave chat
489
- - `banChatMember(chatId, userId, options)` - Ban member
490
- - `unbanChatMember(chatId, userId, options)` - Unban member
491
- - `restrictChatMember(chatId, userId, permissions, options)` - Restrict member
492
- - `promoteChatMember(chatId, userId, options)` - Promote member
493
-
494
- #### File Methods
495
- - `getFile(fileId)` - Get file info
496
- - `downloadFile(fileId, destination)` - Download file
497
-
498
- #### Other Methods
1241
+ ---
1242
+
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
499
1313
  - `getMe()` - Get bot info
500
- - `answerCallbackQuery(callbackQueryId, options)` - Answer callback query
501
- - `answerInlineQuery(inlineQueryId, results, options)` - Answer inline query
502
-
503
- ### Context Object
504
-
505
- The context object (`ctx`) is passed to command handlers and middleware:
506
-
507
- ```javascript
508
- {
509
- update, // Original update object
510
- bot, // Bot instance
511
- message, // Message object (if available)
512
- callbackQuery, // Callback query (if available)
513
- inlineQuery, // Inline query (if available)
514
- chat, // Chat object
515
- from, // User object
516
- chatId, // Chat ID
517
- reply, // Reply to current chat
518
- replyWithPhoto, // Reply with photo
519
- replyWithDocument, // Reply with document
520
- editMessageText, // Edit message text
521
- answerCallbackQuery, // Answer callback query
522
- deleteMessage // Delete message
523
- }
1314
+ - `getUpdates()` - Get updates (polling)
1315
+ - `startPolling()` - Start long polling
1316
+ - `stopPolling()` - Stop polling
1317
+ - `startWebhook()` - Start webhook server
1318
+ - `stopWebhook()` - Stop webhook server
1319
+
1320
+ ---
1321
+
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
+ }
1334
+ });
524
1335
  ```
525
1336
 
526
- ## Performance Tips
1337
+ ### 2. Rate Limiting
1338
+ ```javascript
1339
+ const rateLimits = new Map();
527
1340
 
528
- 1. **Use Rate Limiting**: The bot automatically handles rate limits with smart retry logic
529
- 2. **Batch Requests**: When possible, batch multiple operations
530
- 3. **Use Webhooks in Production**: Webhooks are more efficient than polling for production bots
531
- 4. **Enable Compression**: Use reverse proxy (nginx) with gzip for webhook endpoints
532
- 5. **Connection Pooling**: The module uses optimized HTTP connection handling
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 });
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();
1361
+ });
1362
+ ```
533
1363
 
534
- ## Best Practices
1364
+ ### 3. Command Parsing
1365
+ ```javascript
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
+ }
1374
+ });
1375
+ ```
1376
+
1377
+ ### 4. Session Management
1378
+ ```javascript
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
+ }
535
1391
 
536
- 1. **Always Handle Errors**: Use try-catch blocks and error event listeners
537
- 2. **Validate User Input**: Always validate and sanitize user input
538
- 3. **Use Middleware for Common Tasks**: Authentication, logging, etc.
539
- 4. **Set Request Timeouts**: Adjust timeouts based on your needs
540
- 5. **Implement Graceful Shutdown**: Clean up resources on exit
1392
+ bot.on('text', async (message, ctx) => {
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}!`);
1399
+ }
1400
+ });
1401
+ ```
541
1402
 
1403
+ ### 5. Async File Operations
542
1404
  ```javascript
543
- process.on('SIGINT', () => {
544
- bot.stopPolling();
545
- console.log('Bot stopped gracefully');
546
- process.exit(0);
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
+ }
547
1418
  });
548
1419
  ```
549
1420
 
550
- ## License
1421
+ ---
1422
+
1423
+ ## 🐛 Troubleshooting
1424
+
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
1430
+
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
1435
+
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
1441
+
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
1446
+
1447
+ ---
1448
+
1449
+ ## 📝 License
1450
+
1451
+ MIT License - See LICENSE file for details
1452
+
1453
+ ## 🤝 Contributing
551
1454
 
552
- MIT
1455
+ Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
553
1456
 
554
- ## Contributing
1457
+ ## 📞 Support
555
1458
 
556
- Contributions are welcome! Please feel free to submit a Pull Request.
1459
+ - Report issues on GitHub
1460
+ - Check examples/ folder for code samples
1461
+ - Read full docs at api.telegram.org/bots/api
557
1462
 
558
- ## Support
1463
+ ---
559
1464
 
560
- For issues and questions, please use the [GitHub Issues](https://github.com/kazedevid/teh/issues) page.
1465
+ **Made with ❤️ by KazeDevID**