Creating an invite in a GuildCreate event - discord.js

So I was trying to make my bot send me a DM to every server it joins but I keep getting the API error: Unkown Channel
My code:
bot.on("guildCreate", async guild => {
guild.channels.first().createInvite().then(inv =>
bot.users.get(ownerID).send(`I have been added to **${guild.name}** | ${inv.url}`)
)
});

Okay, this is your problem. I have made the same mistake a few months ago, here's how to fix it.
Since you are using discord.js version 11, guild.channels is indeed a Collection, which you can use .first() on. In this case, you can't do that.
Here's my workaround:
bot.on("guildCreate", async guild => {
var channel;
guild.channels.forEach(c => {
if (c.type === "text" && !channel) channel = c;
});
channel.createInvite({ maxAge: 0 }).then(inv => bot.users.get(ownerID).send(`I have been added to **${guild.name}** | https://discord.gg/${inv.code}`));
});
This basically loops through each channel and finds a valid TextChannel to create an invite.
Hope this helps.

Related

Count reactions to a message after certain time has passed

So I made a bot that has a vote command, where you ask it to say a votable thing and people can only react with tick, cross or N/A in discord.js
What I need to make work now, is a response (either by command or automated over-time, but preferably automated over the time period of 24hrs).
So far, I've tried many different methods and looked all over the Discord.js Docs, but nothing has quite worked out at all. Here's how the code ended up, although it doesn't work:
var textToEcho = args.join(" ");
Client.channels.cache.get('channel ID').send(textToEcho).then(async m => {
await m.react('✅');
await m.react('❎');
await m.react('801426534341541919');
});
message.channel.fetchMessage(textToEcho).then(msg => {
let downVoteCollection = msg.reactions.filter(rx => rx.emoji.name == '✅');
console.log(downVoteCollection.first().count);
}).catch(console.error);
Note: This ONLY checks for the tick response.
It appears that you're trying to get all of the reactions directly after the message has been sent, this will only return the bots reactions, if any at all.
To accurately get the reactions after a certain about of time you'll have to add a .setTimeout(...) function.
var textToEcho = args.join(" ");
Client.channels.cache.get('channel ID').send(textToEcho).then(async m => {
await m.react('✅');
await m.react('❎');
await m.react('801426534341541919');
});
setTimeout(() => {
message.channel.messages.fetch(message.id).then(msg => {
let downVoteCollection = msg.reactions.filter(rx => rx.emoji.name == '✅'); // Filter the reactions
msg.author.send(`You have received **${downVoteCollection.first().count}** votes on your latest poll!`); // Sends the poll owner how many votes they recieved
}).catch(console.error);
}, 86400000); // This will wait 24 hours after the message has been sent to count reactions

Leave message discord.js v12

I have a porblem. My leave message. There I have:
client.on("guildMemberAdd", member => {
const welcomeChannel = member.guild.channels.cache.find(
channel => channel.name === "welcome"
);
welcomeChannel.send(`Hosgeldin :heart: ${member}`);
});
client.on("guildMemberRemove", member => {
const welcomeChannel = member.guild.channels.cache.find(
channel => channel.name === "gelen-giden"
);
welcomeChannel.send(`Bye ${member}!`);
});
and then when somebody left then came <#id>.
I want to find his id because then I can make an link of the person who left.
It look like https://discordapp.com/users/732569703142129685 .
And then it should write 'Member' and this 'member' should be the link.
Please in v12.
Discord returns <#id> because the member that left doesn't have more guilds(servers) in common with you and he is no more in your cache. If you need his id for some deletion of rows in db you can get it as member.id
When a user leaves, he is no longer on the guild, so you can't find a channel on a server he isn't anymore in. You'll need to use client.channels.cache.find() in this case.
have a good day.

Discord.js Forward DM message to specific channel

