Embed command discord.js character limit - node.js

I'm making a command to identify the people who have a role, and he will list all the people with the role, but he ends up exceeding the character limit, because there are many people with that role, what could I do?
const { RichEmbed } = require("discord.js");
exports.run = (bot, message, args) => {
let staff = bot.emojis.get("718580359704477766")
const embed = new RichEmbed()
.setColor("#91e0ff")
.setTitle(`${staff} **| Lista de Staffers do Server**`)
.setThumbnail(bot.user.displayAvatarURL)
.addField(`Equipes Staffers:`, `<a:red2:721546087701282898>・<#&718861978864582707> - (${message.guild.roles.get('718861978864582707').members.size} staffs)`)
.setFooter(`Atenciosamente - ${bot.user.username}`, bot.user.displayAvatarURL)
.setTimestamp()
message.channel.send(embed).then(async msg => {
await msg.react('721546087701282898')
const collector = msg.createReactionCollector((r, u) => (r.emoji.id === '721244453997641758', '721546087701282898', '721546088279965829', '721546088657584150', '721546089190260766', '721546089622405121', '721546089693446145' && u.id === message.author.id))
collector.on("collect", async r => {
r.remove(message.author)
switch (r.emoji.id) {
case '721546087701282898':
msg.reactions.forEach(r=>{ r.users.filter(u =>u === message.author).forEach(bot=>{ r.remove(bot) }) })
msg.edit(new RichEmbed()
.setColor("#91e0ff")
.setTitle(`**Lista de Registro:**`)
.addField(`Registros:`, msg.guild.roles.get('718861978864582707').members.map(m => `<#${m.id}>`).join(`\n`))
.setFooter(`Atenciosamente - ${bot.user.username}`, bot.user.displayAvatarURL)
.setTimestamp()
.setThumbnail(bot.user.displayAvatarURL)
)}
})
})
}
exports.help = {
name: "lista"
}

You can use this simple trimString function to ensure that the string is less than 1024 characters:
trimString = (str, max) => ((str.length > max) ? `${str.slice(0, max - 3)}...` : str);
trimString("hi, how are you today?", 10);//"hi, how..."

Related

i cant solve the error on my state machine code

I had to do 2 messageCollector on my bot, and both have boolean filters to check if the message is able to be collected. But i want that only one collector can be used per time. So, if the person choose the collector 2, i will put his id on an array, and if this id is in the array, the first collector wont be called. When the second collector finish, i put an event "end" to remove the respective id from the array, so he can use the collector 1 again. but isnt working the code is
----- ignore module -----
let ignore = [];
const addIgnore = (message)=>{
ignore.push(message.from)
}
const removeIgnore = (message)=>{
ignore = ignore.filter(ignored=>ignored !== message.from)
}
module.exports={ignore,addIgnore,removeIgnore}
-----first collector code ----
const Response = require('./Response')
const {ignore}= require('./utils/handleIgnore')
const HandleMessageCollector=async (client,message)=>{
const filter = m => m.from === message.from &&;
const collector = client.createMessageCollector(message.from, filter, {max: 10,time: 1000 * 60 })
if (ignore.includes(message.from)) {
return
}
else {
const b64ify = (obj) => Buffer.from(JSON.stringify(obj)).toString('base64');
const options =["Agendar","Local","Promoçoes","Serviços", "Falar com o atendente", "Curso"]
await client.sendListMessage(message.from,[{
title:"Opções",
rows:options.map(option =>({
title:option,
rowId:b64ify({option})
}))
}],"Olá, Tudo bem? Sou o assistente virtual do salão MAURO CHRISOSTISMO. ","Selecione uma das opções","Opções")
await collector.on('collect',
async (m) => {
if (m) {
const mensagem = m.content
switch (mensagem) {
case "Agendar":
await Response.AGENDAR(client,message)
return ;
case "Local":
await Response.LOCAL(client,message); //envia a localização
collector.stop((msg) => { return msg })
return ;
case "Promoçoes":
Response.PROMO(client,message)// Envia as promocoes
collector.stop((msg) => { return msg })
return
case "Serviços":
await client.sendText(message.from, "Em construção")
collector.stop((msg) => { return msg })
return;
case "Falar com o atendente":
Response.ATEND(client,message) // Responseposta do atendimento
return;
case "Curso":
default:
await client.sendText(message.from,`opção inválida`);
collector.stop((msg)=>{return msg})
}
}
})
await collector.on("end",()=>{
})
}
}
module.exports=HandleMessageCollector
--- the second collector ---
const {addIgnore,removeIgnore}=require("../utils/handleIgnore")
const AgendarCollector=async (client,message)=>{
addIgnore(message)
const question = ['Qual o seu nome?','Qual o dia? Formato = dd/mm','Qual o profissional?','Qual o serviço?'];
let counter = 0
const filter = m => m.from === message.from;
const collector = client.createMessageCollector(message.from, filter, {max:4,time: 1000 * 60 })
await client.sendText(message.from,question[counter++])
await collector.on('collect',
async (m) => {
if (m) {
if(counter<question.length){
await client.sendText(message.from,question[counter++])
}
}
})
await collector.on('end', async(all)=>{
let finshed = [];
removeIgnore(message)
if(all.size<question){
console.log('não terminado')
}
await all.forEach(one=>finshed.push(` ${one.content}`))
await client.sendText(message.from,`${finshed}.\nConfirma?`)
})
}
module.exports=AgendarCollector
what im doing wrong?

