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 ADDED
@@ -0,0 +1,587 @@
1
+
2
+ # 🚀 ZerogramJS 2.1
3
+
4
+ ![Banner](banner.jpg)
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;