@botgate/botgate-stats-reporter 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 BotGate
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,708 @@
1
+ # 📊 BotGate Stats Reporter
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@botgate/stats-reporter.svg)](https://www.npmjs.com/package/@botgate/stats-reporter)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ Pacote oficial do **BotGate** para reportar estatísticas do seu bot Discord automaticamente para a plataforma BotGate.
8
+
9
+ ## ✨ Funcionalidades
10
+
11
+ - ✅ **Envio automático** de estatísticas (servidores, usuários, shards)
12
+ - ⏰ **Intervalo configurável** de atualização
13
+ - 🔄 **Retry automático** em caso de falha
14
+ - 🔐 **Verificação de API key**
15
+ - 📝 **Logs detalhados** (modo debug)
16
+ - 🎯 **TypeScript completo** com tipos exportados
17
+ - 🚀 **Fácil integração** com Discord.js
18
+ - 💪 **Robusto e confiável**
19
+
20
+ ## 📦 Instalação
21
+
22
+ ```bash
23
+ npm install @botgate/stats-reporter
24
+ ```
25
+
26
+ ou
27
+
28
+ ```bash
29
+ yarn add @botgate/stats-reporter
30
+ ```
31
+
32
+ ## 🚀 Uso Básico
33
+
34
+ ### JavaScript
35
+
36
+ ```javascript
37
+ const { Client, GatewayIntentBits } = require("discord.js");
38
+ const { BotGateReporter } = require("@botgate/stats-reporter");
39
+
40
+ const client = new Client({
41
+ intents: [GatewayIntentBits.Guilds],
42
+ });
43
+
44
+ const reporter = new BotGateReporter({
45
+ botId: "YOUR_BOT_ID",
46
+ apiKey: "YOUR_API_KEY",
47
+ debug: true, // Opcional
48
+ });
49
+
50
+ client.once("ready", () => {
51
+ console.log(`Bot logado como ${client.user.tag}`);
52
+ reporter.start(client);
53
+ });
54
+
55
+ client.login("YOUR_BOT_TOKEN");
56
+ ```
57
+
58
+ ### TypeScript
59
+
60
+ ```typescript
61
+ import { Client, GatewayIntentBits } from "discord.js";
62
+ import { BotGateReporter } from "@botgate/stats-reporter";
63
+
64
+ const client = new Client({
65
+ intents: [GatewayIntentBits.Guilds],
66
+ });
67
+
68
+ const reporter = new BotGateReporter({
69
+ botId: "YOUR_BOT_ID",
70
+ apiKey: "YOUR_API_KEY",
71
+ debug: true, // Opcional
72
+ });
73
+
74
+ client.once("ready", () => {
75
+ console.log(`Bot logado como ${client.user.tag}`);
76
+ reporter.start(client);
77
+ });
78
+
79
+ client.login("YOUR_BOT_TOKEN");
80
+ ```
81
+
82
+ ## 📖 Documentação Completa
83
+
84
+ ### Configuração
85
+
86
+ ```typescript
87
+ interface BotGateConfig {
88
+ // Obrigatório
89
+ botId: string; // ID do bot no Discord
90
+ apiKey: string; // API key do BotGate
91
+
92
+ // Opcional
93
+ debug?: boolean; // Ativar logs (padrão: false)
94
+ }
95
+ ```
96
+
97
+ ### Métodos Principais
98
+
99
+ #### `start(client: Client): void`
100
+
101
+ Inicia o reporter e começa a enviar estatísticas automaticamente.
102
+
103
+ ```javascript
104
+ reporter.start(client);
105
+ ```
106
+
107
+ #### `stop(): void`
108
+
109
+ Para o reporter e cancela atualizações automáticas.
110
+
111
+ ```javascript
112
+ reporter.stop();
113
+ ```
114
+
115
+ #### `sendStats(): Promise<BotGateResponse>`
116
+
117
+ Envia estatísticas manualmente (sem aguardar o intervalo).
118
+
119
+ ```javascript
120
+ try {
121
+ const response = await reporter.sendStats();
122
+ console.log("Stats enviadas:", response);
123
+ } catch (error) {
124
+ console.error("Erro:", error);
125
+ }
126
+ ```
127
+
128
+ #### `verifyApiKey(): Promise<boolean>`
129
+
130
+ Verifica se a API key é válida.
131
+
132
+ ```javascript
133
+ const isValid = await reporter.verifyApiKey();
134
+ if (isValid) {
135
+ console.log("API key válida!");
136
+ }
137
+ ```
138
+
139
+ #### `getBotInfo(): Promise<BotInfo>`
140
+
141
+ Obtém informações do bot no BotGate.
142
+
143
+ ```javascript
144
+ const botInfo = await reporter.getBotInfo();
145
+ console.log("Nome:", botInfo.name);
146
+ console.log("Votos:", botInfo.stats.votes);
147
+ console.log("Avaliação:", botInfo.stats.rating);
148
+ ```
149
+
150
+ #### `getConfig(): Readonly<Required<BotGateConfig>>`
151
+
152
+ Retorna a configuração atual.
153
+
154
+ ```javascript
155
+ const config = reporter.getConfig();
156
+ console.log("Intervalo:", config.updateInterval);
157
+ ```
158
+
159
+ #### `isActive(): boolean`
160
+
161
+ Verifica se o reporter está ativo.
162
+
163
+ ```javascript
164
+ if (reporter.isActive()) {
165
+ console.log("Reporter está rodando");
166
+ }
167
+ ```
168
+
169
+ #### `getFailedAttempts(): number`
170
+
171
+ Retorna o número de tentativas falhadas consecutivas.
172
+
173
+ ```javascript
174
+ const failures = reporter.getFailedAttempts();
175
+ console.log("Falhas consecutivas:", failures);
176
+ ```
177
+
178
+ #### `refreshTier(): Promise<boolean>`
179
+
180
+ Atualiza o tier e intervalo de atualização consultando a API.
181
+
182
+ **Use este método após fazer upgrade do tier** para aplicar o novo intervalo sem reiniciar o bot.
183
+
184
+ ```javascript
185
+ // Após fazer upgrade para Premium no site
186
+ await reporter.refreshTier();
187
+ // O intervalo será automaticamente ajustado (ex: 30min → 5min)
188
+ ```
189
+
190
+ > **💡 Dica**: Quando você faz upgrade do tier (Free → Premium → Business), chame `refreshTier()` para que o reporter comece a enviar stats com o novo intervalo imediatamente!
191
+
192
+ ## 🔑 Obtendo sua API Key
193
+
194
+ 1. Acesse [BotGate](https://botgate.com)
195
+ 2. Faça login com sua conta Discord
196
+ 3. Vá para o painel do seu bot
197
+ 4. Copie sua API key na seção "Configurações"
198
+
199
+ ⚠️ **Importante**: Nunca compartilhe sua API key publicamente!
200
+
201
+ ## 📊 Estatísticas Enviadas
202
+
203
+ O reporter envia automaticamente:
204
+
205
+ - **Número de servidores** (`serverCount`)
206
+ - **Número total de usuários** (`userCount`)
207
+ - **Número de shards** (`shardCount`)
208
+ - **Timestamp** do envio
209
+
210
+ ## 🔄 Retry Automático
211
+
212
+ O reporter tenta enviar as estatísticas até 3 vezes (configurável) em caso de falha:
213
+
214
+ ```javascript
215
+ const reporter = new BotGateReporter({
216
+ botId: "YOUR_BOT_ID",
217
+ apiKey: "YOUR_API_KEY",
218
+ retryAttempts: 3, // Tentar 3 vezes
219
+ retryDelay: 5000, // Aguardar 5s entre tentativas
220
+ });
221
+ ```
222
+
223
+ ## 🐛 Debug
224
+
225
+ Ative o modo debug para ver logs detalhados:
226
+
227
+ ```javascript
228
+ const reporter = new BotGateReporter({
229
+ botId: "YOUR_BOT_ID",
230
+ apiKey: "YOUR_API_KEY",
231
+ debug: true, // ✅ Ativar logs
232
+ });
233
+ ```
234
+
235
+ Exemplo de logs:
236
+
237
+ ```
238
+ [BotGate Reporter] [2026-01-18T14:30:00.000Z] ✅ BotGate Reporter initialized
239
+ [BotGate Reporter] [2026-01-18T14:30:05.000Z] 🤖 Bot ready: MyBot#1234
240
+ [BotGate Reporter] [2026-01-18T14:30:06.000Z] 📤 Stats sent successfully (attempt 1)
241
+ {
242
+ "servers": 1250,
243
+ "users": 50000,
244
+ "shards": 1
245
+ }
246
+ [BotGate Reporter] [2026-01-18T14:30:06.000Z] ⏰ Auto-update enabled (every 30 minutes)
247
+ ```
248
+
249
+ ## 🛡️ Tratamento de Erros
250
+
251
+ O reporter lida automaticamente com erros comuns:
252
+
253
+ ```javascript
254
+ client.once("ready", async () => {
255
+ reporter.start(client);
256
+
257
+ // Verificar se a API key é válida
258
+ const isValid = await reporter.verifyApiKey();
259
+ if (!isValid) {
260
+ console.error("❌ API key inválida!");
261
+ process.exit(1);
262
+ }
263
+ });
264
+ ```
265
+
266
+ ## 🔧 Exemplos Avançados
267
+
268
+ ### Envio Manual em Eventos
269
+
270
+ ```javascript
271
+ client.on("guildCreate", async (guild) => {
272
+ console.log(`➕ Entrou no servidor: ${guild.name}`);
273
+
274
+ // Enviar stats imediatamente
275
+ await reporter.sendStats();
276
+ });
277
+
278
+ client.on("guildDelete", async (guild) => {
279
+ console.log(`➖ Saiu do servidor: ${guild.name}`);
280
+
281
+ // Enviar stats imediatamente
282
+ await reporter.sendStats();
283
+ });
284
+ ```
285
+
286
+ ### Atualizar Tier Após Upgrade
287
+
288
+ ```javascript
289
+ // Comando para atualizar o tier após fazer upgrade no site
290
+ client.on("messageCreate", async (message) => {
291
+ if (
292
+ message.content === "!refresh-tier" &&
293
+ message.author.id === "SEU_USER_ID"
294
+ ) {
295
+ message.reply("🔄 Atualizando tier...");
296
+
297
+ const success = await reporter.refreshTier();
298
+
299
+ if (success) {
300
+ message.reply("✅ Tier atualizado! Novo intervalo aplicado.");
301
+ } else {
302
+ message.reply("❌ Erro ao atualizar tier.");
303
+ }
304
+ }
305
+ });
306
+ ```
307
+
308
+ ### Graceful Shutdown
309
+
310
+ ```javascript
311
+ process.on("SIGINT", () => {
312
+ console.log("🛑 Encerrando...");
313
+ reporter.stop();
314
+ client.destroy();
315
+ process.exit(0);
316
+ });
317
+ ```
318
+
319
+ ### Monitoramento de Falhas
320
+
321
+ ```javascript
322
+ setInterval(() => {
323
+ const failures = reporter.getFailedAttempts();
324
+ if (failures > 5) {
325
+ console.error(`⚠️ Muitas falhas consecutivas: ${failures}`);
326
+ // Enviar alerta, etc.
327
+ }
328
+ }, 60000); // Verificar a cada minuto
329
+ ```
330
+
331
+ ## 🌐 API Endpoints Completos
332
+
333
+ O reporter se comunica com a API v1 do BotGate. Todos os endpoints requerem autenticação via API key no header `Authorization: Bearer <api_key>`.
334
+
335
+ ### 📤 POST `/api/v1/bots/stats`
336
+
337
+ Envia estatísticas do bot (servidores, usuários, shards).
338
+
339
+ **Request Body:**
340
+
341
+ ```json
342
+ {
343
+ "botId": "123456789012345678",
344
+ "serverCount": 1250,
345
+ "userCount": 50000,
346
+ "shardCount": 1,
347
+ "timestamp": 1705678901234
348
+ }
349
+ ```
350
+
351
+ **Response:**
352
+
353
+ ```json
354
+ {
355
+ "success": true,
356
+ "message": "Stats updated successfully",
357
+ "data": {
358
+ "botId": "123456789012345678",
359
+ "botName": "MyBot",
360
+ "serverCount": 1250,
361
+ "userCount": 50000,
362
+ "shardCount": 1,
363
+ "updatedAt": "2026-01-19T07:00:00.000Z"
364
+ }
365
+ }
366
+ ```
367
+
368
+ ### ✅ GET `/api/v1/verify`
369
+
370
+ Verifica se a API key é válida e retorna informações do tier.
371
+
372
+ **Response:**
373
+
374
+ ```json
375
+ {
376
+ "success": true,
377
+ "message": "API key is valid",
378
+ "data": {
379
+ "botId": "123456789012345678",
380
+ "botName": "MyBot",
381
+ "tier": {
382
+ "name": "free",
383
+ "apiCallsUsed": 150,
384
+ "apiCallsLimit": 1000,
385
+ "updateInterval": "30 minutes",
386
+ "analyticsLevel": "basic",
387
+ "historyDays": 7,
388
+ "features": {
389
+ "customWebhooks": false,
390
+ "prioritySupport": false,
391
+ "badge": "none"
392
+ }
393
+ }
394
+ }
395
+ }
396
+ ```
397
+
398
+ ### 🤖 GET `/api/v1/bots/:botId`
399
+
400
+ Obtém informações completas do bot.
401
+
402
+ **Response:**
403
+
404
+ ```json
405
+ {
406
+ "success": true,
407
+ "data": {
408
+ "id": "123456789012345678",
409
+ "name": "MyBot",
410
+ "avatar": "...",
411
+ "shortDescription": "Um bot incrível!",
412
+ "stats": {
413
+ "servers": 1250,
414
+ "users": 50000,
415
+ "shards": 1,
416
+ "rating": 4.8,
417
+ "reviews": 42
418
+ },
419
+ "owner": {
420
+ "id": "987654321098765432",
421
+ "username": "DevName"
422
+ },
423
+ "categories": [...],
424
+ "features": [...],
425
+ "commands": [...]
426
+ }
427
+ }
428
+ ```
429
+
430
+ ### 🗳️ GET `/api/v1/bots/:botId/votes`
431
+
432
+ Retorna informações detalhadas sobre votos.
433
+
434
+ **Query Parameters:**
435
+
436
+ - `limit` - Número de últimos votantes (padrão: 10, máx: 50)
437
+
438
+ **Response:**
439
+
440
+ ```json
441
+ {
442
+ "success": true,
443
+ "data": {
444
+ "botId": "123456789012345678",
445
+ "botName": "MyBot",
446
+ "total": 5420,
447
+ "monthly": 342,
448
+ "weekly": 87,
449
+ "today": 12,
450
+ "recentVoters": [...],
451
+ "monthlyHistory": [...]
452
+ }
453
+ }
454
+ ```
455
+
456
+ ### 📊 GET `/api/v1/bots/:botId/analytics`
457
+
458
+ Retorna métricas e analytics detalhadas (requer tier Free ou superior).
459
+
460
+ **Response:**
461
+
462
+ ```json
463
+ {
464
+ "success": true,
465
+ "data": {
466
+ "botId": "123456789012345678",
467
+ "botName": "MyBot",
468
+ "growth": {
469
+ "servers": {
470
+ "current": 1250,
471
+ "today": 15,
472
+ "week": 120,
473
+ "month": 450,
474
+ "percentageChange": {
475
+ "daily": "1.2",
476
+ "weekly": "10.6",
477
+ "monthly": "56.3"
478
+ }
479
+ },
480
+ "votes": {...}
481
+ },
482
+ "engagement": {
483
+ "votesPerDay": 12.5,
484
+ "reviewsPerWeek": 2.3,
485
+ "averageRating": 4.8
486
+ },
487
+ "trends": {
488
+ "peakDays": ["Saturday", "Sunday", "Friday"],
489
+ "dailyVotesLast7Days": [...]
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ ### 📈 GET `/api/v1/bots/:botId/stats/history`
496
+
497
+ Retorna histórico de estatísticas para gráficos.
498
+
499
+ **Query Parameters:**
500
+
501
+ - `period` - Período: 'daily', 'weekly', 'monthly', 'all' (padrão: 'all')
502
+
503
+ **Response:**
504
+
505
+ ```json
506
+ {
507
+ "success": true,
508
+ "data": {
509
+ "botId": "123456789012345678",
510
+ "botName": "MyBot",
511
+ "daily": [
512
+ {
513
+ "date": "2026-01-19",
514
+ "servers": 1250,
515
+ "votes": 5420,
516
+ "rating": "4.80"
517
+ }
518
+ ],
519
+ "weekly": [...],
520
+ "monthly": [...]
521
+ }
522
+ }
523
+ ```
524
+
525
+ ### 📋 GET `/api/v1/usage`
526
+
527
+ Retorna informações sobre o uso atual da API.
528
+
529
+ **Response:**
530
+
531
+ ```json
532
+ {
533
+ "success": true,
534
+ "data": {
535
+ "bot": {
536
+ "id": "123456789012345678",
537
+ "name": "MyBot"
538
+ },
539
+ "tier": {
540
+ "name": "free",
541
+ "displayName": "Free",
542
+ "features": {...}
543
+ },
544
+ "usage": {
545
+ "apiCalls": {
546
+ "used": 150,
547
+ "limit": 1000,
548
+ "remaining": 850,
549
+ "percentage": 15.0,
550
+ "status": "healthy",
551
+ "message": "Uso normal"
552
+ },
553
+ "reset": {
554
+ "at": "2026-02-01T00:00:00.000Z",
555
+ "inDays": 13,
556
+ "inHours": 312
557
+ }
558
+ },
559
+ "updates": {
560
+ "interval": "30 minutes",
561
+ "lastUpdate": "2026-01-19T03:20:00.000Z",
562
+ "nextUpdateAllowedAt": "2026-01-19T03:50:00.000Z",
563
+ "minutesUntilNextUpdate": 25,
564
+ "canUpdateNow": false
565
+ },
566
+ "statistics": {
567
+ "avgCallsPerDay": 12.5,
568
+ "estimatedDaysRemaining": 68,
569
+ "usageHistory": [...]
570
+ },
571
+ "upgrade": null
572
+ }
573
+ }
574
+ ```
575
+
576
+ ## 💎 Tiers e Limites
577
+
578
+ O BotGate oferece 3 tiers com diferentes limites e recursos:
579
+
580
+ ### 🆓 Free Tier
581
+
582
+ - ✅ **1,500 chamadas de API/mês**
583
+ - ⏰ **Intervalo mínimo de atualização: 30 minutos**
584
+ - 📊 Analytics **básicas**
585
+ - 📅 Histórico de **7 dias**
586
+ - 🎯 Perfeito para começar!
587
+
588
+ ### ⭐ Premium Tier ($9.99/mês)
589
+
590
+ - ✅ **10,000 chamadas de API/mês** (6.6x mais)
591
+ - ⏰ **Intervalo mínimo de atualização: 5 minutos** (6x mais rápido)
592
+ - 📊 Analytics **avançadas**
593
+ - 📅 Histórico de **90 dias**
594
+ - 🎨 Badge **Premium**
595
+ - 🔔 Webhooks customizados
596
+ - 💬 Suporte prioritário
597
+
598
+ ### 🚀 Business Tier ($29.99/mês)
599
+
600
+ - ✅ **100,000 chamadas de API/mês** (66x mais)
601
+ - ⏰ **Intervalo mínimo de atualização: 1 minuto** (30x mais rápido)
602
+ - 📊 Analytics **enterprise**
603
+ - 📅 Histórico de **365 dias**
604
+ - 👑 Badge **Verified**
605
+ - 🎯 Domínio customizado
606
+ - 🚫 Sem anúncios
607
+ - 🔔 Webhooks customizados
608
+ - 💬 Suporte prioritário 24/7
609
+
610
+ > **💡 Ajuste Automático de Intervalo:**
611
+ >
612
+ > O reporter **detecta automaticamente** o seu tier ao iniciar e ajusta o intervalo de atualização:
613
+ >
614
+ > - 🆓 **Free**: Envia stats a cada **30 minutos**
615
+ > - ⭐ **Premium**: Envia stats a cada **5 minutos** (6x mais rápido!)
616
+ > - 🚀 **Business**: Envia stats a cada **1 minuto** (30x mais rápido!)
617
+ >
618
+ > **Após fazer upgrade**, você tem 2 opções:
619
+ >
620
+ > 1. **Reiniciar o bot** - O novo intervalo será aplicado automaticamente
621
+ > 2. **Chamar `reporter.refreshTier()`** - Atualiza sem reiniciar (recomendado!)
622
+
623
+ ### 📊 Comparação de Limites
624
+
625
+ | Recurso | Free | Premium | Business |
626
+ | ---------------- | ---------- | ----------- | ---------- |
627
+ | Chamadas API/mês | 1,500 | 10,000 | 100,000 |
628
+ | Intervalo mínimo | 30 min | 5 min | 1 min |
629
+ | Analytics | Básicas | Avançadas | Enterprise |
630
+ | Histórico | 7 dias | 90 dias | 365 dias |
631
+ | Webhooks | ❌ | ✅ | ✅ |
632
+ | Domínio custom | ❌ | ❌ | ✅ |
633
+ | Badge | Nenhum | Premium | Verified |
634
+ | Suporte | Comunidade | Prioritário | 24/7 |
635
+
636
+ ## 🔒 Rate Limiting
637
+
638
+ A API implementa rate limiting baseado no tier:
639
+
640
+ - **Free**: 1,500 chamadas/mês, reset no dia 1º de cada mês
641
+ - **Premium**: 10,000 chamadas/mês
642
+ - **Business**: 100,000 chamadas/mês
643
+
644
+ Quando o limite é atingido, a API retorna:
645
+
646
+ ```json
647
+ {
648
+ "success": false,
649
+ "error": "API limit exceeded",
650
+ "message": "You have reached your monthly limit of 1500 API calls",
651
+ "currentUsage": 1500,
652
+ "limit": 1500,
653
+ "resetIn": "13 days",
654
+ "resetAt": "2026-02-01T00:00:00.000Z",
655
+ "upgrade": {
656
+ "message": "Upgrade to Premium for 10,000 calls/month",
657
+ "url": "https://botgate.com/pricing"
658
+ }
659
+ }
660
+ ```
661
+
662
+ ## 📝 Tipos TypeScript
663
+
664
+ Todos os tipos estão exportados e disponíveis:
665
+
666
+ ```typescript
667
+ import {
668
+ BotGateReporter,
669
+ BotGateConfig,
670
+ BotStats,
671
+ BotGateResponse,
672
+ BotInfo,
673
+ createReporter,
674
+ } from "@botgate/stats-reporter";
675
+ ```
676
+
677
+ ## 🤝 Contribuindo
678
+
679
+ Contribuições são bem-vindas! Por favor:
680
+
681
+ 1. Fork o repositório
682
+ 2. Crie uma branch para sua feature (`git checkout -b feature/MinhaFeature`)
683
+ 3. Commit suas mudanças (`git commit -m 'Adiciona MinhaFeature'`)
684
+ 4. Push para a branch (`git push origin feature/MinhaFeature`)
685
+ 5. Abra um Pull Request
686
+
687
+ ## 🔗 Links
688
+
689
+ - [Website do BotGate](https://www.botgate.coden8n.shop/)
690
+ - [Discord de Suporte](https://discord.gg/xK4r9HqKKf)
691
+ - [GitHub](https://github.com/nathan-lucca/botgate-stats-reporter)
692
+ - [NPM](https://www.npmjs.com/package/@botgate/stats-reporter)
693
+
694
+ ## 💬 Suporte
695
+
696
+ Precisa de ajuda? Entre em contato:
697
+
698
+ - 💬 Discord: [Servidor de Suporte](https://discord.gg/xK4r9HqKKf)
699
+ - 🌐 Website: [BotGate](https://www.botgate.coden8n.shop/)
700
+ - 🐛 Issues: [GitHub Issues](https://github.com/nathan-lucca/botgate-stats-reporter/issues)
701
+
702
+ ## 🙏 Agradecimentos
703
+
704
+ Obrigado por usar o BotGate Stats Reporter! ❤️
705
+
706
+ ---
707
+
708
+ Feito com ❤️ pela equipe BotGate
@@ -0,0 +1,51 @@
1
+ import { Client } from "discord.js";
2
+ export interface BotGateConfig {
3
+ botId: string;
4
+ apiKey: string;
5
+ debug?: boolean;
6
+ }
7
+ export interface BotStats {
8
+ botId: string;
9
+ serverCount: number;
10
+ userCount: number;
11
+ shardCount: number;
12
+ timestamp: number;
13
+ }
14
+ export interface BotGateResponse<T = any> {
15
+ success: boolean;
16
+ message?: string;
17
+ data?: T;
18
+ error?: string;
19
+ }
20
+ export declare class BotGateReporter {
21
+ private client;
22
+ private config;
23
+ private axios;
24
+ private statsIntervalId;
25
+ private heartbeatIntervalId;
26
+ private isRunning;
27
+ private failedAttempts;
28
+ private currentTier;
29
+ constructor(config: BotGateConfig);
30
+ start(client: Client): void;
31
+ stop(): void;
32
+ sendStats(): Promise<BotGateResponse>;
33
+ sendHeartbeat(): Promise<BotGateResponse>;
34
+ verifyApiKey(): Promise<boolean>;
35
+ getBotInfo(botId?: string): Promise<BotGateResponse>;
36
+ getBotVotes(botId?: string, limit?: number): Promise<BotGateResponse>;
37
+ getBotAnalytics(botId?: string): Promise<BotGateResponse>;
38
+ getStatsHistory(botId?: string, period?: "daily" | "weekly" | "monthly" | "all"): Promise<BotGateResponse>;
39
+ getApiUsage(): Promise<BotGateResponse>;
40
+ private onReady;
41
+ private setupAutoUpdate;
42
+ private manageHeartbeat;
43
+ private collectStats;
44
+ private postWithRetry;
45
+ private syncFromResponse;
46
+ private updateIntervalFromTier;
47
+ private log;
48
+ private formatError;
49
+ }
50
+ export default BotGateReporter;
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAqBpC,MAAM,WAAW,aAAa;IAE5B,KAAK,EAAE,MAAM,CAAC;IAGd,MAAM,EAAE,MAAM,CAAC;IAGf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAmBD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,WAAW,CAAkB;gBAOzB,MAAM,EAAE,aAAa;IAiC1B,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAkB3B,IAAI,IAAI,IAAI;IAcN,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAarC,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC;IAOzC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAmBhC,UAAU,CACrB,KAAK,GAAE,MAA0B,GAChC,OAAO,CAAC,eAAe,CAAC;IAad,WAAW,CACtB,KAAK,GAAE,MAA0B,EACjC,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,eAAe,CAAC;IAWd,eAAe,CAC1B,KAAK,GAAE,MAA0B,GAChC,OAAO,CAAC,eAAe,CAAC;IASd,eAAe,CAC1B,KAAK,GAAE,MAA0B,EACjC,MAAM,GAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAa,GACrD,OAAO,CAAC,eAAe,CAAC;IAYd,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;YActC,OAAO;IAQrB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,YAAY;YAYN,aAAa;IA6C3B,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,sBAAsB;IAgB9B,OAAO,CAAC,GAAG;IAUX,OAAO,CAAC,WAAW;CAMpB;AAED,eAAe,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,214 @@
1
+ import axios from "axios";
2
+ export class BotGateReporter {
3
+ constructor(config) {
4
+ this.client = null;
5
+ this.statsIntervalId = null;
6
+ this.heartbeatIntervalId = null;
7
+ this.isRunning = false;
8
+ this.failedAttempts = 0;
9
+ this.currentTier = "free";
10
+ if (!config.botId)
11
+ throw new Error("[BotGate Reporter] botId is required");
12
+ if (!config.apiKey)
13
+ throw new Error("[BotGate Reporter] apiKey is required");
14
+ this.config = {
15
+ botId: config.botId,
16
+ apiKey: config.apiKey,
17
+ apiUrl: "https://botgate-api-987684559046.us-central1.run.app",
18
+ updateInterval: 30 * 60 * 1000,
19
+ debug: config.debug || false,
20
+ retryAttempts: 3,
21
+ retryDelay: 5000,
22
+ };
23
+ this.axios = axios.create({
24
+ baseURL: this.config.apiUrl,
25
+ timeout: 10000,
26
+ headers: {
27
+ Authorization: `Bearer ${this.config.apiKey}`,
28
+ "Content-Type": "application/json",
29
+ "User-Agent": `BotGate-Stats-Reporter/1.1.0 (Bot: ${this.config.botId})`,
30
+ },
31
+ });
32
+ this.log("✅ BotGate Reporter initialized", { botId: this.config.botId });
33
+ }
34
+ start(client) {
35
+ if (this.isRunning)
36
+ return;
37
+ this.client = client;
38
+ this.isRunning = true;
39
+ if (client.isReady()) {
40
+ this.onReady();
41
+ }
42
+ else {
43
+ client.once("ready", () => this.onReady());
44
+ }
45
+ this.log("🚀 Reporter started");
46
+ }
47
+ stop() {
48
+ if (this.statsIntervalId)
49
+ clearInterval(this.statsIntervalId);
50
+ if (this.heartbeatIntervalId)
51
+ clearInterval(this.heartbeatIntervalId);
52
+ this.statsIntervalId = null;
53
+ this.heartbeatIntervalId = null;
54
+ this.isRunning = false;
55
+ this.log("🛑 Reporter stopped");
56
+ }
57
+ async sendStats() {
58
+ if (!this.client?.isReady()) {
59
+ throw new Error("[BotGate Reporter] Discord client is not ready");
60
+ }
61
+ const stats = this.collectStats();
62
+ return await this.postWithRetry("/api/v1/bots/stats", stats);
63
+ }
64
+ async sendHeartbeat() {
65
+ return await this.postWithRetry("/api/v1/heartbeat", {});
66
+ }
67
+ async verifyApiKey() {
68
+ try {
69
+ const response = await this.axios.get("/api/v1/verify");
70
+ if (response.data.success && response.data.data?.tier) {
71
+ this.syncFromResponse(response.data.data);
72
+ }
73
+ return response.data.success === true;
74
+ }
75
+ catch (error) {
76
+ this.log("❌ API key verification failed", this.formatError(error));
77
+ return false;
78
+ }
79
+ }
80
+ async getBotInfo(botId = this.config.botId) {
81
+ const response = await this.axios.get(`/api/v1/bots/${botId}`);
82
+ if (response.data.success) {
83
+ this.syncFromResponse(response.data.data);
84
+ }
85
+ return response.data;
86
+ }
87
+ async getBotVotes(botId = this.config.botId, limit = 10) {
88
+ const response = await this.axios.get(`/api/v1/bots/${botId}/votes`, {
89
+ params: { limit },
90
+ });
91
+ return response.data;
92
+ }
93
+ async getBotAnalytics(botId = this.config.botId) {
94
+ const response = await this.axios.get(`/api/v1/bots/${botId}/analytics`);
95
+ return response.data;
96
+ }
97
+ async getStatsHistory(botId = this.config.botId, period = "all") {
98
+ const response = await this.axios.get(`/api/v1/bots/${botId}/stats/history`, { params: { period } });
99
+ return response.data;
100
+ }
101
+ async getApiUsage() {
102
+ const response = await this.axios.get("/api/v1/usage");
103
+ if (response.data.success) {
104
+ this.syncFromResponse(response.data.data);
105
+ }
106
+ return response.data;
107
+ }
108
+ async onReady() {
109
+ this.log(`🤖 Bot ready: ${this.client?.user?.tag}`);
110
+ await this.verifyApiKey();
111
+ await this.sendStats();
112
+ }
113
+ setupAutoUpdate() {
114
+ if (this.statsIntervalId)
115
+ clearInterval(this.statsIntervalId);
116
+ this.statsIntervalId = setInterval(() => this.sendStats(), this.config.updateInterval);
117
+ this.log(`⏰ Auto-stats enabled (${this.config.updateInterval / 60000} min)`);
118
+ }
119
+ manageHeartbeat() {
120
+ if (this.currentTier === "business") {
121
+ if (this.heartbeatIntervalId)
122
+ return;
123
+ this.sendHeartbeat();
124
+ this.heartbeatIntervalId = setInterval(() => this.sendHeartbeat(), 5 * 60 * 1000);
125
+ this.log("💓 Business Heartbeat enabled (every 5 min)");
126
+ }
127
+ else if (this.heartbeatIntervalId) {
128
+ clearInterval(this.heartbeatIntervalId);
129
+ this.heartbeatIntervalId = null;
130
+ }
131
+ }
132
+ collectStats() {
133
+ const guilds = this.client.guilds.cache;
134
+ return {
135
+ botId: this.config.botId,
136
+ serverCount: guilds.size,
137
+ userCount: guilds.reduce((acc, g) => acc + (g.memberCount || 0), 0),
138
+ shardCount: this.client.shard?.count || 1,
139
+ timestamp: Date.now(),
140
+ };
141
+ }
142
+ async postWithRetry(url, data, attempt = 1) {
143
+ try {
144
+ const response = await this.axios.post(url, data);
145
+ const responseData = response.data;
146
+ if (responseData.success) {
147
+ this.syncFromResponse(responseData.data);
148
+ }
149
+ this.failedAttempts = 0;
150
+ return { success: true, data: responseData };
151
+ }
152
+ catch (error) {
153
+ const status = error.response?.status;
154
+ if (status === 403 || status === 429) {
155
+ this.log(`⚠️ Tier/Frequency limit reached (${status}). Syncing and waiting for next cycle...`);
156
+ await this.verifyApiKey();
157
+ return {
158
+ success: false,
159
+ error: `Rate limited or tier mismatch (${status})`,
160
+ };
161
+ }
162
+ if (attempt < this.config.retryAttempts) {
163
+ await new Promise((r) => setTimeout(r, this.config.retryDelay));
164
+ return this.postWithRetry(url, data, attempt + 1);
165
+ }
166
+ this.failedAttempts++;
167
+ return { success: false, error: error.message };
168
+ }
169
+ }
170
+ syncFromResponse(data) {
171
+ if (!data)
172
+ return;
173
+ const tierObject = data.tier || data;
174
+ const tierName = tierObject.name || tierObject.tier || data.tier;
175
+ const intervalMinutes = tierObject.updateIntervalMinutes ||
176
+ data.updates?.updateIntervalMinutes ||
177
+ data.capabilities?.updateIntervalMinutes;
178
+ if (tierName && tierName !== this.currentTier) {
179
+ this.log(`🔄 Plan change detected: ${this.currentTier} -> ${tierName}`);
180
+ this.currentTier = tierName;
181
+ if (intervalMinutes) {
182
+ this.updateIntervalFromTier({
183
+ updateInterval: `${intervalMinutes} minutes`,
184
+ });
185
+ }
186
+ this.manageHeartbeat();
187
+ }
188
+ }
189
+ updateIntervalFromTier(tierData) {
190
+ const minutes = parseInt(tierData.updateInterval?.replace(" minutes", "") || "30");
191
+ const newInterval = minutes * 60 * 1000;
192
+ if (this.config.updateInterval !== newInterval) {
193
+ this.config.updateInterval = newInterval;
194
+ if (this.isRunning) {
195
+ this.setupAutoUpdate();
196
+ }
197
+ }
198
+ }
199
+ log(message, data) {
200
+ if (this.config.debug) {
201
+ console.log(`[BotGate Reporter] [${new Date().toISOString()}] ${message}`);
202
+ if (data)
203
+ console.log(JSON.stringify(data, null, 2));
204
+ }
205
+ }
206
+ formatError(error) {
207
+ return {
208
+ message: error.response?.data?.message || error.message,
209
+ status: error.response?.status,
210
+ };
211
+ }
212
+ }
213
+ export default BotGateReporter;
214
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@botgate/botgate-stats-reporter",
3
+ "version": "1.0.0",
4
+ "description": "Módulo oficial do BotGate para reportar estatísticas do seu bot Discord automaticamente",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "prepublishOnly": "npm run build",
19
+ "test": "jest",
20
+ "lint": "eslint src/**/*.ts"
21
+ },
22
+ "keywords": [
23
+ "discord",
24
+ "bot",
25
+ "botgate",
26
+ "stats",
27
+ "statistics",
28
+ "discord.js",
29
+ "monitoring"
30
+ ],
31
+ "author": "BotGate Team",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/nathan-lucca/botgate-stats-reporter.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/nathan-lucca/botgate-stats-reporter/issues"
39
+ },
40
+ "homepage": "http://docs-botgate.vercel.app/",
41
+ "peerDependencies": {
42
+ "discord.js": "^14.0.0"
43
+ },
44
+ "dependencies": {
45
+ "axios": "^1.6.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.0.0",
49
+ "typescript": "^5.0.0",
50
+ "eslint": "^8.0.0",
51
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
52
+ "@typescript-eslint/parser": "^6.0.0",
53
+ "jest": "^29.0.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=16.0.0"
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "README.md",
61
+ "LICENSE"
62
+ ]
63
+ }