Table of contents
Invites — Invite Tracking, Leaderboard & Role Rewards
GrumpyInvites automatically detects which invite link (including the server's vanity link) was used for a new join, keeps per-inviter stats, and can automatically grant a role once someone reaches a configured invite threshold.
Example Scenario (Step by Step)
Sven wants to know who his most active "recruiters" are, and give them a special role for it — without counting anything by hand.
- Add a reward tier to
configs/modules/invites.yml(copy the role ID from Discord first — right-click the role → "Copy ID", Developer Mode must be enabled in Discord for this):
Then runrewardRoles: - invites: 5 roleId: "123456789012345678" # e.g. role "🌟 Server Recruiter"/invites reloadso the change applies without a bot restart. - Jonas creates his own invite link via Discord's built-in feature (channel → Invite) and shares it.
- Five new members join via Jonas's link. The bot detects this automatically on every join — nothing else to do.
- Once the fifth join counts (non-fake, still in the server), the bot automatically grants the
🌟 Server Recruiterrole to Jonas. - Check how Jonas is doing:
→ shows e.g. Total: 5, Regular: 5, Bonus: 0, Left again: 0, Suspicious: 0/invites stats user:@Jonas - Show the server-wide leaderboard:
/invites leaderboard
Special case — giveaway prize: Someone won a contest and should get 3 extra invites credited without actually having invited 3 people:
/invites bonus user:@Jonas amount:3
These count toward role rewards exactly like "real" invites.
Activation
In configs/config.yml:
addons:
invites: true
On first start, configs/modules/invites.yml is created.
invites.yml
enabled: true
fakeThresholdDays: 7 # Accounts younger than X days count as "suspicious" (fake)
logChannelId: "" # Channel for "X joined, invited by Y" posts. "" = don't post
rewardRoles: []
# Example:
# rewardRoles:
# - invites: 5
# roleId: "123456789012345678"
# - invites: 10
# roleId: "234567890123456789"
| Field | Default | Description |
|---|---|---|
fakeThresholdDays |
7 |
Account age in days below which a join is marked "suspicious" |
logChannelId |
"" |
Optional channel for join logs. Empty = don't post |
rewardRoles |
[] |
List of invites (threshold) + roleId — only ever granted, never auto-revoked |
How Attribution Works
On startup and on every invite create/delete, the bot keeps an in-memory snapshot of all server invites (code, creator, use count). When a new member joins, it compares that snapshot against a fresh fetch:
- A known invite's use count went up → that invite was used.
- An invite disappeared entirely, but had a
maxUseslimit that was just reached → Discord auto-deletes single-use/limited invites the instant the last use is consumed, so no "increased count" is visible in that case. The bot detects this separately. - Vanity URL (e.g.
discord.gg/minetechworld) — compared via its own separate use counter. - Nothing detectable (e.g. server discovery, widget join) → logged as "unknown", doesn't count for anyone.
After every join the snapshot is resynced so drift never accumulates over time. If multiple members join at the same moment, the bot processes them sequentially (not in parallel) — otherwise two joins could accidentally get attributed to the same invite.
Bot joins are not tracked — a bot is added via the OAuth2 "invite bot" flow, which never consumes a regular server invite.
"Suspicious" (Fake) Joins
If the new member's Discord account is younger than fakeThresholdDays, the join is marked as fake. Fake joins:
- are flagged separately in the log
- don't count toward the leaderboard,
/invites stats(regular), or role rewards - still show up in the
fakestat, so abuse (e.g. alt-account farming for invite rewards) stays visible
Leaving the Server
If a member leaves the server again, their most recent open join record is marked as "left". This:
- counts toward the inviter's
leftstat - does not remove any role reward already granted — once a role has been granted it stays, even if the invited user later leaves
Commands
/invites stats [user]
Shows invite stats — your own or another member's.
| Field | Meaning |
|---|---|
| Total | Regular + Bonus (this is what counts for role rewards) |
| Regular | Successful, non-fake joins who are still in the server |
| Bonus | Manually granted bonus invites (see /invites bonus) |
| Left again | Invited members who have since left the server |
| Suspicious | Joins from accounts younger than fakeThresholdDays |
/invites stats
/invites stats user:@Jonas
Permission: Everyone
/invites leaderboard [limit]
Ranks the top inviters by total (regular + bonus).
| Option | Description |
|---|---|
limit |
How many to show (default 10, max 25) |
/invites leaderboard
/invites leaderboard limit:5
Permission: Everyone
/invites bonus <user> <amount>
Grants (or removes) manual bonus invites — e.g. as a giveaway prize or special reward. amount can be negative to take bonus invites back away.
/invites bonus user:@Jonas amount:5
/invites bonus user:@Jonas amount:-2
Permission: Manage Guild
/invites reload
Reloads invites.yml without restarting the bot.
/invites reload
Permission: Manage Guild
Role Rewards
Once a member's total (regular + bonus) reaches a threshold configured in rewardRoles, the bot automatically grants the matching role — checked right after every successful, non-fake join.
- Roles are only ever granted, never auto-removed (not even if an invited member later leaves) — same behavior as the Leveling module's role rewards.
- Multiple thresholds are allowed and all of them are granted once reached (not just the highest) — e.g. with thresholds at
5and10, a user with 12 invites gets both roles. - The bot needs
Manage Roles, and its own role must sit above the reward role in the hierarchy, otherwise it's silently skipped.
Log Example
With logChannelId set:
📨 @NewUser joined — invited by @Jonas (code `abc123`, now 6 invites)
📨 @SuspiciousUser joined — invited by @Jonas (code `abc123`, now 7 invites) ⚠️ (new account — doesn't count toward rewards)
📨 @AnotherUser joined via the vanity link
📨 @OneMore joined — invite could not be determined (discovery/widget or similar)
Permissions
| Command | Permission |
|---|---|
/invites stats |
Everyone |
/invites leaderboard |
Everyone |
/invites bonus |
Manage Guild |
/invites reload |
Manage Guild |
For automatic attribution the bot needs the Manage Guild permission (to view invites) and the Server Invites gateway intent (already part of the standard bot invite). All commands are guild-only (no DM context).
GrumpyCore Wiki
⚙️ Setup
🔧 Core-Module
🆕 Neue Module
🔔 Benachrichtigungen & Utility
💬 Commands
👥 Staff
GrumpyCore Wiki (English)
⚙️ Setup
🔧 Core Modules
🆕 New Modules
🔔 Notifications & Utility
💬 Commands
👥 Staff