A powerful Discord.js invite tracker with persistent storage and comprehensive analytics
🎯 Track member joins and leaves via invites
📝 Support for normal, vanity, and audit-log based invites
💾 Optional persistent JSON storage with analytics
📊 Built-in leaderboards and comprehensive statistics
✨ Features
- 🌐 Complete Invite Tracking - Monitor all guild member joins and leaves
- 📊 Advanced Analytics - Leaderboards, statistics, and detailed invite data
- 🤖 Bot-Friendly - Optional bot filtering and comprehensive error handling
- 💾 Persistent Storage - Local JSON file storage with automatic data management
- 🔄 Real-time Updates - Automatic invite cache management and event handling
- 🛡️ Multiple Sources - Support for normal invites, vanity URLs, and audit logs
- 🧪 Debug Support - Comprehensive logging for easier troubleshooting
- ⚡ TypeScript Ready - Fully typed with excellent IDE support
- 🎛️ Highly Configurable - Flexible options for different use cases
📦 Installation
# Using npm
npm install invitron
# Using yarn
yarn add invitron
# Using pnpm
pnpm add invitron
Requirements:
- Node.js 16.9.0 or higher
- Discord.js v14.11.0 or higher
🚀 Quick Start
Basic Setup
import { Client, GatewayIntentBits } from "discord.js";
import InvitesTracker from "invitron";
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildInvites
]
});
// Initialize the tracker
const tracker = InvitesTracker.init(client, {
fetchGuilds: true, // Load existing invites on startup
fetchVanity: true, // Track vanity URL joins
fetchAuditLogs: true, // Use audit logs as fallback
ignoreBots: true, // Ignore bot joins
deductOnLeave: true, // Remove invite credit when members leave
storage: {
enabled: true,
path: "./data/invites.json"
}
});
// Listen for member joins
tracker.on("guildMemberAdd", (member, joinData) => {
const { inviter, code, totalInvites, type } = joinData;
if (type === "normal" && inviter) {
console.log(`👋 ${member.user.tag} joined using ${inviter.tag}'s invite (${code})`);
console.log(`📊 ${inviter.tag} now has ${totalInvites} total invites`);
}
});
client.login("YOUR_BOT_TOKEN");
Advanced Usage
// Get user's invite statistics
const userInvites = tracker.getInvites(guildId, userId);
console.log(`User has ${userInvites} invites`);
// Get server leaderboard
const leaderboard = tracker.getLeaderboard(guildId, 10);
leaderboard.forEach((entry, index) => {
console.log(`${index + 1}. User ${entry.userId}: ${entry.invites} invites`);
});
// Get top inviter
const topInviter = tracker.getTopInviter(guildId);
if (topInviter) {
console.log(`🏆 Top inviter: ${topInviter.userId} with ${topInviter.invites} invites`);
}
// Reset guild data
tracker.resetGuild(guildId);
📖 API Reference
InvitesTracker.init(client, options)
Initializes the invite tracker with the specified Discord client and options.
Parameters
Parameter | Type | Default | Description |
---|---|---|---|
client |
Client |
- | Discord.js client instance |
options |
TrackerOptions |
{} |
Configuration options |
TrackerOptions
Option | Type | Default | Description |
---|---|---|---|
fetchGuilds |
boolean |
false |
Preload invites from all guilds on startup |
fetchVanity |
boolean |
false |
Track joins via vanity URLs |
fetchAuditLogs |
boolean |
false |
Use audit logs when invite source is unknown |
debug |
boolean |
false |
Enable debug logging |
ignoreBots |
boolean |
false |
Ignore bot joins/leaves |
deductOnLeave |
boolean |
false |
Subtract invite count when members leave |
storage.enabled |
boolean |
false |
Enable persistent storage |
storage.path |
string |
"./invites.json" |
Path to storage file |
Methods
getInvites(guildId: string, userId: string): number
Returns the total number of invites for a user in the specified guild.
resetGuild(guildId: string): void
Resets all invite data for the specified guild.
getTopInviter(guildId: string): { userId: string; invites: number } | null
Returns the user with the most invites in the guild.
getLeaderboard(guildId: string, limit?: number): Array<{ userId: string; invites: number }>
Returns a sorted leaderboard of inviters (default limit: 10).
Events
guildMemberAdd
Emitted when a member joins a guild.
member
: The member who joinedjoinData
: Detailed information about the join
guildMemberRemove
Emitted when a member leaves a guild.
member
: The member who left
💡 Examples
Discord Bot Command Example
// !invites command
if (message.content === "!invites") {
const userId = message.author.id;
const guildId = message.guild!.id;
const invites = tracker.getInvites(guildId, userId);
message.reply(`You have **${invites}** invites! 🎉`);
}
// !leaderboard command
if (message.content === "!leaderboard") {
const guildId = message.guild!.id;
const leaderboard = tracker.getLeaderboard(guildId, 5);
let response = "🏆 **Top Inviters:**\n";
leaderboard.forEach((entry, index) => {
const user = client.users.cache.get(entry.userId);
response += `${index + 1}. ${user?.tag || 'Unknown'}: ${entry.invites} invites\n`;
});
message.reply(response);
}
Slash Command Example
// Register slash command
const invitesCommand = {
name: 'invites',
description: 'Check your invite count',
options: [{
name: 'user',
description: 'User to check (optional)',
type: 6, // USER type
required: false
}]
};
// Handle slash command
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand() || interaction.commandName !== 'invites') return;
const targetUser = interaction.options.getUser('user') || interaction.user;
const invites = tracker.getInvites(interaction.guildId!, targetUser.id);
await interaction.reply(`${targetUser.tag} has **${invites}** invites! 🎯`);
});
🔧 Configuration Examples
Minimal Setup
const tracker = InvitesTracker.init(client);
Production Setup
const tracker = InvitesTracker.init(client, {
fetchGuilds: true,
fetchVanity: true,
fetchAuditLogs: true,
ignoreBots: true,
deductOnLeave: true,
storage: {
enabled: true,
path: process.env.DATA_PATH || "./data/invites.json"
}
});
Development Setup
const tracker = InvitesTracker.init(client, {
debug: true,
fetchGuilds: true,
storage: { enabled: true }
});
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
📄 License
This project is licensed under the Apache-2.0 License - see the LICENSE file for details.
🆘 Support
Made with ❤️ by boda335