DiscordJS 13 user embed display last message sent in specific channel

I am building a profile slash command for discord.js 13. The command checks users roles and displays specific information about them. We are hoping to add the persons introduction from an introduction channel. Is there anyway to pull the last message sent from a user from a specific channel?
Current Code
try{
await guild.members.fetch();
const member = guild.members.cache.get(UserOption.id);
const roles = member.roles;
const userFlags = UserOption.flags.toArray();
const activity = UserOption.presence?.activities[0];
//create the EMBED
const embeduserinfo = new MessageEmbed()
embeduserinfo.setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 512 }))
embeduserinfo.setAuthor("Information about " + member.user.username + "#" + member.user.discriminator, member.user.displayAvatarURL({ dynamic: true }), "https://discord.gg/FQGXbypRf8")
embeduserinfo.addField('**❱ Username**',`<#${member.user.id}>\n\`${member.user.tag}\``,true)
embeduserinfo.addField('**❱ Avatar**',`[\`Link to avatar\`](${member.user.displayAvatarURL({ format: "png" })})`,true)
embeduserinfo.addField('**❱ Joined Discord**', "\`"+moment(member.user.createdTimestamp).format("DD/MM/YYYY") + "\`\n" + "`"+ moment(member.user.createdTimestamp).format("hh:mm:ss") + "\`",true)
embeduserinfo.addField('**❱ Joined MetroVan**', "\`"+moment(member.joinedTimestamp).format("DD/MM/YYYY") + "\`\n" + "`"+ moment(member.joinedTimestamp).format("hh:mm:ss")+ "\`",true)
//DIRECT MESSAGE DISPLAY CODE
if (roles.cache.find(r => r.id === "893305823315492914")) //dms are open
{
embeduserinfo.addField("**❱ DM STATUS**\n`🔔 OPEN` ", "** **", true)
}
If you just need the last message in the channel, use the below code. Possible duplicate of Get last message sent to channel
let channel = bot.channels.get('id-of-the-channel');
channel.messages.fetch({ limit: 1 }).then(messages => {
let lastMessage = messages.first();
if (!lastMessage.author.bot) {
// Do something with it
}
})
.catch(console.error);
If you want the last message sent in a channel by a specific user, filter it with the id property as below-
let channel = bot.channels.get('id-of-the-channel');
channel.messages.fetch().then(messages => {
let lastMessage = messages.filter(m => m.author.id === 'id-of-user').last;
//Do something with it
})
.catch(console.error);
async function searchForLastMessageFromUser(channel, userId) {
let messages = await channel.messages.fetch({before: null}, {cache: true});
while (messages.size > 0) {
let result = messages.find(message => {
return message.author.id === userId;
});
if (result !== null) return result;
messages = await channel.messages.fetch({limit: 50, before: messages[messages.length - 1]}, {cache: true});
}
return null;
}
embeduserinfo.setDescription("**❱ INTRODUCTION**\n" + introMessageText, "** Add your intro at <#885123781130067988>**");