So, I need a way to forward a message sent in the bot's dm to a specific channel in my server.
this is the code that I got so far:
execute(message, args) {
if(message.channel.type == "dm"){
let cf = args.join(' ')
const cfAdm = message.guild.channels.cache.get('767082831205367809')
let embed = new discord.MessageEmbed()
.setTitle('**CONFISSÃO**')
.setDescription(cf)
.setColor('#000000')
const filter = (reaction, user) => ['👍', '👎'].includes(reaction.emoji.name);
const reactOptions = {maxEmojis: 1};
cfAdm.send(embed)
.then(function (message) {
message.react('👍')
.then(() => message.react('👎'))
/**** start collecting reacts ****/
.then(() => message.awaitReactions(filter, reactOptions))
/**** collection finished! ****/
.then(collected => {
if (collected.first().emoji.name === '👍') {
const cfGnr = message.guild.channels.cache.get('766763882097672263')
cfGnr.send(embed)
}
})
});
}
else {
message.delete()
message.channel.send('Send me this in the dm so you can stay anon')
.then (message =>{
message.delete({timeout: 5000})
})
}
}
But for some reason that I can't seem to understand, it gives me this error:
TypeError: Cannot read property 'channels' of null
If anyone can help me, that would be greatly apreciated.
Thanks in advance and sorry for the bad english
The error here is that you are trying to call const cfAdm = message.guild.channels.cache.get('ID') on a message object from a Direct Message channel ( if(message.channel.type == "dm"){)
DMs don't have guilds, therefore message.guild is null and message.guild.channels does not exist.
You will need to first access the channel some other way. Luckily, Discord.js has a way to access all channels the bot can work with* (you don't need to muck around with guilds because all channels have unique IDs):
client.channels.fetch(ID) or client.channels.cache.get(ID)
(I have not tested this but it seems fairly straight forward)
*See the link for caveats that apply to bots in a large amount of servers.

welcome event sometimes not firing all the way discord.js

My bot is suppose to welcome a member in both the main join/leave channel and also in the chat room so that way we can all welcome the user. For some reason there's a bug where sometimes it'll not send the welcome message to the chat room.
Error:
(node:194) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'send' of null
The welcome event:
client.on('guildMemberAdd', async (member) => {
const welcomeEmbed = new Discord.RichEmbed()
.setAuthor(member.user.tag, member.user.avatarURL)
.setColor(`GREEN`)
.setDescription(`Welcome **${member.user.username}** to member.guild.name! Consider reading <# {HIDDEN}> to have a basic understand of what we do and do not allow.
Come hang out with us in <#{HIDDEN}> and have a good time!`)
.setFooter(`Member ID: ${member.id}`)
member.guild.channels.find(channel => channel.id === 'HIDDEN').send(welcomeEmbed);
const welcomeEmbed2 = new Discord.RichEmbed()
.setAuthor("New Member Joined!", member.user.avatarURL)
.setDescription(`**${member.user.tag} has joined the server!**`)
.setColor('GREEN')
member.guild.channels.find(channel => channel.id === 'HIDDEN').send(welcomeEmbed2); // This is the one providing the error sometimes
});
I've tried different things such as a .then or just recoding it in different ways to see if it'll work. So far, this has been the only thing my friends do not understand why it's providing errors
You can just fetch the channel by ID using client
client.channels.fetch("SOME_CHANNEL_ID").then(channel => {
channel.send(welcomeEmbed);
})

DiscordJS Backdoor Command

I have had reports off my support server of my discord js bot of my bot being abused in multiple ways.
I want to have a way upon launch of my bot to see a list of servers as well as invite links to those servers. I do not know the id of server or anything.
The most I've managed to find out how to do is this
var server = client.guilds.get("idk the id part");
console.log('I am in the following servers:');
server.createInvite().then(invite =>
console.log(server.name + "-" + invite.url)
);
});```
In your ready event (client.on('ready', () => {}), add the following lines:
client.guilds.tap(guild => {
console.log(`Name: ${guild.name} ID: ${guild.id}`);
})
This should output
Name: Test1 ID: 00000000000000
in the console for each server.
Also, considering that making a lot of invites might clog up your bot, and is generally more of a hindrance than help to server admins, you might consider making a createinvite command:
const svID = args[0];
const guild = client.guilds.find(guild => guild.id === svID);
const channel = guild.channels.find(channel => channel.position === 1);
channel.createInvite()
.then(invite => message.reply(invite.code));
You can either wait for the bot to emit it's ready event and loop through the guild collection:
client.once('ready', () => {
// client.guilds should be ready
});
or handle each guild individually:
client.on('guildCreate', (guild) => {
// The guild the bot just joined/connected to
// Should also be emitted when the bot launches
});
Either should work, but my recommendation would be the second approach, as this will also allow you to track join events whilst the bot is running.

Resources