invitron
Version:
A powerful Discord.js invite tracker with persistent storage, member analytics, vanity URL support, and comprehensive join monitoring system for Discord bots.
301 lines (223 loc) โข 9.03 kB
Markdown

<div align="center">
**A powerful Discord.js invite tracker with persistent storage and comprehensive analytics**
[](https://www.npmjs.com/package/invitron)
[](https://www.npmjs.com/package/invitron)
[](./LICENSE)
[](https://discord.gg/your-discord-invite)
[](https://github.com/Boda335/invitron)
```
๐ฏ 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
```
[**Installation**](#-installation) โข [**Quick Start**](#-quick-start) โข [**Documentation**](#-api-reference) โข [**Examples**](#-examples)
</div>
## โจ 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
```bash
# 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
```typescript
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
```typescript
// 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 joined
- `joinData`: Detailed information about the join
#### `guildMemberRemove`
Emitted when a member leaves a guild.
- `member`: The member who left
## ๐ก Examples
### Discord Bot Command Example
```typescript
// !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
```typescript
// 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
```typescript
const tracker = InvitesTracker.init(client);
```
### Production Setup
```typescript
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
```typescript
const tracker = InvitesTracker.init(client, {
debug: true,
fetchGuilds: true,
storage: { enabled: true }
});
```
## ๐ค Contributing
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## ๐ License
This project is licensed under the Apache-2.0 License - see the [LICENSE](./LICENSE) file for details.
## ๐ Support
- ๐ฌ [Join our Discord Server](https://discord.gg/your-invite)
- ๐ [Report Issues](https://github.com/Boda335/invitron/issues)
<!-- - ๐ [Documentation](https://github.com/Boda335/invitron/wiki) -->
- โญ [Star us on GitHub](https://github.com/Boda335/invitron)
<div align="center">
**Made with โค๏ธ by [boda335](https://github.com/Boda335)**
</div>