teh-bot 1.0.3 → 1.0.5
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 +571 -349
- package/{index.js → dist/index.cjs} +130 -132
- package/{index.d.ts → dist/index.d.ts} +518 -23
- package/dist/index.mjs +1002 -0
- package/package.json +27 -11
package/README.md
CHANGED
|
@@ -1,560 +1,782 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- **
|
|
18
|
-
-
|
|
19
|
-
- **
|
|
1
|
+
# 🤖 Teh Bot - Lightweight Telegram Bot API Library
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
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
|
|
22
|
+
- ✅ **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
|
|
28
|
+
|
|
29
|
+
## 📦 Installation
|
|
30
|
+
|
|
31
|
+
### Using npm
|
|
32
|
+
```bash
|
|
33
|
+
npm install teh-bot
|
|
34
|
+
```
|
|
20
35
|
|
|
21
|
-
|
|
36
|
+
### Using yarn
|
|
37
|
+
```bash
|
|
38
|
+
yarn add teh-bot
|
|
39
|
+
```
|
|
22
40
|
|
|
41
|
+
### Using pnpm
|
|
23
42
|
```bash
|
|
24
|
-
|
|
43
|
+
pnpm add teh-bot
|
|
25
44
|
```
|
|
26
45
|
|
|
27
|
-
## Quick Start
|
|
46
|
+
## 🚀 Quick Start
|
|
28
47
|
|
|
48
|
+
### CommonJS (.js)
|
|
29
49
|
```javascript
|
|
30
50
|
const TelegramBot = require('teh-bot');
|
|
31
51
|
|
|
32
|
-
const bot = new TelegramBot(
|
|
33
|
-
polling: true
|
|
52
|
+
const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
|
|
53
|
+
polling: true,
|
|
34
54
|
});
|
|
35
55
|
|
|
36
|
-
bot.command('start', async (ctx) => {
|
|
37
|
-
await ctx.
|
|
56
|
+
bot.command('/start', async (ctx) => {
|
|
57
|
+
await ctx.send('👋 Hello! I am Teh Bot!');
|
|
38
58
|
});
|
|
39
59
|
|
|
40
60
|
bot.on('text', async (message, ctx) => {
|
|
41
|
-
|
|
61
|
+
console.log('Message:', message.text);
|
|
42
62
|
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Table of Contents
|
|
46
63
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- [Commands](#commands)
|
|
52
|
-
- [Middleware](#middleware)
|
|
53
|
-
- [Events](#events)
|
|
54
|
-
- [File Handling](#file-handling)
|
|
55
|
-
- [Error Handling](#error-handling)
|
|
56
|
-
- [API Reference](#api-reference)
|
|
57
|
-
|
|
58
|
-
## Basic Usage
|
|
59
|
-
|
|
60
|
-
### Initializing the Bot
|
|
64
|
+
bot.on('polling_start', () => {
|
|
65
|
+
console.log('✅ Bot started polling');
|
|
66
|
+
});
|
|
67
|
+
```
|
|
61
68
|
|
|
69
|
+
### ES Modules (.mjs)
|
|
62
70
|
```javascript
|
|
63
|
-
|
|
71
|
+
import TelegramBot from 'teh-bot';
|
|
64
72
|
|
|
65
|
-
const bot = new TelegramBot(
|
|
73
|
+
const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
|
|
66
74
|
polling: true,
|
|
67
|
-
pollingInterval: 1000,
|
|
68
|
-
pollingTimeout: 30
|
|
69
75
|
});
|
|
70
|
-
```
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
bot.command('/start', async (ctx) => {
|
|
78
|
+
await ctx.send('👋 Hello! I am Teh Bot!');
|
|
79
|
+
});
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
81
|
+
bot.on('text', async (message, ctx) => {
|
|
82
|
+
console.log('Message:', message.text);
|
|
83
|
+
});
|
|
82
84
|
|
|
83
|
-
|
|
85
|
+
bot.on('polling_start', () => {
|
|
86
|
+
console.log('✅ Bot started polling');
|
|
87
|
+
});
|
|
88
|
+
```
|
|
84
89
|
|
|
85
|
-
###
|
|
90
|
+
### TypeScript (.ts)
|
|
91
|
+
```typescript
|
|
92
|
+
import TelegramBot, { Context } from 'teh-bot';
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN || '', {
|
|
95
|
+
polling: true,
|
|
96
|
+
});
|
|
89
97
|
|
|
90
|
-
bot.
|
|
98
|
+
bot.command('/start', async (ctx: Context) => {
|
|
99
|
+
await ctx.send('👋 Hello! I am Teh Bot!');
|
|
100
|
+
});
|
|
91
101
|
|
|
92
|
-
bot.on('
|
|
93
|
-
console.
|
|
102
|
+
bot.on('text', async (message, ctx: Context) => {
|
|
103
|
+
console.log('Message:', message.text);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
bot.on('polling_start', () => {
|
|
107
|
+
console.log('✅ Bot started polling');
|
|
94
108
|
});
|
|
95
109
|
```
|
|
96
110
|
|
|
97
|
-
|
|
111
|
+
## ⚙️ Configuration
|
|
98
112
|
|
|
113
|
+
### BotOptions
|
|
99
114
|
```javascript
|
|
100
115
|
const bot = new TelegramBot(token, {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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)
|
|
120
|
+
|
|
121
|
+
// Webhook
|
|
122
|
+
webhook: false, // Enable webhook (default: false)
|
|
123
|
+
webhookPort: 3000, // Webhook server port (default: 3000)
|
|
124
|
+
webhookPath: '/webhook', // Webhook path (default: '/webhook')
|
|
125
|
+
|
|
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)
|
|
104
131
|
});
|
|
132
|
+
```
|
|
105
133
|
|
|
106
|
-
|
|
134
|
+
## 📚 API Reference
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
|
|
136
|
+
### Core Methods
|
|
137
|
+
|
|
138
|
+
#### Sending Messages
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
// Send text message
|
|
142
|
+
await bot.sendMessage(chatId, 'Hello!');
|
|
143
|
+
|
|
144
|
+
// Send text with options
|
|
145
|
+
await bot.sendMessage(chatId, 'Hello!', {
|
|
146
|
+
parse_mode: 'HTML',
|
|
147
|
+
reply_markup: keyboard,
|
|
110
148
|
});
|
|
111
|
-
```
|
|
112
149
|
|
|
113
|
-
|
|
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);
|
|
159
|
+
|
|
160
|
+
// Send location
|
|
161
|
+
await bot.sendLocation(chatId, latitude, longitude);
|
|
162
|
+
|
|
163
|
+
// Send venue
|
|
164
|
+
await bot.sendVenue(chatId, lat, lon, 'Title', 'Address');
|
|
114
165
|
|
|
115
|
-
|
|
166
|
+
// Send contact
|
|
167
|
+
await bot.sendContact(chatId, '+1234567890', 'John');
|
|
168
|
+
|
|
169
|
+
// Send poll
|
|
170
|
+
await bot.sendPoll(chatId, 'Question?', ['Option 1', 'Option 2', 'Option 3']);
|
|
171
|
+
|
|
172
|
+
// Send dice/game
|
|
173
|
+
await bot.sendDice(chatId);
|
|
174
|
+
|
|
175
|
+
// Send chat action (e.g., typing)
|
|
176
|
+
await bot.sendChatAction(chatId, 'typing');
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Message Management
|
|
116
180
|
|
|
117
181
|
```javascript
|
|
118
|
-
|
|
182
|
+
// Edit message
|
|
183
|
+
await bot.editMessageText('New text', {
|
|
184
|
+
chat_id: chatId,
|
|
185
|
+
message_id: messageId,
|
|
186
|
+
parse_mode: 'HTML',
|
|
187
|
+
});
|
|
119
188
|
|
|
120
|
-
|
|
121
|
-
|
|
189
|
+
// Edit caption
|
|
190
|
+
await bot.editMessageCaption({
|
|
191
|
+
chat_id: chatId,
|
|
192
|
+
message_id: messageId,
|
|
193
|
+
caption: 'New caption',
|
|
122
194
|
});
|
|
123
195
|
|
|
124
|
-
|
|
125
|
-
|
|
196
|
+
// Edit reply markup
|
|
197
|
+
await bot.editMessageReplyMarkup({
|
|
198
|
+
chat_id: chatId,
|
|
199
|
+
message_id: messageId,
|
|
200
|
+
reply_markup: newKeyboard,
|
|
126
201
|
});
|
|
202
|
+
|
|
203
|
+
// Delete message
|
|
204
|
+
await bot.deleteMessage(chatId, messageId);
|
|
205
|
+
|
|
206
|
+
// Forward message
|
|
207
|
+
await bot.forwardMessage(chatId, fromChatId, messageId);
|
|
208
|
+
|
|
209
|
+
// Copy message
|
|
210
|
+
await bot.copyMessage(chatId, fromChatId, messageId);
|
|
127
211
|
```
|
|
128
212
|
|
|
129
|
-
|
|
213
|
+
#### Chat Management
|
|
130
214
|
|
|
131
215
|
```javascript
|
|
132
|
-
|
|
216
|
+
// Get chat info
|
|
217
|
+
const chat = await bot.getChat(chatId);
|
|
218
|
+
|
|
219
|
+
// Get chat administrators
|
|
220
|
+
const admins = await bot.getChatAdministrators(chatId);
|
|
221
|
+
|
|
222
|
+
// Get chat member count
|
|
223
|
+
const count = await bot.getChatMemberCount(chatId);
|
|
224
|
+
|
|
225
|
+
// Get specific chat member
|
|
226
|
+
const member = await bot.getChatMember(chatId, userId);
|
|
227
|
+
|
|
228
|
+
// Set chat title
|
|
229
|
+
await bot.setChatTitle(chatId, 'New Title');
|
|
133
230
|
|
|
134
|
-
|
|
231
|
+
// Set chat description
|
|
232
|
+
await bot.setChatDescription(chatId, 'New Description');
|
|
135
233
|
|
|
136
|
-
|
|
234
|
+
// Pin message
|
|
235
|
+
await bot.pinChatMessage(chatId, messageId);
|
|
137
236
|
|
|
138
|
-
|
|
237
|
+
// Unpin message
|
|
238
|
+
await bot.unpinChatMessage(chatId);
|
|
239
|
+
|
|
240
|
+
// Unpin all messages
|
|
241
|
+
await bot.unpinAllChatMessages(chatId);
|
|
242
|
+
|
|
243
|
+
// Leave chat
|
|
244
|
+
await bot.leaveChat(chatId);
|
|
139
245
|
```
|
|
140
246
|
|
|
141
|
-
|
|
247
|
+
#### Member Management
|
|
142
248
|
|
|
143
249
|
```javascript
|
|
144
|
-
|
|
145
|
-
|
|
250
|
+
// Ban member
|
|
251
|
+
await bot.banChatMember(chatId, userId);
|
|
252
|
+
|
|
253
|
+
// Unban member
|
|
254
|
+
await bot.unbanChatMember(chatId, userId);
|
|
255
|
+
|
|
256
|
+
// Restrict member
|
|
257
|
+
await bot.restrictChatMember(chatId, userId, {
|
|
258
|
+
can_send_messages: false,
|
|
259
|
+
can_send_media_messages: false,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// Promote member
|
|
263
|
+
await bot.promoteChatMember(chatId, userId, {
|
|
264
|
+
can_manage_chat: true,
|
|
265
|
+
can_delete_messages: true,
|
|
146
266
|
});
|
|
147
267
|
```
|
|
148
268
|
|
|
149
|
-
|
|
269
|
+
#### File Management
|
|
150
270
|
|
|
151
271
|
```javascript
|
|
152
|
-
|
|
153
|
-
await bot.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
await bot.
|
|
272
|
+
// Get file info
|
|
273
|
+
const file = await bot.getFile(fileId);
|
|
274
|
+
|
|
275
|
+
// Download file
|
|
276
|
+
await bot.downloadFile(fileId, '/path/to/save/file.jpg');
|
|
157
277
|
```
|
|
158
278
|
|
|
159
|
-
|
|
279
|
+
#### Query Handling
|
|
160
280
|
|
|
161
281
|
```javascript
|
|
162
|
-
|
|
282
|
+
// Answer callback query
|
|
283
|
+
await bot.answerCallbackQuery(callbackQueryId, {
|
|
284
|
+
text: 'Button clicked!',
|
|
285
|
+
show_alert: false,
|
|
286
|
+
});
|
|
287
|
+
|
|
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
|
+
]);
|
|
163
297
|
```
|
|
164
298
|
|
|
165
|
-
|
|
299
|
+
#### Bot Methods
|
|
166
300
|
|
|
167
301
|
```javascript
|
|
168
|
-
|
|
302
|
+
// Get bot info
|
|
303
|
+
const me = await bot.getMe();
|
|
304
|
+
|
|
305
|
+
// Get updates
|
|
306
|
+
const updates = await bot.getUpdates();
|
|
307
|
+
|
|
308
|
+
// Set webhook
|
|
309
|
+
await bot.setWebhook('https://example.com/webhook');
|
|
310
|
+
|
|
311
|
+
// Delete webhook
|
|
312
|
+
await bot.deleteWebhook();
|
|
313
|
+
|
|
314
|
+
// Get webhook info
|
|
315
|
+
const info = await bot.getWebhookInfo();
|
|
169
316
|
```
|
|
170
317
|
|
|
171
|
-
###
|
|
318
|
+
### Context Methods (Available in Command Handlers & Events)
|
|
319
|
+
|
|
320
|
+
The `ctx` object provides convenient shorthand methods:
|
|
172
321
|
|
|
173
322
|
```javascript
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
'
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
});
|
|
180
350
|
```
|
|
181
351
|
|
|
182
|
-
##
|
|
352
|
+
## ⌨️ Keyboard Builders
|
|
183
353
|
|
|
184
|
-
### Inline
|
|
354
|
+
### Inline Keyboard
|
|
185
355
|
|
|
186
356
|
```javascript
|
|
187
357
|
const keyboard = TelegramBot.InlineKeyboard()
|
|
188
|
-
.text('Button 1', '
|
|
189
|
-
.text('Button 2', '
|
|
358
|
+
.text('Button 1', 'btn1')
|
|
359
|
+
.text('Button 2', 'btn2')
|
|
190
360
|
.row()
|
|
191
|
-
.url('
|
|
361
|
+
.url('Google', 'https://google.com')
|
|
362
|
+
.url('GitHub', 'https://github.com')
|
|
363
|
+
.row()
|
|
364
|
+
.switchInline('Search', 'query')
|
|
192
365
|
.build();
|
|
193
366
|
|
|
194
|
-
await bot.sendMessage(chatId, 'Choose
|
|
195
|
-
reply_markup: keyboard
|
|
196
|
-
});
|
|
197
|
-
|
|
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');
|
|
202
|
-
}
|
|
203
|
-
});
|
|
367
|
+
await bot.sendMessage(chatId, 'Choose:', { reply_markup: keyboard });
|
|
204
368
|
```
|
|
205
369
|
|
|
206
|
-
### Reply
|
|
370
|
+
### Reply Keyboard
|
|
207
371
|
|
|
208
372
|
```javascript
|
|
209
373
|
const keyboard = TelegramBot.ReplyKeyboard()
|
|
210
374
|
.text('Option 1')
|
|
211
375
|
.text('Option 2')
|
|
212
376
|
.row()
|
|
213
|
-
.
|
|
214
|
-
.
|
|
215
|
-
.
|
|
377
|
+
.requestContact('Share Contact')
|
|
378
|
+
.requestLocation('Share Location')
|
|
379
|
+
.resize(true)
|
|
380
|
+
.oneTime(true)
|
|
216
381
|
.build();
|
|
217
382
|
|
|
218
|
-
await bot.sendMessage(chatId, '
|
|
219
|
-
reply_markup: keyboard
|
|
220
|
-
});
|
|
383
|
+
await bot.sendMessage(chatId, 'Choose:', { reply_markup: keyboard });
|
|
221
384
|
```
|
|
222
385
|
|
|
223
386
|
### Remove Keyboard
|
|
224
387
|
|
|
225
388
|
```javascript
|
|
226
389
|
await bot.sendMessage(chatId, 'Keyboard removed', {
|
|
227
|
-
reply_markup: TelegramBot.RemoveKeyboard()
|
|
390
|
+
reply_markup: TelegramBot.RemoveKeyboard(),
|
|
228
391
|
});
|
|
229
392
|
```
|
|
230
393
|
|
|
231
|
-
###
|
|
394
|
+
### Force Reply
|
|
232
395
|
|
|
233
396
|
```javascript
|
|
234
|
-
|
|
235
|
-
.
|
|
236
|
-
.row()
|
|
237
|
-
.requestLocation('Share Location')
|
|
238
|
-
.resize()
|
|
239
|
-
.build();
|
|
240
|
-
|
|
241
|
-
await bot.sendMessage(chatId, 'Please share your info:', {
|
|
242
|
-
reply_markup: keyboard
|
|
397
|
+
await bot.sendMessage(chatId, 'Reply to me:', {
|
|
398
|
+
reply_markup: TelegramBot.ForceReply(),
|
|
243
399
|
});
|
|
244
400
|
```
|
|
245
401
|
|
|
246
|
-
##
|
|
402
|
+
## 🎯 Event Handling
|
|
247
403
|
|
|
248
|
-
###
|
|
404
|
+
### Message Events
|
|
249
405
|
|
|
250
406
|
```javascript
|
|
251
|
-
|
|
252
|
-
|
|
407
|
+
// All messages
|
|
408
|
+
bot.on('message', (message, ctx) => {});
|
|
409
|
+
|
|
410
|
+
// Text messages
|
|
411
|
+
bot.on('text', (message, ctx) => {});
|
|
412
|
+
|
|
413
|
+
// Photo messages
|
|
414
|
+
bot.on('photo', (message, ctx) => {});
|
|
415
|
+
|
|
416
|
+
// Video messages
|
|
417
|
+
bot.on('video', (message, ctx) => {});
|
|
418
|
+
|
|
419
|
+
// Audio messages
|
|
420
|
+
bot.on('audio', (message, ctx) => {});
|
|
421
|
+
|
|
422
|
+
// Document messages
|
|
423
|
+
bot.on('document', (message, ctx) => {});
|
|
424
|
+
|
|
425
|
+
// Voice messages
|
|
426
|
+
bot.on('voice', (message, ctx) => {});
|
|
427
|
+
|
|
428
|
+
// Sticker messages
|
|
429
|
+
bot.on('sticker', (message, ctx) => {});
|
|
430
|
+
|
|
431
|
+
// Location messages
|
|
432
|
+
bot.on('location', (message, ctx) => {});
|
|
433
|
+
|
|
434
|
+
// Contact messages
|
|
435
|
+
bot.on('contact', (message, ctx) => {});
|
|
436
|
+
|
|
437
|
+
// Edited messages
|
|
438
|
+
bot.on('edited_message', (message, ctx) => {});
|
|
439
|
+
|
|
440
|
+
// Channel posts
|
|
441
|
+
bot.on('channel_post', (message, ctx) => {});
|
|
442
|
+
|
|
443
|
+
// Edited channel posts
|
|
444
|
+
bot.on('edited_channel_post', (message, ctx) => {});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Query Events
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
// Callback queries (from inline buttons)
|
|
451
|
+
bot.on('callback_query', (query, ctx) => {
|
|
452
|
+
console.log(query.data); // Button callback data
|
|
253
453
|
});
|
|
254
454
|
|
|
255
|
-
|
|
256
|
-
|
|
455
|
+
// Inline queries
|
|
456
|
+
bot.on('inline_query', (query, ctx) => {
|
|
457
|
+
console.log(query.query); // Search query
|
|
257
458
|
});
|
|
459
|
+
|
|
460
|
+
// Chosen inline result
|
|
461
|
+
bot.on('chosen_inline_result', (result, ctx) => {});
|
|
258
462
|
```
|
|
259
463
|
|
|
260
|
-
###
|
|
464
|
+
### Poll Events
|
|
261
465
|
|
|
262
466
|
```javascript
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
467
|
+
// Poll updates
|
|
468
|
+
bot.on('poll', (poll, ctx) => {});
|
|
469
|
+
|
|
470
|
+
// Poll answers
|
|
471
|
+
bot.on('poll_answer', (answer, ctx) => {});
|
|
266
472
|
```
|
|
267
473
|
|
|
268
|
-
###
|
|
474
|
+
### Chat Member Events
|
|
269
475
|
|
|
270
476
|
```javascript
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
});
|
|
477
|
+
// Bot added/removed from chat
|
|
478
|
+
bot.on('my_chat_member', (member, ctx) => {});
|
|
479
|
+
|
|
480
|
+
// User added/removed from chat
|
|
481
|
+
bot.on('chat_member', (member, ctx) => {});
|
|
278
482
|
```
|
|
279
483
|
|
|
280
|
-
|
|
484
|
+
### System Events
|
|
485
|
+
|
|
486
|
+
```javascript
|
|
487
|
+
// Update received
|
|
488
|
+
bot.on('update', (update) => {});
|
|
489
|
+
|
|
490
|
+
// Polling started
|
|
491
|
+
bot.on('polling_start', () => {});
|
|
492
|
+
|
|
493
|
+
// Polling stopped
|
|
494
|
+
bot.on('polling_stop', () => {});
|
|
495
|
+
|
|
496
|
+
// Polling error
|
|
497
|
+
bot.on('polling_error', (error) => {});
|
|
498
|
+
|
|
499
|
+
// Webhook started
|
|
500
|
+
bot.on('webhook_start', (port) => {});
|
|
501
|
+
|
|
502
|
+
// Webhook stopped
|
|
503
|
+
bot.on('webhook_stop', () => {});
|
|
504
|
+
|
|
505
|
+
// Webhook error
|
|
506
|
+
bot.on('webhook_error', (error) => {});
|
|
507
|
+
|
|
508
|
+
// General error
|
|
509
|
+
bot.on('error', (error) => {});
|
|
510
|
+
```
|
|
281
511
|
|
|
282
|
-
|
|
512
|
+
## 🔧 Middleware
|
|
283
513
|
|
|
284
514
|
```javascript
|
|
515
|
+
// Logging middleware
|
|
285
516
|
bot.use(async (ctx, next) => {
|
|
286
|
-
console.log(
|
|
517
|
+
console.log(`[${new Date().toISOString()}] Message from ${ctx.from?.username}`);
|
|
287
518
|
await next();
|
|
288
519
|
});
|
|
289
520
|
|
|
521
|
+
// Rate limiting middleware
|
|
522
|
+
const userCalls = new Map();
|
|
290
523
|
bot.use(async (ctx, next) => {
|
|
291
|
-
|
|
524
|
+
const userId = ctx.from?.id;
|
|
525
|
+
if (!userId) return;
|
|
526
|
+
|
|
527
|
+
const calls = userCalls.get(userId) || 0;
|
|
528
|
+
if (calls > 5) {
|
|
529
|
+
await ctx.send('Rate limited!');
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
userCalls.set(userId, calls + 1);
|
|
534
|
+
await next();
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
// Permission checking middleware
|
|
538
|
+
bot.use(async (ctx, next) => {
|
|
539
|
+
const allowedUsers = [123456789, 987654321];
|
|
540
|
+
if (!allowedUsers.includes(ctx.from?.id || 0)) {
|
|
541
|
+
await ctx.send('❌ Not authorized');
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
292
544
|
await next();
|
|
293
|
-
const duration = Date.now() - ctx.startTime;
|
|
294
|
-
console.log(`Request took ${duration}ms`);
|
|
295
545
|
});
|
|
296
546
|
```
|
|
297
547
|
|
|
298
|
-
|
|
548
|
+
## 📋 Command Handling
|
|
549
|
+
|
|
550
|
+
### Single Command
|
|
299
551
|
|
|
300
552
|
```javascript
|
|
301
|
-
|
|
553
|
+
bot.command('/start', async (ctx) => {
|
|
554
|
+
await ctx.send('Welcome!');
|
|
555
|
+
});
|
|
302
556
|
|
|
303
|
-
bot.
|
|
304
|
-
|
|
305
|
-
await next();
|
|
306
|
-
} else {
|
|
307
|
-
await ctx.reply('You are not authorized to use this bot.');
|
|
308
|
-
}
|
|
557
|
+
bot.command('help', async (ctx) => { // With or without /
|
|
558
|
+
await ctx.send('Need help?');
|
|
309
559
|
});
|
|
310
560
|
```
|
|
311
561
|
|
|
312
|
-
###
|
|
562
|
+
### Multiple Commands
|
|
313
563
|
|
|
314
564
|
```javascript
|
|
315
|
-
bot.
|
|
316
|
-
|
|
317
|
-
const message = ctx.message?.text || 'no text';
|
|
318
|
-
console.log(`[${new Date().toISOString()}] ${user}: ${message}`);
|
|
319
|
-
await next();
|
|
565
|
+
bot.command(['/help', '/h', 'help'], async (ctx) => {
|
|
566
|
+
await ctx.send('Here is help');
|
|
320
567
|
});
|
|
321
568
|
```
|
|
322
569
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
### Message Events
|
|
570
|
+
### Get Command Handler
|
|
326
571
|
|
|
327
572
|
```javascript
|
|
328
|
-
bot.
|
|
329
|
-
|
|
330
|
-
|
|
573
|
+
const handler = bot.command('/start'); // Get without registering
|
|
574
|
+
if (handler) {
|
|
575
|
+
handler(ctx); // Call the handler
|
|
576
|
+
}
|
|
577
|
+
```
|
|
331
578
|
|
|
332
|
-
|
|
333
|
-
console.log('Text message:', message.text);
|
|
334
|
-
});
|
|
579
|
+
## 🌐 Webhook Mode
|
|
335
580
|
|
|
336
|
-
|
|
337
|
-
|
|
581
|
+
```javascript
|
|
582
|
+
const bot = new TelegramBot(token, {
|
|
583
|
+
webhook: true,
|
|
584
|
+
webhookPort: 3000,
|
|
585
|
+
webhookPath: '/webhook',
|
|
338
586
|
});
|
|
339
587
|
|
|
340
|
-
|
|
341
|
-
|
|
588
|
+
// Webhook events
|
|
589
|
+
bot.on('webhook_start', (port) => {
|
|
590
|
+
console.log(`✅ Webhook listening on port ${port}`);
|
|
342
591
|
});
|
|
343
592
|
|
|
344
|
-
bot.on('
|
|
345
|
-
console.log('
|
|
593
|
+
bot.on('webhook_stop', () => {
|
|
594
|
+
console.log('Webhook stopped');
|
|
346
595
|
});
|
|
347
596
|
|
|
348
|
-
bot.on('
|
|
349
|
-
|
|
597
|
+
bot.on('webhook_error', (error) => {
|
|
598
|
+
console.error('Webhook error:', error);
|
|
350
599
|
});
|
|
351
600
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
await ctx.reply(`You are at: ${latitude}, ${longitude}`);
|
|
355
|
-
});
|
|
601
|
+
// Start webhook
|
|
602
|
+
bot.startWebhook();
|
|
356
603
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
});
|
|
604
|
+
// Stop webhook
|
|
605
|
+
bot.stopWebhook();
|
|
360
606
|
```
|
|
361
607
|
|
|
362
|
-
|
|
608
|
+
## 🔄 Polling Mode
|
|
363
609
|
|
|
364
610
|
```javascript
|
|
365
|
-
bot
|
|
366
|
-
|
|
611
|
+
const bot = new TelegramBot(token, {
|
|
612
|
+
polling: true,
|
|
613
|
+
pollingInterval: 1000,
|
|
614
|
+
pollingTimeout: 30,
|
|
367
615
|
});
|
|
368
616
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
});
|
|
617
|
+
// Start polling
|
|
618
|
+
await bot.startPolling();
|
|
372
619
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
});
|
|
620
|
+
// Stop polling
|
|
621
|
+
bot.stopPolling();
|
|
376
622
|
```
|
|
377
623
|
|
|
378
|
-
|
|
624
|
+
## 📤 Advanced Examples
|
|
379
625
|
|
|
380
|
-
|
|
381
|
-
bot.on('error', (error) => {
|
|
382
|
-
console.error('Bot error:', error);
|
|
383
|
-
});
|
|
626
|
+
### Image Processing Bot
|
|
384
627
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
});
|
|
628
|
+
```javascript
|
|
629
|
+
const fs = require('fs');
|
|
388
630
|
|
|
389
|
-
bot.on('
|
|
390
|
-
|
|
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!');
|
|
391
635
|
});
|
|
392
636
|
```
|
|
393
637
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
### Download Files
|
|
638
|
+
### Interactive Menu
|
|
397
639
|
|
|
398
640
|
```javascript
|
|
399
|
-
bot.
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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();
|
|
648
|
+
|
|
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;
|
|
407
665
|
}
|
|
408
666
|
});
|
|
409
667
|
```
|
|
410
668
|
|
|
411
|
-
###
|
|
669
|
+
### Survey Bot
|
|
412
670
|
|
|
413
671
|
```javascript
|
|
414
|
-
|
|
415
|
-
console.log(
|
|
416
|
-
console.log(
|
|
417
|
-
|
|
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
|
+
});
|
|
418
679
|
|
|
419
|
-
|
|
680
|
+
bot.on('poll_answer', async (answer, ctx) => {
|
|
681
|
+
console.log(`User ${answer.user.id} voted for options: ${answer.option_ids}`);
|
|
682
|
+
});
|
|
683
|
+
```
|
|
420
684
|
|
|
421
|
-
###
|
|
685
|
+
### Auto-responder
|
|
422
686
|
|
|
423
687
|
```javascript
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
688
|
+
const responses = {
|
|
689
|
+
hello: '👋 Hello! How can I help?',
|
|
690
|
+
hi: '👋 Hi there!',
|
|
691
|
+
bye: '👋 Goodbye!',
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
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);
|
|
429
699
|
}
|
|
430
700
|
});
|
|
431
701
|
```
|
|
432
702
|
|
|
433
|
-
|
|
703
|
+
## 🐛 Error Handling
|
|
434
704
|
|
|
435
705
|
```javascript
|
|
436
706
|
bot.on('error', (error) => {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
console.error('Unexpected error:', error);
|
|
443
|
-
}
|
|
707
|
+
console.error('Bot error:', {
|
|
708
|
+
message: error.message,
|
|
709
|
+
code: error.errorCode,
|
|
710
|
+
response: error.response,
|
|
711
|
+
});
|
|
444
712
|
});
|
|
445
|
-
```
|
|
446
713
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
|
499
|
-
- `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:
|
|
714
|
+
bot.on('polling_error', (error) => {
|
|
715
|
+
console.error('Polling error:', error.message);
|
|
716
|
+
// Auto-reconnect happens automatically
|
|
717
|
+
});
|
|
506
718
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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
|
|
719
|
+
try {
|
|
720
|
+
await bot.sendMessage(chatId, 'message');
|
|
721
|
+
} catch (error) {
|
|
722
|
+
console.error('Send failed:', error.message);
|
|
523
723
|
}
|
|
524
724
|
```
|
|
525
725
|
|
|
526
|
-
##
|
|
726
|
+
## 📊 Telegram Bot API Coverage
|
|
527
727
|
|
|
528
|
-
|
|
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
|
|
728
|
+
### ✅ Implemented Features
|
|
533
729
|
|
|
534
|
-
|
|
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
|
|
535
741
|
|
|
536
|
-
|
|
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
|
|
742
|
+
## 🔌 Environment Setup
|
|
541
743
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
744
|
+
### Get Your Bot Token
|
|
745
|
+
|
|
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
|
|
750
|
+
|
|
751
|
+
### Set Environment Variable
|
|
752
|
+
|
|
753
|
+
```bash
|
|
754
|
+
export TELEGRAM_BOT_TOKEN="YOUR_TOKEN_HERE"
|
|
548
755
|
```
|
|
549
756
|
|
|
550
|
-
|
|
757
|
+
Or in `.env` file:
|
|
758
|
+
```env
|
|
759
|
+
TELEGRAM_BOT_TOKEN=your_token_here
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
## 📝 License
|
|
551
763
|
|
|
552
|
-
MIT
|
|
764
|
+
MIT License - See LICENSE file for details
|
|
553
765
|
|
|
554
|
-
## Contributing
|
|
766
|
+
## 🤝 Contributing
|
|
555
767
|
|
|
556
768
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
557
769
|
|
|
558
|
-
## Support
|
|
770
|
+
## 📞 Support
|
|
771
|
+
|
|
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.
|
|
779
|
+
|
|
780
|
+
---
|
|
559
781
|
|
|
560
|
-
|
|
782
|
+
**Happy botting! 🤖**
|