Logging message.author from one command and pulling it to another - javascript

I am creating a discord bot that does tickets which are used as applications and I have most of it done except I want the bot when the -close command is used to log the ticket that was closed.
I've tried a few things such as calling a .then to send a message to the logging channel of the specific channel being deleted then calling another .then when it was deleted except it would still send the message saying #deleted-channel. I tried this in a few ways but I couldn't figure it out.
Another solution I tried was creating a variable in the -apply command that would log the name of the person that created the message but I realized that after many people used the command apply if I attempted to close one it would log the most recent applicant's name, not the application I was closing
-apply command
const reason = message.content.split(" ").slice(1).join(" ");
var tAuthor = message.author.tag
if (!message.guild.roles.exists("name", "[»] Helpers")) return message.channel.send(`Server does not have role set correctly., This error has been logged. \nPlease contact bot developer <#251557870603075586>`);
if (message.guild.channels.exists("name", "t-staff-" + message.author.tag)) return message.reply(`You already have an application open.`);
message.guild.createChannel(`t-staff-${message.author.tag}`, "text").then(c => {
let role = message.guild.roles.find("name", `${config.role}`);
let role2 = message.guild.roles.find("name", "#everyone");
c.overwritePermissions(role, {
SEND_MESSAGES: true,
READ_MESSAGES: true
});
c.overwritePermissions(role2, {
SEND_MESSAGES: false,
READ_MESSAGES: false
});
c.overwritePermissions(message.author, {
SEND_MESSAGES: true,
READ_MESSAGES: true
});
c.setParent(message.guild.category.exists("name", "t-staff-"))
message.reply(`:white_check_mark: Your application has been created, #${c.name}.`);
const embed = new Discord.RichEmbed()
.setColor(0xCF40FA)
.setTitle(`Staff Application`)
.setDescription(`<#${message.author.id}>`)
.addField(`Requirements`, `You must meet all the requirements:\n\n1. Professional attitude and grammar\n2. Working Microphone\n3. No severe punishments on the server. (Racial Slurs, DDos Threats, etc..)\n4. You must be over the age of 14`)
.addBlankField()
.addField(`Note:`, `Please check in announcements for open staff positions`)
.addField(`Note:`, `Please paste the format with your answers`)
.addField(`Note:`, `If your previous application was denied you must wait one week to sumbit a new one`)
.addBlankField()
.addField('Format', `\nWhat position are you applying for: \n\nMinecraft username: \n\nPrevious Minecraft usernames: \n\nWhat is your age: \n\nTimezone: \n\nAbility to record Minecraft video: \n\nHow much time do you have to contribute a week? \n\nWhat do you consider to be your biggest weaknesses?\n\nWhat's your dream job? \n\nHow do you deal with pressure or stressful situations? \n\nAny previous staff skills or experience? \n\nHave you ever been banned or punished for your actions on this server? If so, please include details. \n\nTell us about a time you made a mistake within the last year? How did you deal with it? What did you learn? \n\nAre you currently staff on any other servers? \n\nWhere did you hear about nodepvp? \n\nHave you made any previous applications, if so how many and what is the date of your last one? \n\nWhat would be your daily tasks for the rank you are applying for \n\nAnything else we should know? `)
.addBlankField()
.setTimestamp();
c.send({ embed: embed });
client.channels.get(`568210811009499136`).send(`:white_check_mark: !!!Ticket Created ${message.author} at **${current_date}**`);
-close command
if (!message.channel.name.startsWith(`ticket-`)) return message.channel.send(`You can't use the close command outside of a ticket channel.`);
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.channel.send(`${message.author} Do not have permission to close this application`);
// Confirm delete - with timeout (Not command)
message.channel.send(`Are you sure? Once confirmed, you cannot reverse this action!\nTo confirm, type \`/confirm\`. This will time out in 10 seconds and be cancelled.`)
.then((m) => {
message.channel.awaitMessages(response => response.content === '/confirm', {
max: 1,
time: 10000,
errors: ['time'],
})
.then((collected) => {
message.channel.delete();
})
.catch(() => {
m.edit('Ticket close timed out, the ticket was not closed.').then(m2 => {
m2.delete();
}, 3000);
});
});
When I tried to log this by using a .then function in the close command right before
.then((collected) => {
message.channel.delete();
It still sends the message to the channel saying #deleted-channel even though I'm sending the command before the channel is deleted.

If you send a message with a channel mention, such as #test, it will stay as a clickable link to the test channel, as long as that channel exists. If you delete that channel, all links will seize and become a dull #deleted-channel.
One solution would be to log Closed ${channel.name}, then deleting the channel.
You cannot make it so it keeps the linked message (unless you make it so no one can see the deleted channel by denying read access to closed tickets for everyone except staff for logging purposes).

Related

Discord.js || Can bot track ban list?

There are a lot of to ban a user in a server, you can do it manually or with another bot. I want my bot to scan a banlist, and if someone will get banned, it will send a message "user (id) has been banned
I started writing smt but now, I had no idea what can I do to check it.
EDIT: It's working now, but it still need to find this user id.
client.on('guildBanAdd', message => {
client.user.cache.find() //idk how to define it
const channel1 = client.channels.cache.find(channel => channel.id === "158751278127895");
channel1.send('12512');
})
You don't have to fetch bans because the guildBanAdd event parses a GuildBan object,which als includes a User object.
client.on('guildBanAdd', ban => {
console.log(ban.user.username); // Username
})
message.channel won't work because there isn't a message object.
If you want to get the executor (moderator) who performed the ban, kick etc.
There is a good guide for this Working with Audit Logs

Discord.JS | Auto-Kick someone after posting a specific link?

Im trying to add some "auto-mod" features to my bot, recently I added a small command that will delete fake steam trade links (as they seem to be getting more common every day) as you can see in this image basically it token logs your discord account, then spams the same message in all of your servers. So I developed some code to auto-delete these links, and reply with a gif... but I want more, as I believe these bots don't stop spamming until they are removed from the server, so I want to add a function to auto kick them, and DM them a message about why they were kicked, and an invite back to the server (as most of these people quickly get their accounts back) sorry for the long talk, my current WORKING code is below:
client.on('message', (message) => { //whenever a message is sent
if (message.content.includes('https://stearncomminuty.ru/tradofferr/new/?partner=1284276379&token=iMNdOshG')) {
message.delete() //delete the message
.then(message.channel.send('https://media.discordapp.net/attachments/859211601726275636/859977676919013386/5f36hh.gif'))
}})
Any help or suggested improvements would be appreciated!
You can solve this really simply. Just add another .then() after your first one and call the <guildMember>.kick() function.
For example:
client.on('message', (message) => { //whenever a message is sent
if (message.content.includes('https://stearncomminuty.ru/tradofferr/new/?partner=1284276379&token=iMNdOshG')) {
message.delete() //delete the message
.then(message.channel.send('https://media.discordapp.net/attachments/859211601726275636/859977676919013386/5f36hh.gif'))
.then(() => message.member.kick('User kicked for sending spam links.'))
}
});
Also, why don't you just put https://stearncomminuty.ru/tradofferr/ in your include()? This will also delete similar fake-steam-URLs and not just a specific one because it is not unlikely that there are lots of URLs starting like this.

How to make a bot find a channel owner / compare to the author's ID

I'm making a bot where if you do d!move, the bot will move the channel where the message was sent in under a category via ID. I also want to make it so that whoever does the command has permissions such as MANAGE_CHANNELS, which I've already added. The problem is that when I want to confirm whoever created that channel is the person that activated the command, the bot says yes. I did this on an alt account, where I made the channel and my alt was the one initializing it, and the bot said "success!" I also wanted to make it so if someone else made the channel, and when I did it, it would work because I made the bot know my ID.
I've researched Google and found nothing.
I've tried using a function with fetchAuditlog but get anywhere.
if(!message.channel.client.user.id == message.author || !message.author.id == `329023088517971969`) return message.channel.send("You don't own this channel!")
else message.channel.send("success!");
message.channel.setParent(`576976244575305759`);
I expect the bot to be able to check if the author created the channel, and lead to You don't own this channel if they don't own it. But if they do then the bot moves the channel.
The actual result is the bot moving the channel anyway regardless if they own the channel or not.
As #André has pointed out, channel.client represents the client itself, not the user who created the channel. Also, the last line in your code is not part of the else statement, so that's why it's run regardless of the conditions you defined.
To reach a solution, you can make use of the guild's audit logs. You can search for entries where the user is the message author and a channel was created. Then, all you have left is to check if one of those entries is for the current channel, and run the rest of your code if so.
Sample:
message.guild.fetchAuditLogs({
user: message.author,
type: 'CHANNEL_CREATE'
}).then(logs => {
if (!logs.entries.find(e => e.target && e.target.id === message.channel.id)) return message.channel.send('You don\'t own this channel.');
else {
// rest of code
}
}).catch(err => console.error(err));
When you go <anything>.client.user it will return the bot client.
If you want to see who created the channel you would have to check the Audit Logs or save it internally.
I've checked the documents. Here's what it says for .client about the
channel. It says the person that initialized the channel, or the
person that created it.
On documentation I see this:
The client that instantiated the Channel
instantiated is different of initialized

How do I add multiple reactions?

I've looked everywhere for answers and I can't figure this out.
Here's what I want to do:
I want to run some command initially for my bot to send an embed to a specific channel only admins have access to. Done.
Then the bot will immediately react to its own message with the number emojis 1, 2, and 3. Problem.
I don't want the bot to await a reaction to the message from an admin. This embed is meant to stay there UNTIL an admin reacts to it. That could be within 1 minute, or 3 days, but if I have to reboot the bot for any reason then it will stop awaiting the reaction. So I have an event that triggers when someone reacts with a given emoji, this works. It can be improved, but it functions:
bot.on("messageReactionAdd", (messageReaction, user) => {
console.log(messageReaction);
if(reaction.emoji.name === "\u0031\u20E3") {
message.channel.send('one'); //This is temporary to test it out. There will be other code here eventually.
}
else if(reaction.emoji.name === "\u0032\u20E3") {
message.channel.send('two');
}
else if(reaction.emoji.name === "\u0033\u20E3") {
message.channel.send('three');
}
});
My problem is that when I run this code:
let cmdEmbed = new discord.RichEmbed()
.setTitle('**Command Menu Test**')
.setDescription("Type commands")
.setAuthor('InfernoBot', 'https://cdn.discordapp.com/avatars/533089334224617474/17ddec7cb178601d17964040ed8dc32d.png?size=2048')
.setColor(0xD41519);
message.channel.sendEmbed(cmdEmbed).then(function (message) {
message.react('\u0031\u20E3')
message.react('\u0032\u20E3') //This doesn't run
message.react('\u0033\u20E3') //This doesn't run
});
It only ever reacts with the '1' emoji.
How do I make it react with emoji numbers 1, 2, and 3, without awaiting for a reaction?
PS: I'm going to implement some code that will resend the exact same embed with the same reactions once the existing embed has been reacted to, to reset it.
EDIT: The bot doesn't always react with 1. However, it only ever adds one reaction. It's not consistent.
.
Found the answer about 30 mins after posting this. I'll share for anyone who was having the same issue.
My first chunk of code in the original post was causing the bot to break and reboot.
I replaced the first chunk of code with:
bot.on("messageReactionAdd", (reaction, user) => {
if(user.toString() !== '<#533089334224617474>' /*InfernoBot ID*/) {
console.log('User is not InfernoBot')
if(reaction.emoji.name === "\u0031\u20E3") {
//code here
}
}
});
And I replaced the second chunk of code with:
let cmdEmbed = new discord.RichEmbed()
.setTitle('**Command Menu Test**')
.setDescription("Type commands")
.setAuthor('InfernoBot', 'https://cdn.discordapp.com/avatars/533089334224617474/17ddec7cb178601d17964040ed8dc32d.png?size=2048')
.setColor(0xD41519);
message.channel.sendEmbed(cmdEmbed).then(function (message) {
message.react('\u0031\u20E3').then(() => message.react('\u0032\u20E3')).then(() => message.react('\u0033\u20E3'));
});

Assigned Roles by Reactions

I have recently been trying to make a Reaction-to-Role bot and have been struggling with some criteria for making it.
I have researched and looked at other peoples' versions of a similar bot on it, yet I have not been able to use it purposefully in my own code.
The goal of the bot is to have multiple options on a message. Here's an example of what it would look like as a message.
**What do you drive?**
🚙 - A car
🚲 - A bicycle
❌ - Nothing
There would be reactions under the message of each emoji that was specified. Once a user clicked on one of these emojis, it would add a role to them such as "Drives a Bike" or "Rides a Bicycle."
I have managed to go as far as making an addrole command (which receives the message the bot will react to, the emoji, and the role it assigns) and stores some info to a JSON file.
The area in which I have been having issues is actually capturing each user that reacts to the specific message, finding out which reaction they sent, and assigning the role assigned to that emoji.
Here is my current code, I'm thank you for any help you may provide :)
addrole.js
if(!args[0] || !args[1] || !args[2] || !args[3]) return message.reply("please use the following format: `autorole #channel messageID icon #role`.");
let channel = message.mentions.channels.first();
let messageID = args[1];
let icon = args[2];
let role = message.mentions.roles.first();
if(!channel.fetchMessage(messageID)) return message.reply("could not find the specified message. Please check the channel and message ID again.");
channel.fetchMessage(messageID).then(msg => {
msg.react(icon);
info[role.name] = {
roleID: role.id,
channelID: channel.id,
icon: icon,
};
fs.writeFile("./configs/info.json", JSON.stringify(info), (err)=>{
if(err) console.log(err);
});
});
I know that creating an event named messageReactionAdd and messageReactionRemove are needed, but I'm not sure how to find their variables and match them accordingly.
Additionally, I am not sure how to make it constantly watch one message even after a restart. From some testing, I noticed that messageReactionAdd would not continue watching the specified messages reactions after a restart.
I am looking for any guidance/help that anyone may provide, thank you!
I've seen on: https://github.com/Sam-DevZ/Discord-RoleReact/blob/master/roleReact.js that there is an event. I've tried this out and it's working.

Categories