Put a cooldown to a command after 10 uses and on a certain person

I would like to know how to put a cooldown of 1 hour on a command after someone used it 10 times, and put the cooldown only to this person, idk if I explained it well.
Here's the coomand that I want to put a cooldown to, if the user used it 10 times in a hour, it will tell him that he has to wait.
I hope that it's possible
const fs = require("fs");
const db = require('quick.db');
const Discord = require("discord.js");
const { find } = require('image-search-engine')
const { send } = require("process")
module.exports = {
name : 'random',
description : "commande Random",
async execute(message, args) {
const rapworld = require('./rapworld.json')
var random = rapworld[Math.floor(Math.random() * rapworld.length)];
const lo_artist = random.fields.location_city;
const name_artist = random.fields.name;
const date_artist = random.fields.bio_yearsactivestart;
const bio_url = random.fields.bio_url;
const image_artist = await find(`${name_artist} rapper`, {size : "Large"})
let embed = new Discord.MessageEmbed()
.setTitle(name_artist)
.setDescription(`Actif depuis ${date_artist} \nIl vient de ${lo_artist}`)
.setURL(bio_url)
.setImage(image_artist)
message.channel.send(embed)
.then(async (msg) => {
msg.react('🔥');
let filter = (reaction, user) => reaction.emoji.name === '🔥';
let collector = msg.createReactionCollector(filter);
collector.on ('collect', (reaction, user) => {
if (reaction.count == 2){
db.push(user.id, name_artist);
message.channel.send(`**${user.tag}**, **${name_artist}** a été ajouté à votre cave !`)
}
});
});
}}
And I want to put another cooldown, of 12 hours on the claim, always specific to one person.
So this part of the code
collector.on ('collect', (reaction, user) => {
if (reaction.count == 2){
db.push(user.id, name_artist);
message.channel.send(`**${user.tag}**, **${name_artist}** a été ajouté à votre cave !`)
}
You could try looking at the official discord.js commando as they have a throttling feature which can be found here. You can do something like:
const { Command } = require('discord.js-commando');
module.exports = class MeowCommand extends Command {
constructor(client) {
super(client, {
name: 'meow',
group: 'first',
memberName: 'meow',
description: 'Replies with a meow, kitty cat.',
throttling: {
usages: 2,
duration: 10,
},
});
}
run(message) {
return message.say('Meow!');
}
};
This will make it so if a user tries to use the meow command more than two times in ten seconds, it will not allow them to use it until the ten seconds have fully passed.

How to edit/replace embeds in discordjs-commando

I am making a Type racing minigame with my discord bot, the code works... but I want to change the messages it sends to embeds, im new to Commando and it wont let me use the discord.js functions im used to using
I need to change all the bots responses to embeds, and make it so when it sends a new embed it just edits the old one so it isnt spamming messages. Here is my code:
const Commando = require('discord.js-commando')
const { words } = require('../../util/fast-type-words')
const example = {
channelId: {
message: 'message object',
stage: 'string',
counter: 'number',
currentWord: 'string',
remainingWords: ['words here'],
points: {
userId: 'points',
},
},
}
const games = {}
const stages = {
STARTING: (counter) => {
return `A new "fast type" game is starting in ${counter}s!`
},
IN_GAME: (word) => {
let spacedWord = ''
for (const character of [...word]) {
spacedWord += character
spacedWord += ' '
}
return `The new word is **${spacedWord}**!`
},
ENDING: (points) => {
const sorted = Object.keys(points).sort((a, b) => {
return points[b] - points[a]
})
let results = ''
for (const key of sorted) {
const amount = points[key]
results += `<#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
}
return `The game is now over Here's how everyone did:\n\n${results}------------------`
},
}
const selectWord = (game) => {
game.currentWord =
game.remainingWords[Math.floor(Math.random() * game.remainingWords.length)]
const index = game.remainingWords.indexOf(game.currentWord)
game.remainingWords.splice(index, 1)
}
const gameLoop = () => {
for (const key in games) {
const game = games[key]
const { message, stage } = game
if (stage === 'STARTING') {
let string = stages[stage](game.counter)
message.edit(string)
if (game.counter <= 0) {
game.stage = 'IN_GAME'
game.counter = 15
selectWord(game)
string = stages[game.stage](game.currentWord)
message.edit(string)
}
} else if (stage === 'IN_GAME') {
if (game.counter <= 0) {
game.stage = 'ENDING'
const string = stages[game.stage](game.points)
message.edit(string)
// Delete the game
delete games[key]
continue
}
}
--game.counter
}
setTimeout(gameLoop, 1000)
}
module.exports = class FastTypeGame extends Commando.Command {
constructor(client) {
super(client, {
name: 'fasttype',
group: 'games',
memberName: 'fasttype',
description: 'Starts a fast type game',
userPermissions: ['ADMINISTRATOR'],
})
client.on('message', (message) => {
const { channel, content, member } = message
const { id } = channel
const game = games[id]
if (game && game.currentWord && !member.user.bot) {
message.delete()
if (
game.stage === 'IN_GAME' &&
content.toLowerCase() === game.currentWord.toLowerCase()
) {
game.currentWord = null
const seconds = 2
const { points } = game
points[member.id] = points[member.id] || 0
message
.reply(`You won! +1 point (${++points[member.id]} total)`)
.then((newMessage) => {
newMessage.delete({
timeout: 1000 * seconds,
})
})
setTimeout(() => {
if (game.stage === 'IN_GAME') {
selectWord(game)
const string = stages[game.stage](game.currentWord)
game.message.edit(string)
}
}, 1000 * seconds)
}
}
})
gameLoop()
}
async run(message) {
const { channel } = message
message.delete()
channel.send('Preparing game...').then((message) => {
games[channel.id] = {
message,
stage: 'STARTING',
counter: 5,
remainingWords: [...words],
points: {
'719805930547445772': 4,
'723819104045105172': 1,
},
}
})
}
}
First change embeded content is not related to discord.js-commando to change the content of sended embeded message you need to get Message Object then using edit() method to pass the new embed content to it:
-Bonus: You can also edit text message into embed message.
Docs for edit method: https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=edit
Example code:
let youCurrentMessage = await channel.send(embedContent);
yourCurrentMessage.edit(newEmbedContent);
yourCurrentMessage.edit(newEmbedContent2);
// If you edit message in other command , session.You need message id
let yourCurrentMessage = await msg.channel.messages.fetch(editMessageId);
yourCurrentMessage.edit(newEmbedContent);

How do you make it so you don't have to mention the user for the description discord bot

const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
module.exports = {
name: "report",
category: "moderation",
description: "Reports a member",
usage: "<mention, id>",
run: async (client, message, args) => {
if (message.deletable) message.delete();
let rMember = message.mentions.members.first() || message.guild.members.get(args[0]);
if (!rMember)
return message.reply("Couldn't find that person?").then(m => m.delete(5000));
if (rMember.hasPermission("BAN_MEMBERS") || rMember.user.bot)
return message.channel.send("Can't report that member").then(m => m.delete(5000));
if (!args[1])
return message.channel.send("Please provide a reason for the Arrest").then(m => m.delete(5000));
const channel = message.guild.channels.find(c => c.name === "arrest-log")
if (!channel)
return message.channel.send("Couldn't find a `#arrest-log` channel").then(m => m.delete(5000));
const embed = new RichEmbed()
.setColor("#ff0000")
.setTimestamp()
.setFooter(message.guild.name, message.guild.iconURL)
.setAuthor("Arrest Log", rMember.user.displayAvatarURL )
.setDescription(stripIndents`**> User:** ${rMember}
**> Arrested by:** ${message.member}
**> Reason:** ${args.slice(1).join("")}`);
return channel.send(embed);
}
}
Simply add a few more options. Add an option to find by name, then filter the member list by the name. Also could add an option to find by ID then filter the member list by ID.

Resources