discord-voice-tracker 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 +21 -0
- package/dist/core/VoiceManager.d.ts +98 -0
- package/dist/core/VoiceManager.d.ts.map +1 -0
- package/dist/core/VoiceManager.js +399 -0
- package/dist/core/VoiceManager.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/JSONStorage.d.ts +30 -0
- package/dist/storage/JSONStorage.d.ts.map +1 -0
- package/dist/storage/JSONStorage.js +202 -0
- package/dist/storage/JSONStorage.js.map +1 -0
- package/dist/storage/MongoStorage.d.ts +27 -0
- package/dist/storage/MongoStorage.d.ts.map +1 -0
- package/dist/storage/MongoStorage.js +220 -0
- package/dist/storage/MongoStorage.js.map +1 -0
- package/dist/types/index.d.ts +266 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/Calculator.d.ts +31 -0
- package/dist/utils/Calculator.d.ts.map +1 -0
- package/dist/utils/Calculator.js +70 -0
- package/dist/utils/Calculator.js.map +1 -0
- package/dist/utils/Logger.d.ts +9 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +25 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/Validator.d.ts +19 -0
- package/dist/utils/Validator.d.ts.map +1 -0
- package/dist/utils/Validator.js +63 -0
- package/dist/utils/Validator.js.map +1 -0
- package/package.json +76 -0
- package/readme.md +662 -0
package/readme.md
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
# Discord Voice Tracker
|
|
2
|
+
|
|
3
|
+
> 🎙️ A modern, production-ready voice activity tracking system for Discord bots with XP, leveling, and comprehensive statistics.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/discord-voice-tracker)
|
|
6
|
+
[](https://www.npmjs.com/package/discord-voice-tracker)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://nodejs.org)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ✨ Features
|
|
13
|
+
|
|
14
|
+
- 🎯 **Voice Time Tracking** - Track total and per-channel voice activity
|
|
15
|
+
- 💫 **XP & Leveling System** - Automatic XP gain and level progression
|
|
16
|
+
- 📊 **Statistics & Analytics** - Detailed user stats and session history
|
|
17
|
+
- 🏆 **Leaderboards** - Rank users by voice time, XP, or level
|
|
18
|
+
- ⚙️ **Highly Configurable** - Customize tracking behavior per guild
|
|
19
|
+
- 💾 **Multiple Storage Options** - JSON (built-in) and MongoDB support
|
|
20
|
+
- 🔒 **TypeScript Support** - Full type definitions included
|
|
21
|
+
- 🚀 **Production Ready** - Optimized performance with caching
|
|
22
|
+
- 📦 **Easy Integration** - Simple setup with sensible defaults
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 📋 Table of Contents
|
|
27
|
+
|
|
28
|
+
- [Installation](#-installation)
|
|
29
|
+
- [Quick Start](#-quick-start)
|
|
30
|
+
- [Slash Commands](#-slash-commands)
|
|
31
|
+
- [Configuration](#-configuration)
|
|
32
|
+
- [Events](#-events)
|
|
33
|
+
- [API Reference](#-api-reference)
|
|
34
|
+
- [Storage Options](#-storage-options)
|
|
35
|
+
- [Examples](#-examples)
|
|
36
|
+
- [Troubleshooting](#-troubleshooting)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📦 Installation
|
|
41
|
+
|
|
42
|
+
### Prerequisites
|
|
43
|
+
|
|
44
|
+
Before installing, make sure you have:
|
|
45
|
+
- **Node.js 18.0.0 or higher** - [Download here](https://nodejs.org/)
|
|
46
|
+
- **A Discord Bot** - [Create one here](https://discord.com/developers/applications)
|
|
47
|
+
|
|
48
|
+
### Step 1: Install the Package
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install discord-voice-tracker discord.js
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**What this does:**
|
|
55
|
+
- Installs `discord-voice-tracker` (this package)
|
|
56
|
+
- Installs `discord.js` (required peer dependency)
|
|
57
|
+
|
|
58
|
+
### Step 2: (Optional) Install MongoDB
|
|
59
|
+
|
|
60
|
+
If you want to use MongoDB instead of JSON storage:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install mongodb
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**When to use MongoDB:**
|
|
67
|
+
- ✅ Large servers (1000+ members)
|
|
68
|
+
- ✅ Multiple guilds
|
|
69
|
+
- ✅ Production environments
|
|
70
|
+
- ❌ Small bots or testing (use JSON instead)
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 🚀 Quick Start
|
|
75
|
+
|
|
76
|
+
### Basic Setup (5 minutes)
|
|
77
|
+
|
|
78
|
+
Create a file called `bot.js`:
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
// Import required modules
|
|
82
|
+
const { Client, GatewayIntentBits } = require('discord.js');
|
|
83
|
+
const { VoiceManager, JSONStorage } = require('discord-voice-tracker');
|
|
84
|
+
|
|
85
|
+
// Create Discord client with required intents
|
|
86
|
+
const client = new Client({
|
|
87
|
+
intents: [
|
|
88
|
+
GatewayIntentBits.Guilds, // Required: Access to guilds
|
|
89
|
+
GatewayIntentBits.GuildVoiceStates, // Required: Voice state updates
|
|
90
|
+
],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Create storage (saves data to ./data folder)
|
|
94
|
+
const storage = new JSONStorage('./data');
|
|
95
|
+
|
|
96
|
+
// Create voice manager
|
|
97
|
+
const voiceManager = new VoiceManager(client, {
|
|
98
|
+
storage, // Where to save data
|
|
99
|
+
checkInterval: 5000, // Check voice activity every 5 seconds
|
|
100
|
+
debug: true, // Enable debug logs (disable in production)
|
|
101
|
+
defaultConfig: {
|
|
102
|
+
trackBots: false, // Don't track bot users
|
|
103
|
+
trackAllChannels: true, // Track all voice channels
|
|
104
|
+
xpPerCheck: 5, // Give 5 XP every 5 seconds in voice
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Listen for level ups
|
|
109
|
+
voiceManager.on('levelUp', (userData, oldLevel, newLevel) => {
|
|
110
|
+
console.log(`🎉 User ${userData.userId} leveled up to ${newLevel}!`);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Initialize when bot is ready
|
|
114
|
+
client.once('ready', async () => {
|
|
115
|
+
console.log(`✅ Logged in as ${client.user.tag}`);
|
|
116
|
+
|
|
117
|
+
// Initialize voice manager
|
|
118
|
+
await voiceManager.init();
|
|
119
|
+
console.log('✅ Voice tracking active!');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Login with your bot token
|
|
123
|
+
client.login('YOUR_BOT_TOKEN_HERE');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Run Your Bot
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
node bot.js
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**You should see:**
|
|
133
|
+
```
|
|
134
|
+
✅ Logged in as YourBot#1234
|
|
135
|
+
[VoiceTracker DEBUG] Initializing VoiceManager...
|
|
136
|
+
[VoiceTracker DEBUG] Storage initialized
|
|
137
|
+
[VoiceTracker DEBUG] Tracking started with 5000ms interval
|
|
138
|
+
✅ Voice tracking active!
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Test It
|
|
142
|
+
|
|
143
|
+
1. **Join a voice channel** in your Discord server
|
|
144
|
+
2. **Wait 5-10 seconds**
|
|
145
|
+
3. **Check the console** - you should see tracking activity
|
|
146
|
+
4. **Leave the voice channel**
|
|
147
|
+
5. **Check `data/guilds.json`** - you'll see your data saved!
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 💬 Slash Commands
|
|
152
|
+
|
|
153
|
+
Want users to check their stats? Add these commands to your bot!
|
|
154
|
+
|
|
155
|
+
### Example: `/stats` Command
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
|
159
|
+
const { XPCalculator } = require('discord-voice-tracker');
|
|
160
|
+
|
|
161
|
+
const calculator = new XPCalculator();
|
|
162
|
+
|
|
163
|
+
// Register the command
|
|
164
|
+
const statsCommand = new SlashCommandBuilder()
|
|
165
|
+
.setName('stats')
|
|
166
|
+
.setDescription('View your voice activity statistics')
|
|
167
|
+
.addUserOption(option =>
|
|
168
|
+
option
|
|
169
|
+
.setName('user')
|
|
170
|
+
.setDescription('User to check (optional)')
|
|
171
|
+
.setRequired(false)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Handle the command
|
|
175
|
+
client.on('interactionCreate', async (interaction) => {
|
|
176
|
+
if (!interaction.isChatInputCommand()) return;
|
|
177
|
+
if (interaction.commandName !== 'stats') return;
|
|
178
|
+
|
|
179
|
+
const targetUser = interaction.options.getUser('user') || interaction.user;
|
|
180
|
+
const userData = await voiceManager.getUser(interaction.guildId, targetUser.id);
|
|
181
|
+
|
|
182
|
+
if (!userData) {
|
|
183
|
+
return interaction.reply({
|
|
184
|
+
content: `${targetUser.username} has no voice activity yet!`,
|
|
185
|
+
ephemeral: true,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const embed = new EmbedBuilder()
|
|
190
|
+
.setColor('#5865F2')
|
|
191
|
+
.setTitle(`📊 Voice Stats for ${targetUser.username}`)
|
|
192
|
+
.addFields(
|
|
193
|
+
{ name: '⏱️ Total Voice Time', value: calculator.formatVoiceTime(userData.totalVoiceTime), inline: true },
|
|
194
|
+
{ name: '⭐ Level', value: `${userData.level}`, inline: true },
|
|
195
|
+
{ name: '💫 XP', value: `${userData.xp}`, inline: true }
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
await interaction.reply({ embeds: [embed] });
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Register commands when bot is ready
|
|
202
|
+
client.once('ready', async () => {
|
|
203
|
+
await client.application.commands.create(statsCommand);
|
|
204
|
+
console.log('✅ Slash commands registered!');
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Available Commands
|
|
209
|
+
|
|
210
|
+
| Command | Description | Example |
|
|
211
|
+
|---------|-------------|---------|
|
|
212
|
+
| `/stats [@user]` | View voice statistics | `/stats @John` |
|
|
213
|
+
| `/leaderboard [type]` | View server leaderboard | `/leaderboard xp` |
|
|
214
|
+
| `/rank [@user]` | Check server rank | `/rank` |
|
|
215
|
+
| `/sessions [@user]` | View recent sessions | `/sessions @John` |
|
|
216
|
+
|
|
217
|
+
**📖 See [examples/bot.js](examples/bot.js) for complete command implementations!**
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## ⚙️ Configuration
|
|
222
|
+
|
|
223
|
+
### Manager Options
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
const voiceManager = new VoiceManager(client, {
|
|
227
|
+
// Required
|
|
228
|
+
storage: storage, // Storage adapter (JSONStorage or MongoStorage)
|
|
229
|
+
|
|
230
|
+
// Optional
|
|
231
|
+
checkInterval: 5000, // How often to check (milliseconds)
|
|
232
|
+
debug: false, // Enable debug logging
|
|
233
|
+
|
|
234
|
+
defaultConfig: {
|
|
235
|
+
// Tracking options
|
|
236
|
+
trackBots: false, // Track bot users
|
|
237
|
+
trackAllChannels: true, // Track all voice channels
|
|
238
|
+
trackMuted: true, // Track muted users
|
|
239
|
+
trackDeafened: true, // Track deafened users
|
|
240
|
+
|
|
241
|
+
// Channel filters
|
|
242
|
+
channelIds: [], // Specific channels to track (if trackAllChannels: false)
|
|
243
|
+
minUsersToTrack: 0, // Minimum users in channel to track (0 = no limit)
|
|
244
|
+
maxUsersToTrack: 0, // Maximum users in channel to track (0 = no limit)
|
|
245
|
+
|
|
246
|
+
// Permission filters
|
|
247
|
+
exemptPermissions: [], // Users with these permissions won't be tracked
|
|
248
|
+
|
|
249
|
+
// XP & Leveling
|
|
250
|
+
xpPerCheck: 5, // XP to award per check interval
|
|
251
|
+
voiceTimePerCheck: 5000, // Voice time to add per check (milliseconds)
|
|
252
|
+
levelMultiplier: 0.1, // Level calculation multiplier
|
|
253
|
+
enableLeveling: true, // Enable XP/leveling system
|
|
254
|
+
enableVoiceTime: true, // Enable voice time tracking
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Per-Guild Configuration
|
|
260
|
+
|
|
261
|
+
Change settings for specific servers:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
// Get current config
|
|
265
|
+
const config = await voiceManager.getGuildConfig(guildId);
|
|
266
|
+
|
|
267
|
+
// Modify settings
|
|
268
|
+
config.trackBots = true; // Now track bots
|
|
269
|
+
config.xpPerCheck = 10; // Give more XP
|
|
270
|
+
config.channelIds = ['123456789']; // Only track specific channel
|
|
271
|
+
|
|
272
|
+
// Save changes
|
|
273
|
+
await voiceManager.saveGuildConfig(guildId, config);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Advanced Filtering
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
const config = await voiceManager.getGuildConfig(guildId);
|
|
280
|
+
|
|
281
|
+
// Only track channels with "voice" in the name
|
|
282
|
+
config.channelFilter = (channel) => {
|
|
283
|
+
return channel.name.toLowerCase().includes('voice');
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// Don't track users with "Muted" role
|
|
287
|
+
config.memberFilter = (member) => {
|
|
288
|
+
return !member.roles.cache.some(role => role.name === 'Muted');
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
await voiceManager.saveGuildConfig(guildId, config);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## 🎯 Events
|
|
297
|
+
|
|
298
|
+
Listen to these events to add custom features:
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// User gained voice time
|
|
302
|
+
voiceManager.on('voiceTimeGained', (userData, gained) => {
|
|
303
|
+
console.log(`User gained ${gained}ms of voice time`);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// User gained XP
|
|
307
|
+
voiceManager.on('xpGained', (userData, gained) => {
|
|
308
|
+
console.log(`User gained ${gained} XP`);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// User leveled up
|
|
312
|
+
voiceManager.on('levelUp', (userData, oldLevel, newLevel) => {
|
|
313
|
+
console.log(`User leveled up from ${oldLevel} to ${newLevel}!`);
|
|
314
|
+
|
|
315
|
+
// Example: Give a role when reaching level 10
|
|
316
|
+
if (newLevel === 10) {
|
|
317
|
+
const guild = client.guilds.cache.get(userData.guildId);
|
|
318
|
+
const member = guild.members.cache.get(userData.userId);
|
|
319
|
+
const role = guild.roles.cache.find(r => r.name === 'Active Chatter');
|
|
320
|
+
if (member && role) {
|
|
321
|
+
member.roles.add(role);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Voice session started
|
|
327
|
+
voiceManager.on('sessionStart', (session) => {
|
|
328
|
+
console.log(`Session started for ${session.userId}`);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Voice session ended
|
|
332
|
+
voiceManager.on('sessionEnd', (session) => {
|
|
333
|
+
console.log(`Session ended, duration: ${session.duration}ms`);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// Configuration updated
|
|
337
|
+
voiceManager.on('configUpdated', (guildId, config) => {
|
|
338
|
+
console.log(`Config updated for guild ${guildId}`);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Error occurred
|
|
342
|
+
voiceManager.on('error', (error) => {
|
|
343
|
+
console.error('Voice Manager Error:', error);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Debug messages (only if debug: true)
|
|
347
|
+
voiceManager.on('debug', (message) => {
|
|
348
|
+
console.log(`[DEBUG] ${message}`);
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 📚 API Reference
|
|
355
|
+
|
|
356
|
+
### VoiceManager
|
|
357
|
+
|
|
358
|
+
#### Methods
|
|
359
|
+
|
|
360
|
+
```javascript
|
|
361
|
+
// Initialize the manager
|
|
362
|
+
await voiceManager.init();
|
|
363
|
+
|
|
364
|
+
// Get user data
|
|
365
|
+
const userData = await voiceManager.getUser(guildId, userId);
|
|
366
|
+
// Returns: { userId, guildId, totalVoiceTime, xp, level, channels, ... }
|
|
367
|
+
|
|
368
|
+
// Update user data
|
|
369
|
+
await voiceManager.updateUser(guildId, userId, {
|
|
370
|
+
addVoiceTime: 60000, // Add 1 minute
|
|
371
|
+
addXp: 100, // Add 100 XP
|
|
372
|
+
setLevel: 5, // Set to level 5
|
|
373
|
+
metadata: { ... } // Custom data
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// Get leaderboard
|
|
377
|
+
const leaderboard = await voiceManager.getLeaderboard(guildId, {
|
|
378
|
+
sortBy: 'xp', // 'voiceTime', 'xp', or 'level'
|
|
379
|
+
limit: 10, // Number of users
|
|
380
|
+
offset: 0, // Pagination offset
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
// Get/save guild config
|
|
384
|
+
const config = await voiceManager.getGuildConfig(guildId);
|
|
385
|
+
await voiceManager.saveGuildConfig(guildId, config);
|
|
386
|
+
|
|
387
|
+
// Delete data
|
|
388
|
+
await voiceManager.deleteGuild(guildId);
|
|
389
|
+
await voiceManager.deleteUser(guildId, userId);
|
|
390
|
+
|
|
391
|
+
// Cleanup
|
|
392
|
+
await voiceManager.destroy();
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### XPCalculator
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
const { XPCalculator } = require('discord-voice-tracker');
|
|
399
|
+
const calculator = new XPCalculator();
|
|
400
|
+
|
|
401
|
+
// Calculate level from XP
|
|
402
|
+
const level = calculator.calculateLevel(1000, 0.1);
|
|
403
|
+
// Returns: 10
|
|
404
|
+
|
|
405
|
+
// Calculate XP needed for level
|
|
406
|
+
const xpNeeded = calculator.calculateXPForLevel(10, 0.1);
|
|
407
|
+
// Returns: 1000
|
|
408
|
+
|
|
409
|
+
// Calculate XP to next level
|
|
410
|
+
const xpToNext = calculator.calculateXPToNextLevel(1500, 0.1);
|
|
411
|
+
// Returns: 610
|
|
412
|
+
|
|
413
|
+
// Calculate progress percentage
|
|
414
|
+
const progress = calculator.calculateLevelProgress(1500, 0.1);
|
|
415
|
+
// Returns: 22 (22%)
|
|
416
|
+
|
|
417
|
+
// Format voice time to readable string
|
|
418
|
+
const formatted = calculator.formatVoiceTime(3661000);
|
|
419
|
+
// Returns: "1h 1m 1s"
|
|
420
|
+
|
|
421
|
+
// Calculate average session duration
|
|
422
|
+
const avgDuration = calculator.calculateAverageSessionDuration(
|
|
423
|
+
totalVoiceTime,
|
|
424
|
+
totalSessions
|
|
425
|
+
);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 💾 Storage Options
|
|
431
|
+
|
|
432
|
+
### JSON Storage (Default)
|
|
433
|
+
|
|
434
|
+
**Best for:** Small to medium bots, testing, single server
|
|
435
|
+
|
|
436
|
+
```javascript
|
|
437
|
+
const { JSONStorage } = require('discord-voice-tracker');
|
|
438
|
+
|
|
439
|
+
const storage = new JSONStorage('./data');
|
|
440
|
+
// Creates: ./data/guilds.json and ./data/sessions.json
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Pros:**
|
|
444
|
+
- ✅ No external dependencies
|
|
445
|
+
- ✅ Easy to inspect/edit files
|
|
446
|
+
- ✅ Simple backup (just copy the folder)
|
|
447
|
+
|
|
448
|
+
**Cons:**
|
|
449
|
+
- ❌ Not suitable for large scale (1000+ users)
|
|
450
|
+
- ❌ No concurrent write protection
|
|
451
|
+
|
|
452
|
+
### MongoDB Storage
|
|
453
|
+
|
|
454
|
+
**Best for:** Production, large servers, multiple bots
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
const { MongoStorage } = require('discord-voice-tracker');
|
|
458
|
+
|
|
459
|
+
// Make sure to: npm install mongodb
|
|
460
|
+
|
|
461
|
+
const storage = new MongoStorage(
|
|
462
|
+
'mongodb://localhost:27017', // Connection string
|
|
463
|
+
'voicetracker' // Database name
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
// Or with MongoDB Atlas:
|
|
467
|
+
const storage = new MongoStorage(
|
|
468
|
+
'mongodb+srv://user:pass@cluster.mongodb.net/',
|
|
469
|
+
'voicetracker'
|
|
470
|
+
);
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Pros:**
|
|
474
|
+
- ✅ Handles large datasets efficiently
|
|
475
|
+
- ✅ Built-in indexing for fast queries
|
|
476
|
+
- ✅ Concurrent write support
|
|
477
|
+
- ✅ Easy to scale
|
|
478
|
+
|
|
479
|
+
**Cons:**
|
|
480
|
+
- ❌ Requires MongoDB server
|
|
481
|
+
- ❌ More complex setup
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## 📝 Examples
|
|
486
|
+
|
|
487
|
+
### Example 1: Basic Bot
|
|
488
|
+
|
|
489
|
+
```javascript
|
|
490
|
+
const { Client, GatewayIntentBits } = require('discord.js');
|
|
491
|
+
const { VoiceManager, JSONStorage } = require('discord-voice-tracker');
|
|
492
|
+
|
|
493
|
+
const client = new Client({
|
|
494
|
+
intents: [
|
|
495
|
+
GatewayIntentBits.Guilds,
|
|
496
|
+
GatewayIntentBits.GuildVoiceStates,
|
|
497
|
+
],
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
const storage = new JSONStorage('./data');
|
|
501
|
+
const voiceManager = new VoiceManager(client, { storage });
|
|
502
|
+
|
|
503
|
+
client.once('ready', async () => {
|
|
504
|
+
await voiceManager.init();
|
|
505
|
+
console.log('Bot ready!');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
client.login('YOUR_TOKEN');
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Example 2: With Level-Up Rewards
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
voiceManager.on('levelUp', async (userData, oldLevel, newLevel) => {
|
|
515
|
+
const guild = client.guilds.cache.get(userData.guildId);
|
|
516
|
+
const member = await guild.members.fetch(userData.userId);
|
|
517
|
+
|
|
518
|
+
// Level 5: Bronze role
|
|
519
|
+
if (newLevel === 5) {
|
|
520
|
+
const role = guild.roles.cache.find(r => r.name === 'Bronze Chatter');
|
|
521
|
+
await member.roles.add(role);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Level 10: Silver role
|
|
525
|
+
if (newLevel === 10) {
|
|
526
|
+
const role = guild.roles.cache.find(r => r.name === 'Silver Chatter');
|
|
527
|
+
await member.roles.add(role);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Level 25: Gold role
|
|
531
|
+
if (newLevel === 25) {
|
|
532
|
+
const role = guild.roles.cache.find(r => r.name === 'Gold Chatter');
|
|
533
|
+
await member.roles.add(role);
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Example 3: Custom XP Based on Channel
|
|
539
|
+
|
|
540
|
+
```javascript
|
|
541
|
+
const config = await voiceManager.getGuildConfig(guildId);
|
|
542
|
+
|
|
543
|
+
// Give more XP in certain channels
|
|
544
|
+
config.channelFilter = (channel) => {
|
|
545
|
+
if (channel.name === 'study-room') {
|
|
546
|
+
config.xpPerCheck = 10; // Double XP in study room
|
|
547
|
+
} else {
|
|
548
|
+
config.xpPerCheck = 5; // Normal XP elsewhere
|
|
549
|
+
}
|
|
550
|
+
return true; // Track all channels
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
await voiceManager.saveGuildConfig(guildId, config);
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
**📖 More examples in [examples/](examples/) folder!**
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## 🐛 Troubleshooting
|
|
561
|
+
|
|
562
|
+
### "Module not found: discord-voice-tracker"
|
|
563
|
+
|
|
564
|
+
**Solution:** Make sure you installed it:
|
|
565
|
+
```bash
|
|
566
|
+
npm install discord-voice-tracker discord.js
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### "Cannot find module 'mongodb'"
|
|
570
|
+
|
|
571
|
+
**Solution:** MongoDB is optional. Install it if you want to use MongoStorage:
|
|
572
|
+
```bash
|
|
573
|
+
npm install mongodb
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Or use JSONStorage instead:
|
|
577
|
+
```javascript
|
|
578
|
+
const { JSONStorage } = require('discord-voice-tracker');
|
|
579
|
+
const storage = new JSONStorage('./data');
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Voice tracking not working
|
|
583
|
+
|
|
584
|
+
**Checklist:**
|
|
585
|
+
1. ✅ Bot has correct intents:
|
|
586
|
+
- `GatewayIntentBits.Guilds`
|
|
587
|
+
- `GatewayIntentBits.GuildVoiceStates`
|
|
588
|
+
2. ✅ Called `await voiceManager.init()`
|
|
589
|
+
3. ✅ Bot is in the server
|
|
590
|
+
4. ✅ User is in a voice channel
|
|
591
|
+
5. ✅ Wait at least 5-10 seconds
|
|
592
|
+
|
|
593
|
+
**Check the logs:**
|
|
594
|
+
```javascript
|
|
595
|
+
const voiceManager = new VoiceManager(client, {
|
|
596
|
+
storage,
|
|
597
|
+
debug: true, // Enable this!
|
|
598
|
+
});
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Stats command shows no data
|
|
602
|
+
|
|
603
|
+
**Possible causes:**
|
|
604
|
+
1. User hasn't joined voice yet
|
|
605
|
+
2. `trackBots` is false and checking a bot
|
|
606
|
+
3. Config updated and wiped users (see bug fix in docs)
|
|
607
|
+
|
|
608
|
+
**Solution:**
|
|
609
|
+
```javascript
|
|
610
|
+
const userData = await voiceManager.getUser(guildId, userId);
|
|
611
|
+
if (!userData) {
|
|
612
|
+
return interaction.reply('No data yet! Join a voice channel first.');
|
|
613
|
+
}
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### TypeError: Cannot read property 'users' of null
|
|
617
|
+
|
|
618
|
+
**Solution:** Guild not initialized. The bot will create it automatically when someone joins voice, or you can create it manually:
|
|
619
|
+
```javascript
|
|
620
|
+
const config = await voiceManager.getGuildConfig(guildId);
|
|
621
|
+
// This creates the guild if it doesn't exist
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
## 🤝 Contributing
|
|
627
|
+
|
|
628
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
629
|
+
|
|
630
|
+
1. Fork the repository
|
|
631
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
632
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
633
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
634
|
+
5. Open a Pull Request
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## 📄 License
|
|
639
|
+
|
|
640
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
## 🙏 Support
|
|
645
|
+
|
|
646
|
+
- 📖 **Documentation:** [GitHub](https://github.com/yourusername/discord-voice-tracker)
|
|
647
|
+
- 🐛 **Bug Reports:** [Issues](https://github.com/yourusername/discord-voice-tracker/issues)
|
|
648
|
+
- 💬 **Discord:** [Join our server](https://discord.gg/your-invite)
|
|
649
|
+
- ⭐ **Star on GitHub** if you find this useful!
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
## 📊 Stats
|
|
654
|
+
|
|
655
|
+

|
|
656
|
+

|
|
657
|
+

|
|
658
|
+

|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
**Made with ❤️ by [Async](https://github.com/yourusername)**
|