Discordjs mentions not always resolving - discord.js

I am trying to implement a list of users inside a Discord Embed. The list contains a mention for each user and I have been partially successful in accomplishing that. However, it appears that my bot cannot mention everyone, some of the mentions aren't being resolved, and I wonder why is that so. Is it related to the cache? Is there a way to fetch the mentions like fetching users that aren't cached by the bot?
An image of the bot output
leastActiveMembers.forEach((member, index) => {
let mention = `<#${member.user.id}>`;
let lastActive = "";
if (member.user.activity) {
lastActive = new Date(member.user.activity.latestActivityTimestamp).toLocaleString("en-GB");
} else {
lastActive = "Never";
}
lastActive = lastActive.padEnd(20, " ");
leaderBoardRepresentation += `\`${lastActive} ⌛ \`${mention}\n`;
});
const embed = new Discord.MessageEmbed()
.setColor('#DAA520')
.setTitle("🕒 Activity Board ")
.setDescription(leaderBoardRepresentation)
.setThumbnail('https://i.imgur.com/v5RR3ro.png')
.setFooter({ text: footer, iconURL: "" })
I am using discordjs v13.

As #NotTrixxie said, this is Discord's built-in code which we cannot modify. If a user has no relation to the bot (not in the server), it will display it. If you want the username to show, you can display the username instead of mentioning which will work. See below for an example of this:
leastActiveMembers.forEach((member, index) => {
const mention = member.user.username;
let lastActive = '';
if (member.user.activity) {
lastActive = new Date(member.user.activity.latestActivityTimestamp).toLocaleString('en-GB');
} else {
lastActive = 'Never';
}
lastActive = lastActive.padEnd(20, ' ');
leaderBoardRepresentation += `\`${lastActive} ⌛ \`${mention}\n`;
});
const embed = new Discord.MessageEmbed()
.setColor('#DAA520')
.setTitle('🕒 Activity Board ')
.setDescription(leaderBoardRepresentation)
.setThumbnail('https://i.imgur.com/v5RR3ro.png')
.setFooter({
text: footer,
})
Hoped this helped!

Related

Discord.js v12.5.3 is there a way I could add role(s) on interaction?

