Skip to content

Instantly share code, notes, and snippets.

@icourt
Last active September 16, 2021 01:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save icourt/42b3abbb7c0c19d8630d9fa3014e2074 to your computer and use it in GitHub Desktop.
Save icourt/42b3abbb7c0c19d8630d9fa3014e2074 to your computer and use it in GitHub Desktop.
How to create a DiscordJS Invite Tracker
// Welcome to my gist! This is how you can create an invite tracker using JavaScript and Discord.JS!
// First we are going to statt off in our ready event.
// Create a new Collection called guildInvites and add it to your client
// client is the new Client you created in your main file. If you're using an event handler, make sure to pass the client into this file.
const { Collection } = require("discord.js");
// Collection is an enhanced Map which we are going to save our invites to.
const guildInvites = new Collection();
client.invites = guildInvites;
// Next, we are going to fetch invites for every guild and add them to our map.
for(const guild of client.guilds.cache.values()) {
// Here we are getting all invites for the guild
// Using our client.invites collection we created, we are saving all invites to the cache by guild id.
guild.fetchInvites()
.then(invite => client.invites.set(guild.id, invite)
.catch(error => console.log(error));
};
// Now we can move to our inviteCreate event.
// We are going to add our new invite to the cache every time a new one is created.
// This is to ensure we always have a valid cache.
// Out inviteCreate event passes a parameter, which we call "invite" in this example.
// We can also use our client.invites collection we created in our ready event.
client.invites.set(invite.guild.id, await invite.guild.fetchInvites());
// invite has a guild property that we can access the guild from.
// Note here that we require an async function to fetchInvites. Otherwise use a .then()
// Let us move on to our guildMemberAdd event
// Our guildMemberAdd event passes a parameter we called "member"
// Firstly, lets make sure this is not a bot. We simply do not care about them.
if(member.user.bot) return;
// Now we want to get all invites from our client.invites cache.
// Our member variable has a guild property we can use to get the guild.
const cachedInvites = client.invites.get(member.guild.id)
// Now we want to get any new invites that may have been created and add them to our map.
// Note, we are using await meaning you'll need an async function. Otherwise use .then()
const newInvites = await member.guild.fetchInvites();
client.invites.set(member.guild.id, newInvites);
// Now in DiscordJS there isn't a way to see who used an invite.
// Due to this, we will track their uses to see which invite updates.
// We are going to find an invite in our cache that has a smaller amount of uses than it's previous cache amount.
const usedInvite = newInvites.find(invite => cachedInvites.get(invite.code).uses < invite.uses);
// Now we can send an embed to the logging channel of your choice.
// Lets get the MessageEmbed constructor from the discordjs package.
const { MessageEmbed } = require("discord.js");
// Now lets find the logging channel in the current guild.
const logChannel = member.guild.channels.cache.find(channel => channel.name === "logs");
// If the channel doesn't exist, lets do nothing.
if(!logChannel) return;
// We can now use our usedInvites variable to access different information about the invite.
// To simplify this into one line, we can do this:
const { code, uses, inviter, channel } = usedInvites;
// Now lets construct an embed.
const embed = new MessageEmbed()
// We can put the member's tag and avatar in the title.
.setAuthor(`${member.user.tag} joined!`, member.user.displayAvatarURL())
// Here we create a field and use an array to join the description by a newline.
.addField("Information", [
`➤ **Code:** ${code}`,
` ➤ **Created by:** ${inviter.tag}`,
` ➤ **Uses:** ${uses}`,
`➤ **Channel:** ${channel}`
].join('\n'))
// And we can set our embed color to BLUE so it doesn't look plain.
.setColor("BLUE");
// Finally, lets send the embed to our log channel.
logChannel.send(embed);
// Now we're done!
@icourt
Copy link
Author

icourt commented Jun 23, 2020

Thank you @Anish-Shobith for help with edits:

  • Use a Collection rather than a Map to provide extra properties.
  • Use for/of rather than forEach for better performance.
  • Use object destructuring to get properties from usedInvites.

@VenomTR
Copy link

VenomTR commented Sep 9, 2020

Can you do one for guildMemberRemove?

@sell
Copy link

sell commented Nov 3, 2020

can you remove all these comments, then i'll be able to read the code

@anishshobithps
Copy link

can you remove all these comments, then i'll be able to read the code

Comments are given so you understand what is going on , you could remove yourself too!

@ArchimedianIT
Copy link

Where do I put these files? do I make a new file for all three?

@vexdy
Copy link

vexdy commented Jun 3, 2021

Can you do one for guildMemberRemove?

You need to work much better than this gist.

Firstly, you need to check if inviter has an object. If he doesnt, you need to make a object for inviter with some custom information in it so you can actually pass IDs of users which got into guild into an array.

In guildMemberRemove, you should find from inviters objects' user id array to find. If you dont, that means the user is not logged.
If it is logged, filter the array with (user => user.id !== member.id) and rewrite (do this if you are using a json database, which is not recommended. If you are using another database, you should think about another solution).

You can think about this more and you should get much more efficient results than I give you.

@TheRealDuff
Copy link

Please update this to discord.js V13. This isn't working anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment