Discord Voice is a powerful Node.js module that allows you to easily track the user's voice time and levels!
- ✨ Easy to use!
- 📁 Support for all databases! (default is json)
- ⚙️ Very customizable! (ignored channels, ignored members, ignored permissions, xp amount to add, voice time to add etc...)
- 🚀 Super powerful: createUser, createConfig, removeUser, removeConfig, updateUser and updateConfig!
- 🕸️ Support for shards!
- and much more!
npm install --save discord-voice
You can use this example bot on GitHub: VoiceTimeTrackerBot
const { Client, Intents } = require("discord.js"),
client = new Client({
intents: [Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] // The GUILD_VOICE_STATES and GUILDS intents are required for discord-voice to function.
}),
settings = {
prefix: "v!",
token: "Your Discord Bot Token"
};
// Requires Manager from discord-voice
const { VoiceManager } = require("discord-voice");
// Create a new instance of the manager class
const manager = new VoiceManager(client, {
userStorage: "./users.json",
configStorage: "./configs.json",
checkMembersEvery: 5000,
default: {
trackBots: false,
trackAllChannels: true
}
});
// We now have a voiceManager property to access the manager everywhere!
client.voiceManager = manager;
After that, user's who are in the voice channel's that the bot has cached will be checked. You can pass an options object to customize the config. For a list of them refer to the documentation.
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "create-user") {
client.voiceManager.createUser(message.author.id, message.guild.id, {
levelingData: {
xp: 0,
level: 0
}
// The user will have 0 xp and 0 level.
});
}
});
This allow's you create a user in the database if the user is not already present in the database. You can pass an options object to customize the user's data. For a list of them refer to the documentation.
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "create-config") {
client.voiceManager.createConfig(message.guild.id, {
trackBots: false, // If the user is a bot it will not be tracked.
trackAllChannels: true, // All of the channels in the guild will be tracked.
exemptChannels: () => false, // The user will not be tracked in these channels. (This is a function).
channelIds: [], // The channel ids to track. (If trackAllChannels is true, this is ignored)
exemptPermissions: [], // The user permissions to not track.
exemptMembers: () => false, // The user will not be tracked. (This is a function).
trackMute: true, // It will track users if they are muted aswell.
trackDeaf: true, // It will track users if they are deafen aswell.
minUserCountToParticipate: 0, // The min amount of users to be in a channel to be tracked.
maxUserCountToParticipate: 0, // The max amount of users to be in a channel to be tracked.
minXpToParticipate: 0, // The min amount of xp needed to be tracked.
minLevelToParticipate: 0, // The min level needed to be tracked.
maxXpToParticipate: 0, // The max amount of xp needed to be tracked.
maxLevelToParticipate: 0, // The max level needed to be tracked.
xpAmountToAdd: () => Math.floor(Math.random() * 10) + 1, // The amount of xp to add to the user (This is a function).
voiceTimeToAdd: () => 1000, // The amount of time in ms to add to the user (This is a function).
voiceTimeTrackingEnabled: true, // Whether the voiceTimeTracking module is enabled.
levelingTrackingEnabled: true // Whether the levelingTracking module is enabled.
});
}
});
This allow's you create a config in the database if the config is not already present in the database. You can pass an options object to customize the config's data. For a list of them refer to the documentation.
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "remove-user") {
client.voiceManager.removeUser(message.author.id, message.guild.id); // Removes the user from the database and the cache.
}
});
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "remove-config") {
client.voiceManager.removeConfig(message.guild.id); // Removes the config from the database and the cache.
}
});
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "edit-user") {
client.voiceManager.updateUser(message.author.id, message.guild.id, {
newVoiceTime: {
channels: [],
total: 0
} // The new voice time user will have.
});
}
});
This allow's you edit a user's data. You need to pass an options object to edit the user's data. For a list of them refer to the documentation.
client.on("messageCreate", (message) => {
const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "edit-config") {
client.voiceManager.updateConfig(message.guild.id, {
newTrackBots: true // The module will now track bot user's voice time aswell.
});
}
});
This allow's you edit a config's data. You need to pass an options object to edit the config's data. For a list of them refer to the documentation.
// A list of all the users
const allUsers = client.voiceManager.users; // [ {User}, {User} ]
// A list of all the users on the server with ID "1909282092"
const onServer = client.voiceManager.users.filter((u) => u.guildId === "1909282092");
// The user on the server with Id "1909282092" and the user Id "1234567890"
const user = client.voiceManager.users.filter((u) => u.guildId === "1909282092" && u.userId === "1234567890");
// A list of all the configs
const allConfigs = client.voiceManager.configs; // [ {Config}, {Config} ]
// The config of the guild with Id "1909282092"
const config = client.voiceManager.configs.filter((c) => c.guildId === "1909282092");
client.voiceManager.updateConfig(message.guild.id, {
// The channel will not be tracked if it's name is "private"
exemptChannels: (channel) => channel.name === "private")
});
const channelName = "private";
client.voiceManager.updateConfig(message.guild.id, {
// The channel won't be tracked if it's name is equal to the value which is assigned to "channelName"
exemptChannels: new Function("channel", `return channel.name === \'${channelName}\'`)
});
client.voiceManager.updateConfig(message.guild.id, {
// Only members who have the "Nitro Boost" role are able to be tracked
exemptMembers: (member) => !member.roles.cache.some((r) => r.name === "Nitro Boost")
});
const roleName = "Nitro Boost";
client.voiceManager.updateConfig(message.guild.id, {
// Only members who have the the role which is assigned to "roleName" are able to be tracked
exemptMembers: new Function("member", `return !member.roles.cache.some((r) => r.name === \'${roleName}\')`)
});
client.voiceManager.updateConfig(message.guild.id, {
xpAmountToAdd: () => Math.floor(Math.random() * 10) + 1 // This will add a random amount between 1 and 10 of xp to the user.
});
Math.floor(Math.random() * 10) + 1
) will be used.
client.voiceManager.updateConfig(message.guild.id, {
voiceTimeToAdd: () => 1000 // This will add 1000 ms of voice time everytime the user is checked.
});
1000
) will be used.
client.voiceManager.updateConfig(message.guild.id, {
levelMultiplier: () => 0.1 // This will set the level multiplier to 0.1 (normally it's 0.1).
});
0.1
) will be used.
You can use your custom database to save users and configs, instead of the json files (the "database" by default for discord-voice
). For this, you will need to extend the VoiceManager
class, and replace some methods with your custom ones. There are 8 methods you will need to replace:
getAllUsers
: this method returns an array of stored users.getAllConfigs
: this method returns an array of stored configs.saveUser
: this method stores a new user in the database.saveConfig
: this method stores a new config in the database.editUser
: this method edits a user already stored in the database.editConfig
: this method edits a config already stored in the database.deleteUser
: this method deletes a user from the database (permanently).deleteConfig
: this method deletes a config from the database (permanently).
Here is an example, using quick.db
, a SQLite database. The comments in the code below are very important to understand how it works!
Other examples:
- MongoDB
- Mongoose
- QuickMongo
⚠️ Not recommended for high giveaway usage, use themongoose
example instead
- Enmap
- Replit Database
⚠️ Only usable if your bot is hosted on Replit
const { Client, Intents } = require("discord.js"), // npm install discord.js
client = new Client({
intents: [Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] // The GUILD_VOICE_STATES and GUILDS intents are required for discord-voice to function.
}),
settings = {
prefix: "v!",
token: "Your Discord Bot Token"
};
// Load quick.db - it's an example of custom database, you can use MySQL, PostgreSQL, etc...
const db = require("quick.db");
if (!Array.isArray(db.get("users"))) db.set("users", []);
if (!Array.isArray(db.get("configs"))) db.set("configs", []);
const { VoiceManager } = require("discord-voice");
const VoiceManagerWithOwnDatabase = class extends VoiceManager {
// This function is called when the manager needs to get all users which are stored in the database.
async getAllUsers() {
// Get all users from the database
return db.get("users");
}
// This function is called when the manager needs to get all configs which are stored in the database.
async getAllConfigs() {
// Get all configs from the database
return db.get("configs");
}
// This function is called when a user needs to be saved in the database.
async saveUser(userId, guildId, userData) {
// Add the new user to the database
db.push("users", userData);
// Don't forget to return something!
return true;
}
// This function is called when a user needs to be saved in the database.
async saveConfig(guildId, configData) {
// Add the new user to the database
db.push("configs", configData);
// Don't forget to return something!
return true;
}
// This function is called when a user needs to be edited in the database.
async editUser(userId, guildId, userData) {
// Get all users from the database
const users = db.get("users");
// Find the user to edit
const user = users.find((u) => u.guildId === guildId && u.userId === userId);
// Remove the unedited user from the array
const newUsersArray = users.filter((u) => u !== user);
// Push the edited user into the array
newUsersArray.push(userData);
// Save the updated array
db.set("users", newUsersArray);
// Don't forget to return something!
return true;
}
// This function is called when a config needs to be edited in the database.
async editConfig(guildId, configData) {
// Get all configs from the database
const configs = db.get("configs");
// Remove the unedited config from the array
const newConfigsArray = configs.filter((config) => config.guildId !== guildId);
// Push the edited config into the array
newConfigsArray.push(configData);
// Save the updated array
db.set("configs", newConfigsArray);
// Don't forget to return something!
return true;
}
// This function is called when a user needs to be deleted from the database.
async deleteUser(userId, guildId) {
// Get all users from the database
const users = db.get("users");
// Find the user to edit
const user = users.find((u) => u.guildId === guildId && u.userId === userId);
// Remove the user from the array
const newUsersArray = users.filter((u) => u !== user);
// Save the updated array
db.set("users", newUsersArray);
// Don't forget to return something!
return true;
}
// This function is called when a config needs to be deleted from the database.
async deleteConfig(guildId) {
// Get all configs from the database
const configs = db.get("configs");
// Remove the config from the array
const newConfigsArray = configs.filter((config) => config.guildId !== guildId);
// Save the updated array
db.set("configs", newConfigsArray);
// Don't forget to return something!
return true;
}
};
// Create a new instance of your new class
const manager = new VoiceManagerWithOwnDatabase(client, {
checkMembersEvery: 5000,
default: {
trackBots: false,
trackAllChannels: true
}
});
// We now have a voiceManager property to access the manager everywhere!
client.voiceManager = manager;
client.on("ready", () => {
console.log("I'm ready!");
});
client.login(settings.token);
To make discord-voice
work with shards, you will need to extend the VoiceManager
class and update the refreshStorage()
method. This method should call the getAllUsers()
and getAllConfigs()
method for every shard, so all VoiceManager
's synchronize their cache with the updated database.
const { Client, Intents } = require("discord.js"), // npm install discord.js
client = new Client({
intents: [Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] // The GUILD_VOICE_STATES and GUILDS intents are required for discord-voice to function.
}),
settings = {
prefix: "v!",
token: "Your Discord Bot Token"
};
// Extends the VoiceManager class and update the refreshStorage method
const { VoiceManager } = require("discord-voice");
const VoiceManagerWithShardSupport = class extends VoiceManager {
// The refreshStorage method is called when the database is updated on one of the shards
async refreshStorage() {
// This should make all shards refresh their cache with the updated database
return client.shard.broadcastEval(() => this.voiceManager.getAllUsers() && this.voiceManager.getAllConfigs());
}
};
// Create a new instance of your new class
const manager = new VoiceManagerWithShardSupport(client, {
userStorage: "./users.json",
configStorage: "./configs.json",
checkMembersEvery: 5000,
default: {
trackBots: false,
trackAllChannels: true
}
});
// We now have a voiceManager property to access the manager everywhere!
client.voiceManager = manager;
client.on("ready", () => {
console.log("I'm ready!");
});
client.login(settings.token);