I am 90% done with my application system but I am missing one thing
I am trying to add roles when someone applies,
I tried doing it with this
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
but it does not add the roles (I don't get any errors doing it)
is there any way I can do it with the code below for the interaction?
client.ws.on("INTERACTION_CREATE", async (interaction) => {
// If component type is a button
if (interaction.data.component_type === 2) {
const guildId = interaction.guild_id;
const userId = interaction.member.user.id;
const buttonId = interaction.data.custom_id;
const member = client.guilds.resolve(guildId).member(userId);
if (buttonId == "send_application") {
// Reply to an interaction, so we don't get "This interaction failed" error
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "I have started the application process in your DM's.",
flags: 64 // make the message ephemeral
}
}
});
I would appreciate the help with this
When you add a role it should be a snowflake value, so you should add using the ID and not the role it self
Incorrect:
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
Correct:
// using the ID Directly
member.roles.add('761996603434598460')

Discord JS - forEach looped embed

I'm quite new to Javascript, normally a Python person. I've looked at some other answers but my embed does not add the fields as expected. The embed itself is sent.
My Discord bot follows the guide provided by the devs (primary file, slash commands, command files). I am trying to loop through the entries in an SQLite query and add them as fields.
My command file is below.
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageEmbed } = require('discord.js')
const sqlite = require('sqlite3').verbose();
module.exports = {
data: new SlashCommandBuilder()
.setName('rank')
.setDescription('Rank all points.'),
async execute(interaction) {
const rankEmbed = new MessageEmbed()
.setColor('#0099ff')
.setTitle('Rank Board')
let db = new sqlite.Database('./databases/ranktest.db', sqlite.OPEN_READWRITE);
let queryall = 'SELECT name, points FROM pointstable ORDER BY points DESC'
db.all(queryall, [], (err, rows) => {
if (err) {
console.log('There was an error');
} else {
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, true);
});
}
})
return interaction.reply({embeds: [ rankEmbed ] });
}
}
I would also like to convert row.name - held as Discord IDs - to usernames i.e. MYNAME#0001. How do I do this by interaction? I was able to obtain the User ID in another command by using interaction.member.id, but in this case I need to grab them from the guild. In Python I did this with await client.fetch_user but in this case the error await is only valid in async functions and the top level bodies of modules is thrown.
Thanks.
OK I've solved the first aspect, I had the return interaction.reply in the wrong place.
Relevant snippet:
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, false);
})
return interaction.reply({embeds: [rankEmbed ]} );
Would still appreciate an answer to the converting row.name (user ID) to user name via fetch.
I've solved the second aspect also. Add the below into the loop.
rows.forEach((row) => {
let client = interaction.client
const uname = client.users.cache.get(row.name);
rankEmbed.addField('\u200b', `${uname}: ${row.points}`, false);

How to ban user on pinging someone?

I'm trying to make a discord bot on, when pinging the owner, auto bans the author that pinged the player. The issue is, it bans the player for saying anything, how would I make it that it'd only ban if they pinged the owner?
Here's the code.
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = '<#329005206526361610>'
client.once('ready', () => {
console.log("Wary's Defender Bot is up");
});
function getUserFromMention(mention) {
if (!mention) return;
if (mention.startsWith('!')) {
mention = mention.slice(1);
}
if (mention.startsWith('<#329005206526361610') && mention.endsWith('>')) return {
// mention = mention.slice(2, -1),
return: client.users.cache.get(mention)
}
}
client.on('message', _message => {
// if(!_message.content.users.has('#warycoolio')) return;
const user = getUserFromMention(_message.content);
if(user) return;
console.log('found target')
var member = _message.author
var rMember = _message.guild.member(_message.author)
// ban7, 'lol.'
rMember.ban({ days: 7, reason: 'They deserved it'}); {
// Successmessage
console.log('target dead.')
}
});
You can do this by checking _message.mentions.users with .has() and passing in the guild owner's id.
Use .has() instead of checking message content, this will automatically check the Message#mentions collection.
Dynamically get the guild owner's id using Guild#ownerID.
client.on('message', _message => {
if (_message.mentions.users.has(_message.guild.ownerID)) {
_message.author.ban({ days: 7, reason: 'They deserved it'});
}
});
You could just do a quick check to see if the mentions include a mention to the owner of the server, and then ban the user.
client.on("message", _message => {
if (_message.mentions.users.first().id === "owner id") {
message.author.ban()
}
})

Bot readout for who used a command

Wanting to have a readout channel for my bot to keep track of what happens, just like a second console log. Want to be able to have it read out in the message the username of the person who used the command. Any ideas? Also, in a similar note, is there a way to copy the console readout and possibly just paste that instead?
var Scraper = require('images-scraper');
const google = new Scraper({
puppeteer: {
headless: true
},
})
module.exports = {
name: 'image',
description: 'Google image scraper',
async execute(message, args){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const image_query = args.join(' ');
if(!image_query) return message.channel.send('Please enter a valid image search.');
const image_results = await google.scrape(image_query, 1);
message.channel.send(image_results[0].url);
readout.send('Image sent');
}
}
I think you want
message.author.username (It gives username who sent the message)
or message.member (it gives user as a guildmember)
Just access the author property of the message object and include it via a template string into the message:
readout.send(`Image sent to ${message.author.username}`);
Ended up doing an embed system in a separate channel on my discord.
const Discord = require('discord.js');
module.exports = {
name: 'suggestionlog',
description: 'logs suggestion',
execute(message){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const embed = new Discord.MessageEmbed()
.setColor('FADF2E')
.setTitle(message.channel.name)
.setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(message);
readout.send(embed)
.catch((err)=>{
throw err;
});
}
}

guild.icon & guild.iconURL() not working in embed thumbnail

I want to set guild icon as the thumbnail of embed but neither guild.icon nor guild.iconURL() work
bot.on('message', message => {
if(message.author.bot) return;
if(message.channel.name === 'verify') {
if(message.content === '!verify') {
message.delete()
let dm = message.author;
let server = message.guild.name;
let servericon = message.guild.iconURL();
console.log(servericon)
let attachment = new Discord.MessageAttachment(this.choose , 'chosen.png')
let embed = new Discord.MessageEmbed()
.setTitle(`**Welcome to ${server}**\n\nCaptcha`)
.setDescription("Please complete the captcha given below to gain access to the server.\n**Note:** This is case sensitive")
.setAuthor('Mr.Verifier', "https://i.ibb.co/nckjDjG/hmm.png")
.setThumbnail(servericon)
.addField(
{ name: '**Why all this?**', value: 'This is to protect the servers from\nmalicious raids of automated bots'}
)
.setImage(`attachment://chosen.png`)
dm.send(embed)
}else{
message.delete();
}
};
})
You need to use guild.iconURL().

Resources