I'm looking for a way to get the number of bans a moderator has done, here is what I have so far. I'm guessing I have to loop thru each ban?
let targetMod = message.mentions.users.first()
message.guild.bans.fetch().then((bans) => {
bans.forEach((ban) => {
//My problem is here, I dont know how to check who did the ban
})
})
The moderator is not actually provided in the info. You will need to check the audit logs for this (will only go back to a certain time, it's not fully accurate)
let logs = await message.guild.fetchAuditLogs()
logs = logs.entries.filter(e => e.action === "MEMBER_BAN_ADD")
logs = logs.entries.filter(e => e.executor?.id === targetMod.id)
console.log(logs.size) //should be the rough amount of bans
Related
I have searched through similar questions, but non seems to be answering what I am looking for
So basically I have this website, where an emoji (lets use emoji for it to be easy) is generated randomly was saved in local storage. As you know, it is not effective, since a user can simply clear his/her history and that random value was deleting.
Example of the code
<script>
var res = localStorage.getItem('img');
if(res == null){
const myList = ['🐒', '🐕', '🐈', '🐅', '🐎', '🦓', '🐄', '🦒', '🐘', '🦔', '🦉', '🐊', '🦖', '🐬', '🦈', '🦋', '🐞', '🦂'];
res = myList[Math.floor(Math.random() * myList.length)];
localStorage.setItem('img', res);
}
console.log(res);
document.querySelectorAll('.emoji').forEach(span => span.textContent = res)
</script>
Then I found out about the fingerprint JS and was very happy about it, since the user's ID doesnt delete even if the history has been deleted.
However, I don't seem to understand of how to do exact same emoji generation with the fingerprint JS
<script>
// Initialize the agent at application startup.
const fpPromise = import('https://openfpcdn.io/fingerprintjs/v3')
.then(FingerprintJS => FingerprintJS.load())
// Get the visitor identifier when you need it.
fpPromise
.then(fp => fp.get())
.then(result => {
// This is the visitor identifier:
const visitorId = result.visitorId
console.log(visitorId)
alert(visitorId)
})
</script>
I understand that I have to add a const, however, all the time I tried to implement the code for random emoji generation to the fingerprint js, everything failed
Could you give me some advice or an example of the working alike code/idea?
So that at the end the stored values would be like:
ID : 12312312313123
Emoji : 🐒
Thanks in advance!
Get the hash number (I used this CRC implementation), modulo length of your emoji list and just pick the given emoji.
<script>
// Initialize the agent at application startup.
const fpPromise = import('https://openfpcdn.io/fingerprintjs/v3')
.then(FingerprintJS => FingerprintJS.load())
const crc32=function(r){for(var a,o=[],c=0;c<256;c++){a=c;for(var f=0;f<8;f++)a=1&a?3988292384^a>>>1:a>>>1;o[c]=a}for(var n=-1,t=0;t<r.length;t++)n=n>>>8^o[255&(n^r.charCodeAt(t))];return(-1^n)>>>0};
// Get the visitor identifier when you need it.
fpPromise
.then(fp => fp.get())
.then(result => {
// This is the visitor identifier:
const visitorId = result.visitorId
const myList = ['🐒', '🐕', '🐈', '🐅', '🐎', '🦓', '🐄', '🦒', '🐘', '🦔', '🦉', '🐊', '🦖', '🐬', '🦈', '🦋', '🐞', '🦂'];
const listLength = myList.length
const visitorIdNumber = crc32(visitorId);
const selectedEmoji = myList[visitorIdNumber % listLength];
localStorage.setItem('img', selectedEmoji);
})
</script>
So I have a poll command, it will gonna &poll [pollEvent] [agreeStatement] [disagreeStatement]
Here's my code
if (command === 'poll') {
let pollMessage = args[0]
let aggree = args[1];
let disagree = args[2];
const agreeEmoji = '<a:verified:753654287338569778>'
const disagreeEmoji = '<:no:753654286134542447>'
if (!pollMessage) return message.reply("What are you going to poll?")
if (!aggree) return message.reply('Please insert the aggree statement')
if (!disagree) return message.reply("Please insert the disagree statement")
const pollEmbed = new Discord.MessageEmbed()
.setTitle('Poll!')
.setColor('#00FF2A')
.addFields(
{ name: pollMessage, value: `
<a:verified:753654287338569778> ${aggree}
<:no:753654286134542447> ${disagree}`}
)
message.delete();
let msg = await message.channel.send(pollEmbed);
await msg.react('753654287338569778')
await msg.react('753654286134542447')
const filter = (reaction, user) => reaction.emoji.id === '753654287338569778' || reaction.emoji.id === '753654286134542447'
const result = await msg.awaitReactions(filter, {time: 5000}).then((collected) => {
if (msg.reactions.cache.get('753654287338569778').count-1 <= 0 || msg.reactions.cache.get('753654286134542447').count-1 <= 0) return message.channel.send("No one voted sorry this poll is aborted")
let resutEmbed = new Discord.MessageEmbed()
.setTitle('Voting Complete!')
.setColor('#00FF2A')
.addFields(
{name: pollMessage, value: `<a:verified:753654287338569778> ${aggree} => ${collected.get('753654287338569778').count-1}
<:no:753654286134542447> ${disagree} => ${collected.get('753654286134542447').count-1}`}
)
msg.edit(resutEmbed)
msg.reactions.removeAll()
})
}
But the problem is, when I said &poll Should I go outside? Yes No it will shown like, because I want to be like &poll Should I go outside? Yes No then the bot will add Yes and No as the agree and disagree statement and make Should I go outside? as poll event message, any ideas?
Seems like the Array Destructuring and the rest operator ES6s features will come handy for your command.
You can "destructure" your args Array elements and give each one a variable name by doing the following:
// where: let [word1, word2, ...rest] = args
// is the same as:
let [word1, word2, ...rest] = ['Should', 'I', 'go', 'outside', 'yes', 'no'];
By doing this you can start working with the command entries, no matter how long these would be. Here rest is also declared as a variable and contains the "rest" of the elements that weren't named:
console.log( rest );
// will prompt •> ['go', 'outside', 'yes', 'no']
If you want to enable personalized responses per poll, your implementation could be upgraded to:
let [...question, option_a, option_b] = args;
Which would be fine for this case, although I would advise against making the command's answer options personalized if you're just looking to implement a yes / no poll.
If in the future you would like to offer more than two answer choices, you could design the command to detect them after a special character like:
&poll What's the coolest pet: dog, cat, panda
(Special character being : here)
You may also want to consider performing an Array.join() method and String.split() to process your command entry as the ...rest operation way would only work for single worded answer options: sure / nah, and errors would come out if you get an entry like:
&poll Should I go outside?: sure thing nah
as option_a will contain thing / and option_b contain nah
My main goal is for someone with message managing permissions to type a command for deleting a message but be able to specify how many messages they'd like to delete.
I have tried messing with variables but I don't have much knowledge on them, usually ending in some errors. I've tried replacing the value of messages deleted (the 2) with the variable with success but I'm clueless when it comes to changing the variable with a message.
if(message.member.hasPermission('MANAGE_MESSAGES')) {
if(message.content.startsWith(`${prefix}delete`)) {
message.channel.bulkDelete(2)
}
}
I will suppose you have it on message event.
This is one of many ways you can do it:
if(message.content.startsWith(`${prefix}delete`)) {
const user = message.mentions.users.first();
// Parse Amount
const amount = !!parseInt(message.content.split(' ')[1]) ? parseInt(message.content.split(' ')[1]) : parseInt(message.content.split(' ')[2])
//Check if it the amount for message to delete where declared
if (!amount) return message.reply('Must specify an amount to delete!').then(msg => msg.delete(15000));
// Fetch 100 messages (will be filtered and lowered up to max amount requested)
message.channel.fetchMessages({
limit: 100,
}).then((messages) => {
//I declare the messages like that with amount + 1 to delete the command itself
messages = messages.array().slice(0, amount + 1);
//And finally buldDelete deletes the desired amount
message.channel.bulkDelete(messages).then(messages => console.log(`Bulk deleted ${args[0]} messages`))
.catch(console.error);
});
You would need to split message.content, which will return an array that I'll name args for this example. Then, args[1] should be the number you are looking for.
const prefix = '#'
const args = message.content.split(' ')
if(message.member.hasPermission('MANAGE_MESSAGES')) {
if(message.content.startsWith(`${prefix}delete`)) {
message.channel.bulkDelete(args[1])
}
}
Et voilà ! You just need to make sure that args[1] is a number now.
This is my first Discord bot and I am stuck.
I want this bot to pick a winner for a quiz.
So, I am trying to fetch all messages with correct answer from a random user.
However the following code does not pick up a user with right answer.
Could you please tell me how I should do this??
const chan = message.channel;
const answer = 'test';
//Select a random user
const user = message.channel.members.random();
const userid = user.id
//fetch messages from the user and contains answer
chan.fetchMessages().then(messages => {
const usermsgs = messages.filter(
m => m.author.id === `${user.id}` &&
m.content === answer);
//check if the answer is in the messages
if(usermsgs){
message.reply('winner is' + `${user.user}`);
}else{
message.reply('No Winner');
}
}).catch(console.error);
I'm not familiar with discord.js, but a littling reading into their docs came up this.
Instead of randomizing the entire channel's user base, you want to randomize the users who correctly answered the question. Since discord.js returns a Collection object for the filter function, you can use its random function there.
chan.fetchMessages().then(messages => {
const usermsgs = messages.filter(
m => m.content === answer);
if(usermsgs){
const randomCorrectUser = usermsgs.random().author;
message.reply('winner is' + `${randomCorrectUser.username}`);
}else{
message.reply('No Winner');
}
}
Uhh this is old but you could probably do
const randomCorrectUser = usermsgs.random().author.tag;
for name#0000 or
const randomCorrectUser = usermsgs.random().author.username;
for just the name
How I can list members in a role using Discord.js.
My code:
client.on("message", message => {
var guild = message.guild;
let args = message.content.split(" ").slice(1);
if (!message.content.startsWith(prefix)) return;
if (message.author.bot) return;
if(message.content.startsWith(prefix + 'go4-add')) {
guild.member(message.mentions.users.first()).addRole('415665311828803584');
}
});
How would I go about listing all the members that have the go4 role in an embed. When the message .go4-list is entered in a channel I would like the bot to respond with the embed.
<Role>.members returns a collection of GuildMembers. Simply map this collection to get the property you want.
Here's an example according to your scenario:
message.guild.roles.get('415665311828803584').members.map(m=>m.user.tag);
This will output an array of user tags from members that have the "go4" role. Now you can .join(...) this array to your desired format.
Also, guild.member(message.mentions.users.first()).addRole('415665311828803584'); could be shortened down to: message.mentions.members.first().addRole('415665311828803584');
Here's a rough example of how it would look as a result:
client.on("message", message => {
if(message.content.startsWith(`${prefix}go4-add`)) {
message.mentions.members.first().addRole('415665311828803584'); // gets the <GuildMember> from a mention and then adds the role to that member
}
if(message.content == `${prefix}go4-list`) {
const ListEmbed = new Discord.RichEmbed()
.setTitle('Users with the go4 role:')
.setDescription(message.guild.roles.get('415665311828803584').members.map(m=>m.user.tag).join('\n'));
message.channel.send(ListEmbed);
}
});
As #Wright mentioned in his answer, if there are over many members it will throw an error as an embed can only hold 2048 characters maximum, so you may want to do some checks before sending out the embed and then handle oversized embeds by either splitting them into multiple embed messages, or using reaction based pages maybe.
if(message.content.startsWith("//inrole")){
let roleName = message.content.split(" ").slice(1).join(" ");
//Filtering the guild members only keeping those with the role
//Then mapping the filtered array to their usernames
let membersWithRole = message.guild.members.filter(member => {
return member.roles.find("name", roleName);
}).map(member => {
return member.user.username;
})
let embed = new discord.RichEmbed({
"title": `Users with the ${roleName} role`,
"description": membersWithRole.join("\n"),
"color": 0xFFFF
});
return message.channel.send({embed});
}
Example use on discord:
Do note though that if there are a lot of members with the role, you may get an error telling you that you have exceeded the number of chars you can put in an embed. In such a case, you can decide to send multiple embeds splitting the users.
I tried Newbie's solution, but it didnt work
message.guild.roles.get('415665311828803584').members.map(m=>m.user.tag);
Gave me an error that .get is not a function maybe something changed with discord.js,
Adding cache after roles made it work.
message.guild.roles.cache.find(r => r.name === args[0]);
Since Discord v12, you now have to use roles.add() instead of addRole()
To mention the user in the embed (this looks a lot better than just text) remove .tag so it is just
(m => m.user).join('\n')