zerogramjs 2.1.0
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 +587 -0
- package/index.js +18 -0
- package/lib/Context.js +195 -0
- package/lib/Downloader.js +234 -0
- package/lib/Router.js +152 -0
- package/lib/Session.js +77 -0
- package/lib/Zerogram.js +325 -0
- package/package.json +25 -0
- package/shared/downloadState.js +9 -0
- package/utils/ffmpeg.js +152 -0
- package/utils/loader.js +71 -0
- package/utils/markdown.js +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
|
|
2
|
+
# 🚀 ZerogramJS 2.1
|
|
3
|
+
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
Framework moderno y elegante para crear bots de Telegram con Node.js.
|
|
7
|
+
|
|
8
|
+
## ✨ Características
|
|
9
|
+
|
|
10
|
+
- 🎯 **API Simple**: Sintaxis clara y expresiva
|
|
11
|
+
- 📦 **Modular**: Arquitectura bien organizada
|
|
12
|
+
- ⚡ **Descargas Avanzadas**: Con progreso, lotes y cancelación
|
|
13
|
+
- 🎨 **Markdown Personalizado**: Soporte para formateo rico
|
|
14
|
+
- 🎬 **FFmpeg Integrado**: Generación de thumbnails y análisis de videos
|
|
15
|
+
- 🔄 **Middleware**: Sistema de middlewares tipo Express
|
|
16
|
+
- 💾 **Sesiones**: Persistencia automática
|
|
17
|
+
- 🛡️ **Robusto**: Manejo de errores y reintentos automáticos
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Instalación
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install telegram debug
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Copia la carpeta `zerogram/` a tu proyecto.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 🚀 Inicio Rápido
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
const Zerogram = require('./zerogram');
|
|
35
|
+
|
|
36
|
+
const bot = new Zerogram(
|
|
37
|
+
12345678, // API ID
|
|
38
|
+
'your_api_hash', // API Hash
|
|
39
|
+
'bot:token', // Bot Token
|
|
40
|
+
{
|
|
41
|
+
debug: true,
|
|
42
|
+
sessionsDir: './sessions'
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// Inicializar
|
|
47
|
+
await bot.init();
|
|
48
|
+
|
|
49
|
+
// Comando simple
|
|
50
|
+
bot.command('start', async (ctx) => {
|
|
51
|
+
await ctx.reply('¡Hola! Soy tu bot 🤖');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Comando con argumentos
|
|
55
|
+
bot.command('echo', async (ctx, args) => {
|
|
56
|
+
await ctx.reply(args.join(' ') || 'Envía algo para hacer echo');
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 📚 API Reference
|
|
63
|
+
|
|
64
|
+
### Constructor
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
new Zerogram(apiId, apiHash, botToken, options)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Parámetros:**
|
|
71
|
+
- `apiId` (number): Tu API ID de Telegram
|
|
72
|
+
- `apiHash` (string): Tu API Hash
|
|
73
|
+
- `botToken` (string): Token del bot de @BotFather
|
|
74
|
+
- `options` (object):
|
|
75
|
+
- `debug` (boolean): Activar logs de debug
|
|
76
|
+
- `sessionsDir` (string): Directorio para sesiones
|
|
77
|
+
- `maxRetries` (number): Reintentos de conexión (default: 3)
|
|
78
|
+
- `retryDelay` (number): Delay entre reintentos en ms (default: 2000)
|
|
79
|
+
|
|
80
|
+
### Métodos Principales
|
|
81
|
+
|
|
82
|
+
#### `bot.init()`
|
|
83
|
+
Inicializa la conexión con Telegram.
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
await bot.init();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `bot.command(name, handler)`
|
|
90
|
+
Registra un comando.
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
bot.command('help', async (ctx, args) => {
|
|
94
|
+
await ctx.reply('**Comandos disponibles:**\n/start\n/help');
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `bot.onCallback(action, handler)`
|
|
99
|
+
Registra un callback para botones inline.
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
bot.onCallback('like', async (ctx) => {
|
|
103
|
+
await ctx.client.sendMessage(ctx.userId, {
|
|
104
|
+
message: '¡Te gustó! ❤️'
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### `bot.use(middleware)`
|
|
110
|
+
Registra un middleware.
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
bot.use(async (ctx, next) => {
|
|
114
|
+
console.log('Nueva actualización:', ctx.update);
|
|
115
|
+
await next();
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `bot.stop()`
|
|
120
|
+
Detiene el bot de forma segura.
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
await bot.stop();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 🎯 Context (ctx)
|
|
129
|
+
|
|
130
|
+
Cada handler recibe un objeto `ctx` enriquecido:
|
|
131
|
+
|
|
132
|
+
### Propiedades
|
|
133
|
+
|
|
134
|
+
- `ctx.bot`: Instancia del bot
|
|
135
|
+
- `ctx.client`: Cliente de Telegram
|
|
136
|
+
- `ctx.update`: Actualización raw de Telegram
|
|
137
|
+
- `ctx.message`: Objeto del mensaje
|
|
138
|
+
|
|
139
|
+
### Métodos
|
|
140
|
+
|
|
141
|
+
#### `ctx.reply(text, options)`
|
|
142
|
+
Responde al mensaje actual.
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
await ctx.reply('**Negrita**, __cursiva__, `código`');
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### `ctx.send(text, options)`
|
|
149
|
+
Envía un mensaje al chat actual.
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
await ctx.send('Hola mundo', { parseMode: 'html' });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### `ctx.sendFile(file, options)`
|
|
156
|
+
Envía un archivo.
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
await ctx.sendFile('./photo.jpg', {
|
|
160
|
+
caption: 'Mira esta foto'
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### `ctx.getReplyMessage()`
|
|
165
|
+
Obtiene el mensaje al que se está respondiendo.
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
const replyMsg = await ctx.getReplyMessage();
|
|
169
|
+
if (replyMsg) {
|
|
170
|
+
console.log('Respondiendo a:', replyMsg.text);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### `ctx.downloadMedia(message, options)`
|
|
175
|
+
Descarga medios con progreso.
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
const buffer = await ctx.downloadMedia(message, {
|
|
179
|
+
filePath: './downloads/video.mp4',
|
|
180
|
+
onProgress: (progress) => {
|
|
181
|
+
console.log(`${progress.percent.toFixed(1)}% - ${progress.speed} bytes/s`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### `ctx.downloadMediaBatch(messages, options)`
|
|
187
|
+
Descarga múltiples archivos.
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
const results = await ctx.downloadMediaBatch(messages, {
|
|
191
|
+
dir: './downloads',
|
|
192
|
+
onProgress: (p) => {
|
|
193
|
+
console.log(`Archivo ${p.index}/${p.total}: ${p.percent.toFixed(1)}%`);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### `ctx.thumbFromVideo(buffer, options)`
|
|
199
|
+
Genera un thumbnail de un video.
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
const thumbnail = await ctx.thumbFromVideo(videoBuffer, {
|
|
203
|
+
seek: 1.5, // Segundo 1.5
|
|
204
|
+
width: 320
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 🎨 Formato de Texto
|
|
211
|
+
|
|
212
|
+
Zerogram soporta markdown personalizado:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
await ctx.reply('**Negrita**');
|
|
216
|
+
await ctx.reply('__Cursiva__');
|
|
217
|
+
await ctx.reply('`Código`');
|
|
218
|
+
await ctx.reply('[Link](https://example.com)');
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 🔘 Botones
|
|
224
|
+
|
|
225
|
+
### Inline Buttons
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
const Zerogram = require('./zerogram');
|
|
229
|
+
|
|
230
|
+
// Crear botones
|
|
231
|
+
const buttons = [
|
|
232
|
+
[
|
|
233
|
+
Zerogram.createButton('👍 Like', 'like:123'),
|
|
234
|
+
Zerogram.createButton('👎 Dislike', 'dislike:123')
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
Zerogram.urlButton('🌐 Website', 'https://example.com')
|
|
238
|
+
]
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
await ctx.reply('¿Te gusta?', { buttons });
|
|
242
|
+
|
|
243
|
+
// Manejar callback
|
|
244
|
+
bot.onCallback('like', async (ctx) => {
|
|
245
|
+
await ctx.client.answerCallbackQuery(ctx.queryId, {
|
|
246
|
+
message: '¡Gracias!',
|
|
247
|
+
alert: false
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 🔄 Middlewares
|
|
255
|
+
|
|
256
|
+
Los middlewares se ejecutan antes de los handlers:
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
// Logger
|
|
260
|
+
bot.use(async (ctx, next) => {
|
|
261
|
+
console.log(`[${new Date().toISOString()}] Update received`);
|
|
262
|
+
await next();
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Auth
|
|
266
|
+
bot.use(async (ctx, next) => {
|
|
267
|
+
const userId = ctx.message?.peerId?.userId;
|
|
268
|
+
if (!isAllowed(userId)) {
|
|
269
|
+
await ctx.reply('No autorizado');
|
|
270
|
+
return; // No llamar a next()
|
|
271
|
+
}
|
|
272
|
+
await next();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Error handler
|
|
276
|
+
bot.use(async (ctx, next) => {
|
|
277
|
+
try {
|
|
278
|
+
await next();
|
|
279
|
+
} catch (error) {
|
|
280
|
+
console.error('Error:', error);
|
|
281
|
+
await ctx.reply('❌ Ocurrió un error');
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 📥 Descargas Avanzadas
|
|
289
|
+
|
|
290
|
+
### Con Cancelación
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
const controller = new AbortController();
|
|
294
|
+
|
|
295
|
+
// Guardar en map global
|
|
296
|
+
ctx.downloadControllers.set(userId, controller);
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
const buffer = await ctx.downloadMedia(message, {
|
|
300
|
+
controller,
|
|
301
|
+
onProgress: (p) => {
|
|
302
|
+
statusMsg.safeEdit(`Descargando: ${p.percent.toFixed(1)}%`);
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
} catch (error) {
|
|
306
|
+
if (error.message === 'DOWNLOAD_CANCELLED') {
|
|
307
|
+
await ctx.reply('⚠️ Descarga cancelada');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Para cancelar:
|
|
312
|
+
const controller = ctx.downloadControllers.get(userId);
|
|
313
|
+
if (controller) {
|
|
314
|
+
controller.abort();
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Descarga en Lote
|
|
319
|
+
|
|
320
|
+
```javascript
|
|
321
|
+
const messages = await ctx.client.getMessages(chatId, { limit: 10 });
|
|
322
|
+
|
|
323
|
+
const results = await ctx.downloadMediaBatch(messages, {
|
|
324
|
+
dir: './downloads',
|
|
325
|
+
onProgress: (p) => {
|
|
326
|
+
statusMsg.safeEdit(
|
|
327
|
+
`📥 Descargando archivo ${p.index}/${p.total}\n` +
|
|
328
|
+
`Progreso: ${p.overallPercent.toFixed(1)}%\n` +
|
|
329
|
+
`Velocidad: ${formatSpeed(p.speed)}`
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
console.log('Descargados:', results.map(r => r.filePath));
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 🎬 FFmpeg
|
|
340
|
+
|
|
341
|
+
Zerogram incluye utilidades para trabajar con videos:
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
// Generar thumbnail
|
|
345
|
+
const thumbnail = await ctx.thumbFromVideo(videoBuffer, {
|
|
346
|
+
seek: 2.5, // Capturar en el segundo 2.5
|
|
347
|
+
width: 320, // Ancho del thumbnail
|
|
348
|
+
timeout: 10000 // Timeout en ms
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
await ctx.sendFile(thumbnail, {
|
|
352
|
+
caption: 'Thumbnail del video'
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Obtener duración
|
|
356
|
+
const duration = await ctx.bot.ffutil.duration(videoBuffer);
|
|
357
|
+
console.log(`Duración: ${duration}s`);
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## 📁 Carga Automática de Módulos
|
|
363
|
+
|
|
364
|
+
### Estructura de carpetas
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
my-bot/
|
|
368
|
+
├── commands/
|
|
369
|
+
│ ├── start.js
|
|
370
|
+
│ ├── help.js
|
|
371
|
+
│ └── download.js
|
|
372
|
+
├── callbacks/
|
|
373
|
+
│ └── actions.js
|
|
374
|
+
└── index.js
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### commands/start.js
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
module.exports = async (ctx) => {
|
|
381
|
+
await ctx.reply('¡Bienvenido! 👋');
|
|
382
|
+
};
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### callbacks/actions.js
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
module.exports = {
|
|
389
|
+
like: async (ctx) => {
|
|
390
|
+
await ctx.reply('¡Te gustó! ❤️');
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
dislike: async (ctx) => {
|
|
394
|
+
await ctx.reply('No te gustó 💔');
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### index.js
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
const Zerogram = require('./zerogram');
|
|
403
|
+
const path = require('path');
|
|
404
|
+
|
|
405
|
+
const bot = new Zerogram(apiId, apiHash, botToken);
|
|
406
|
+
await bot.init();
|
|
407
|
+
|
|
408
|
+
// Cargar comandos
|
|
409
|
+
await Zerogram.loadModules(
|
|
410
|
+
path.join(__dirname, 'commands'),
|
|
411
|
+
'command',
|
|
412
|
+
(name, handler) => bot.command(name, handler)
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
// Cargar callbacks
|
|
416
|
+
await Zerogram.loadModules(
|
|
417
|
+
path.join(__dirname, 'callbacks'),
|
|
418
|
+
'callback',
|
|
419
|
+
(name, handler) => bot.onCallback(name, handler)
|
|
420
|
+
);
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## 🛡️ Manejo de Errores
|
|
426
|
+
|
|
427
|
+
### FloodWait Automático
|
|
428
|
+
|
|
429
|
+
Zerogram maneja automáticamente los errores de FloodWait:
|
|
430
|
+
|
|
431
|
+
```javascript
|
|
432
|
+
// Se reintentará automáticamente después del tiempo requerido
|
|
433
|
+
await bot.init();
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Eventos
|
|
437
|
+
|
|
438
|
+
```javascript
|
|
439
|
+
bot.on('ready', () => {
|
|
440
|
+
console.log('✅ Bot iniciado');
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
bot.on('error', (error) => {
|
|
444
|
+
console.error('❌ Error:', error);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
bot.on('unhandled', (ctx) => {
|
|
448
|
+
console.log('⚠️ Update no manejado:', ctx.update);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
bot.on('stopped', () => {
|
|
452
|
+
console.log('🛑 Bot detenido');
|
|
453
|
+
});
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 📝 Ejemplos Completos
|
|
459
|
+
|
|
460
|
+
### Bot de Descargas
|
|
461
|
+
|
|
462
|
+
```javascript
|
|
463
|
+
const Zerogram = require('./zerogram');
|
|
464
|
+
const path = require('path');
|
|
465
|
+
|
|
466
|
+
const bot = new Zerogram(apiId, apiHash, botToken);
|
|
467
|
+
await bot.init();
|
|
468
|
+
|
|
469
|
+
bot.command('download', async (ctx) => {
|
|
470
|
+
const replyMsg = await ctx.getReplyMessage();
|
|
471
|
+
|
|
472
|
+
if (!replyMsg?.media) {
|
|
473
|
+
return ctx.reply('❌ Responde a un archivo para descargarlo');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const statusMsg = await ctx.reply('📥 Descargando...');
|
|
477
|
+
const userId = ctx.message.peerId.userId.toString();
|
|
478
|
+
const controller = new AbortController();
|
|
479
|
+
|
|
480
|
+
ctx.downloadControllers.set(userId, controller);
|
|
481
|
+
|
|
482
|
+
try {
|
|
483
|
+
await ctx.downloadMedia(replyMsg, {
|
|
484
|
+
filePath: path.join('./downloads', `file_${Date.now()}`),
|
|
485
|
+
controller,
|
|
486
|
+
onProgress: (p) => {
|
|
487
|
+
statusMsg.safeEdit(
|
|
488
|
+
`📥 Descargando: ${p.percent.toFixed(1)}%\n` +
|
|
489
|
+
`Velocidad: ${(p.speed / 1024 / 1024).toFixed(2)} MB/s`
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
await statusMsg.safeEdit('✅ Descarga completada');
|
|
495
|
+
} catch (error) {
|
|
496
|
+
if (error.message === 'DOWNLOAD_CANCELLED') {
|
|
497
|
+
await statusMsg.safeEdit('⚠️ Descarga cancelada');
|
|
498
|
+
} else {
|
|
499
|
+
await statusMsg.safeEdit('❌ Error en la descarga');
|
|
500
|
+
}
|
|
501
|
+
} finally {
|
|
502
|
+
ctx.downloadControllers.delete(userId);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
bot.command('cancel', async (ctx) => {
|
|
507
|
+
const userId = ctx.message.peerId.userId.toString();
|
|
508
|
+
const controller = ctx.downloadControllers.get(userId);
|
|
509
|
+
|
|
510
|
+
if (controller) {
|
|
511
|
+
controller.abort();
|
|
512
|
+
await ctx.reply('🛑 Cancelando descarga...');
|
|
513
|
+
} else {
|
|
514
|
+
await ctx.reply('⚠️ No hay descargas en curso');
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## 🔧 Configuración Avanzada
|
|
522
|
+
|
|
523
|
+
### Variables de Entorno
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
# FFmpeg paths (opcional)
|
|
527
|
+
export FFMPEG_PATH=/usr/bin/ffmpeg
|
|
528
|
+
export FFPROBE_PATH=/usr/bin/ffprobe
|
|
529
|
+
|
|
530
|
+
# Debug
|
|
531
|
+
export DEBUG=zerogram*
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Opciones de Cliente
|
|
535
|
+
|
|
536
|
+
```javascript
|
|
537
|
+
const bot = new Zerogram(apiId, apiHash, botToken, {
|
|
538
|
+
debug: true,
|
|
539
|
+
sessionsDir: './sessions',
|
|
540
|
+
maxRetries: 5,
|
|
541
|
+
retryDelay: 3000,
|
|
542
|
+
connectionRetries: 3,
|
|
543
|
+
useWSS: true,
|
|
544
|
+
maxConcurrentDownloads: 2
|
|
545
|
+
});
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## 📄 Licencia
|
|
551
|
+
|
|
552
|
+
MIT
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 🤝 Contribuciones
|
|
557
|
+
|
|
558
|
+
¡Las contribuciones son bienvenidas! Por favor:
|
|
559
|
+
|
|
560
|
+
1. Fork el proyecto
|
|
561
|
+
2. Crea una rama para tu feature
|
|
562
|
+
3. Commit tus cambios
|
|
563
|
+
4. Push a la rama
|
|
564
|
+
5. Abre un Pull Request
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## 💡 Tips
|
|
569
|
+
|
|
570
|
+
1. **Usa `safeEdit`** para editar mensajes sin errores si el mensaje ya fue eliminado
|
|
571
|
+
2. **Cancela descargas** guardando el `AbortController` en un Map global
|
|
572
|
+
3. **Middlewares** son perfectos para logging, auth y error handling
|
|
573
|
+
4. **Carga automática** mantiene tu código organizado en archivos separados
|
|
574
|
+
5. **FFmpeg** requiere tener instalado ffmpeg y ffprobe en tu sistema
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
## 📞 Soporte
|
|
579
|
+
|
|
580
|
+
- Issues: [GitHub Issues]
|
|
581
|
+
- Telegram: [https://t.me/Bots0075]
|
|
582
|
+
- Docs: [https://github.com/UserZero075/ZerogramJS/blob/main/README.md]
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
**Made with ❤️ for the Telegram Bot community**
|
|
587
|
+
```
|
package/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zerogram 2.1 - Modern Telegram Bot Framework
|
|
3
|
+
* @module zerogram
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const Zerogram = require('./lib/Zerogram');
|
|
7
|
+
const { parseMarkdown, markdownToHtml, markdownToMarkdownV2 } = require('./utils/markdown');
|
|
8
|
+
const { FFMpegUtil } = require('./utils/ffmpeg');
|
|
9
|
+
const { loadModules } = require('./utils/loader');
|
|
10
|
+
|
|
11
|
+
// Exportaciones principales
|
|
12
|
+
module.exports = Zerogram;
|
|
13
|
+
module.exports.Zerogram = Zerogram;
|
|
14
|
+
module.exports.parseMarkdown = parseMarkdown;
|
|
15
|
+
module.exports.markdownToHtml = markdownToHtml;
|
|
16
|
+
module.exports.markdownToMarkdownV2 = markdownToMarkdownV2;
|
|
17
|
+
module.exports.FFMpegUtil = FFMpegUtil;
|
|
18
|
+
module.exports.loadModules = loadModules;
|