I've got a message collector, and I'm trying to use the data collected in an embed as the title, description and embed colour. So far I've got it working so that each value returns an individual embed.
I believe this is due to the forEach in line 38, however everything else I've tried (deleting that line, returns nothing, changing to collected.messages(value) throws value is not defined, collected.messages throws its not a function) doesn't work
I'm not sure what to change it to, to get the result I'm after (which is the first answer setting the embed title, the second the embed description and the third the embed colour).
code is
module.exports = {
name: "embed",
description: "Sets up a reaction role message!",
async execute(client, message, args, Discord) {
const questions = [
'What is the message title?',
'What is the message description?',
'What is the embed colour?',
]
let counter = 0
const filter = (m) => !m.author.bot
const collector = new Discord.MessageCollector(message.channel, filter, {
max: questions.length,
time: 60000 * 5, // 5m
})
message.channel.send(questions[counter++])
collector.on('collect', (m) => {
if (counter < questions.length) {
m.channel.send(questions[counter++])
}
})
collector.on('end', (collected) => {
console.log(`Collected ${collected.size} messages`)
if (collected.size < questions.length) {
message.reply('The command has timed out')
return
}
let counter = 0
collected.forEach((value) => {
console.log(value.content)
let embed = new Discord.MessageEmbed()
.setTitle(value.content)
.setDescription(value.content)
.setColor(value.content)
let messageEmbed = message.channel.send(embed);
})
})
}
}```
Any help would be greatly appreciated
all I needed to do was set a variable to see where I was in the count, then use the variable to set the fields
let i = 0;
collected.forEach((value) => {
i++;
if (i === 1) embed.setTitle(value.content);
else if (i === 2) embed.setDescription(value.content);
else if (i === 3) embed.setColor(value.content);
})
let messageEmbed = message.channel.send(embed);```
Related
It just gives me an error that the function message.guild.channels.create does not work because it's not a correct name.
My intention is to create a command where you will be asked how the channel you want to create be named. So it's ask you this. After this you send the wanted name for the channel. Now from this the bot should name the channel.
(sorry for bad english and low coding skills, im a beginner)
module.exports = {
name: "setreport",
description: "a command to setup to send reports or bugs into a specific channel.",
execute(message, args) {
const Discord = require('discord.js')
const cantCreate = new Discord.MessageEmbed()
.setColor('#f07a76')
.setDescription(`Can't create channel.`)
const hasPerm = message.member.hasPermission("ADMINISTRATOR");
const permFail = new Discord.MessageEmbed()
.setColor('#f07a76')
.setDescription(`${message.author}, you don't have the permission to execute this command. Ask an Admin.`)
if (!hasPerm) {
message.channel.send(permFail);
}
else if (hasPerm) {
const askName = new Discord.MessageEmbed()
.setColor(' #4f6abf')
.setDescription(`How should the channel be called?`)
message.channel.send(askName);
const collector = new Discord.MessageCollector(message.channel, m => m.author.id === message.author.id, { max: 1, time: 10000 });
console.log(collector)
var array = message.content.split(' ');
array.shift();
let channelName = array.join(' ');
collector.on('collect', message => {
const created = new Discord.MessageEmbed()
.setColor('#16b47e')
.setDescription(`Channel has been created.`)
message.guild.channels.create(channelName, {
type: "text",
permissionOverwrites: [
{
id: message.guild.roles.everyone,
allow: ['VIEW_CHANNEL','READ_MESSAGE_HISTORY'],
deny: ['SEND_MESSAGES']
}
],
})
.catch(message.channel.send(cantCreate))
})
}
else {
message.channel.send(created)
}
}
}
The message object currently refers to the original message posted by the user. You're not declaring it otherwise, especially seeing as you're not waiting for a message to be collected before defining a new definition / variable for your new channel's name.
NOTE: In the following code I will be using awaitMessages() (Message Collector but promise dependent), as I see it more fitting for this case (Seeing as you're more than likely not hoping for it to be asynchronous) and could clean up the code a little bit.
const filter = m => m.author.id === message.author.id
let name // This variable will later be used to define our channel's name using the user's input.
// Starting our collector below:
try {
const collected = await message.channel.awaitMessages(filter, {
max: 1,
time: 30000,
errors: ['time']
})
name = collected.first().content /* Getting the collected message and declaring it as the variable 'name' */
} catch (err) { console.error(err) }
await message.guild.channels.create(name, { ... })
This is the current code that I have, I would like to make it where if you have a certain role then you can bypass the cooldown, also if anyone knows how to make a command that restricts a certain command to a certain channel, instead of having this really long message.channel.id.
const Discord = require('discord.js');
const fetch = require('node-fetch');
const talkedRecently = new Set();
module.exports.run = async(client, message, args, queue, searcher, ) => {
if (talkedRecently.has(message.author.id)) {
message.channel.send("Wait 1 minute before getting typing this again. " +'<#'+ message.author.id + '>');
} else {
switch(args[0].toLowerCase()){
case 'neko':
if(message.channel.id === '739002385531404288'||
message.channel.id === '646849145289834506'||
message.channel.id === '785079847763574794'||
message.channel.id === '782891383361896469'||
message.channel.id === '784417039425994772'){
fetch('https://nekos.life/api/v2/img/lewd')
.then(res => res.json())
.then(json => {
let nekoEmbed = new Discord.MessageEmbed()
.setTitle('Lewd Nekos! (=^ļ½„Ļļ½„^=)')
.setImage(json.url)
message.channel.send(nekoEmbed)
})
}else{
return}}
talkedRecently.add(message.author.id);
setTimeout(() => {
talkedRecently.delete(message.author.id);
}, 60000);
}
}
module.exports.config = {
name: "hentai",
aliases: ['ht']
}
```
Answering Your First Question:
Simply check if the member has a certain role. If they do, construct your if statement so that it will not fire if they have that role
Make sure to use message.member when checking roles
if (talkedRecently.has(message.author.id) && !message.member.roles.cache.has('bypass role id here')) {
// Your cooldown message
}
Learn more about Roles#has
Answering your 2nd question:
You can have an array of channel id's then use includes to check if any of the id's in the array match the current channel id
const ids = ['id1', 'id2', 'id3', 'id4'] // And so on
if (ids.includes(message.channel.id)) {
// Your Code
}
Learn more about Array.prototype.includes
So I would like to know if it is possible to edit a message Embed with the user's reply. I will post the code below and the example.
module.exports.run = async (Client, message, args) => {
let battleChannel = message.channel;
const filter = (m) => !m.content.length === 3;
message.reply("Please enter your alliance name... Will expire in 10 seconds...");
message.channel
.awaitMessages(filter, { max: 1, time: 10000 })
.then((collected) => {
let game = new Listing();
let editLast3 = null;
let startMessage = new Discord.MessageEmbed().setTitle("1657 Battles").setDescription("Please write your alliance.").setColor("#0099ff").setTimestamp().setFooter(`Maintained by UKzs`);
message.delete();
message.channel.send(new Discord.MessageEmbed().setTitle("1657 Battles").setDescription("").setColor("#0099ff").setTimestamp().setFooter(`Maintained by UKzs`));
})
.catch((err) => {
console.log(err);
});
};
So as you can see I have the first part then I am waiting for a response from the user so I would type the following command !start = The bot will them bot the above info and wait for me to reply = I then reply with 57kl = Is there a way to then update the embed with 57kl instead of "Please write your alliance."
Thank you Ukzs
You can store the embed/message you send initially:
const original = await message.channel.send(embed);
then edit it after you collected the message:
original.edit(newEmbed);
So I've basically set up my suggestion bot, it's a very basis one but I'm looking to add a cool feature that will collect the positive and negative reactions and display a percentage. If the positive votes are more it would display 100%, if it's 1 positive and 1 negative it would display 50% and if it's negative it's 1 negative and nothing else it would display -100%. It's very simple but I'm struggling to understand how to do it. Any ideas?
For handle reaction you can use method createReactionCollector, but the 1 one problem is: method not triggered on reaction remove. So you need use some interval to check message reaction.
time: 120000 - its time to await reaction of millisecond, change it to whats you need.
If bot go restart hadling reactions will stop...
client.on('message', message => {
if (message.content.startsWith('test')) {
let suggestion = message.content.substring(0, 4) //test length
let embed = new Discord.MessageEmbed();
embed.setAuthor(message.author.tag, message.author.displayAvatarURL({
dynamic:true,
format: "png"
}))
embed.setTitle('Suggestion')
embed.setColor('GOLD')
embed.setDescription(suggestion)
embed.setTimestamp()
message.channel.send(embed).then(msg => {
msg.react('š').then(() => msg.react('š'))
const filter = (reaction, user) => {
return [`š`, 'š'].includes(reaction.emoji.name)
};
let check = setInterval(handleReaction, 5000, message, msg, suggestion)
const collector = msg.createReactionCollector(filter, {
time: 120000,
});
collector.on('collect', (reaction, reactionCollector) => {
handleReaction(message, msg, suggestion)
});
collector.on('end', (reaction, reactionCollector) => {;
clearInterval(check)
});
})
}
})
function handleReaction (message, msg, suggestion) {
let embed = new Discord.MessageEmbed();
let positiveReaction = msg.reactions.cache.get('š')
let negativeReaction = msg.reactions.cache.get('š')
let negativeCount = negativeReaction ? negativeReaction.count : 0
let positiveCount = positiveReaction ? positiveReaction.count : 0
embed.setAuthor(message.author.tag, message.author.displayAvatarURL({
dynamic:true,
format: "png"
}))
embed.setTitle('Suggestion')
embed.setColor('GOLD')
embed.setDescription(suggestion)
embed.addField('Votes', `š - ${(positiveCount / (positiveCount + negativeCount) * 100).toFixed(2)}%\nš - ${(negativeCount / (positiveCount + negativeCount) * 100).toFixed(2)}%`)
embed.setTimestamp()
msg.edit(embed)
}
I Don't Really Now If This Is What You Were Looking For Directly But Here Is My Old Code From An Old Bot I Had
const sayMessage = args.join(" ");
if (!args.length) {
return message.channel.send(`You didn't provide any text! <:angry:713422454688710717>`);
}
const sentMessage = await client.channels.get(< CHANNEL ID HERE >).send({embed: {
color: 700000,
author: {
name: client.user.username,
},
title: "Suggestion",
description: sayMessage,
footer: {
timestamp: new Date(),
icon_url: client.user.avatarURL,
text: "Suggestion"
}
}});
message.react('š');
sentMessage.react('š').then(sentMessage.react('š'))
message.channel.send("To vote for a suggestion, join my server. It should just be ..server!")
What It Does Is It Takes The Users Message And Puts It In An Embed And Reacts With Thumbs Up And Thumbs Down In The Channel Of Your Choice
But It May Need To Be Updated A Bit If Your Using V.12
I have created a discord bot recently using node js which when I do !purge, responds with Unknown command, do !help to view a list of command but after saying it, it is purging the messages. That is, it works well but posting that error message. I don't know what's the problem please help me
const commando = require('discord.js-commando');
const bot = new commando.Client();
const prefix = '!';
bot.on('message', message => {
let msg = message.content.toUpperCase();
let sender = message.author;
let cont = message.content.slice(prefix.length).split(" ");
let args = cont.slice(1);
if (msg.startsWith(prefix + 'PURGE')) {
async function purge() {
message.delete();
if (isNaN(args[0])) {
message.channel.send('Please input a number of messages to be deleted \n Syntax: ' + prefix + 'purge <amount>');
return;
}
const fetched = await message.channel.fetchMessages({limit: args[0]});
console.log(fetched.size + ' messages found, deleting...');
// Deleting the messages
message.channel.bulkDelete(fetched)
.catch(error => message.channel.send(`Error: ${error}`));
}
purge();
}
});
bot.login('MY BOT TOKEN HERE');
Right now you're using the discord.js-commando library. Any reason you decided to use that library? It looks like you're just using standard discord.js functions like bot.on, message.channel.send, message.channel.fetchMessages, message.channel.bulkDelete...
You should be good just useing the standard discord.js library, starting your code with this:
const Discord = require('discord.js');
const bot = new Discord.Client();
You can find this code on the main "Welcome" page of Discord.js
Edit:
I'm still not sure why you're using discord.js-commando, but that doesn't matter. Here's an example command I came up with using the discord.js-commando library:
const commando = require('discord.js-commando');
class PurgeCommand extends commando.Command {
constructor(client) {
super(client, {
name: 'purge',
group: 'random', // like your !roll command
memberName: 'purge',
description: 'Purge some messages from a Text Channel.',
examples: ['purge 5'],
args: [
{
key: 'numToPurge',
label: 'number',
prompt: 'Please input a number ( > 0) of messages to be deleted.',
type: 'integer'
}
]
});
}
run(msg, { numToPurge }) {
let channel = msg.channel;
// fail if number of messages to purge is invalid
if (numToPurge <= 0) {
return msg.reply('Purge number must be greater than 0');
}
// channel type must be text for .bulkDelete to be available
else if (channel.type === 'text') {
return channel.fetchMessages({limit: numToPurge})
.then(msgs => channel.bulkDelete(msgs))
.then(msgs => msg.reply(`Purge deleted ${msgs.size} message(s)`))
.catch(console.error);
}
else {
return msg.reply('Purge command only available in Text Channels');
}
}
};
module.exports = PurgeCommand
I'd also recommend using a new type instead of integer so you can validate the user's response and make sure they enter a number greater than 0.
If you need help setting up an initial discord.js-commando script, I'd take a look at this repo provided by the Discord team: https://github.com/discordjs/Commando/tree/master/test
You might wanna use this. This purge command is intended for discord.js v11.5.1 and I haven't tested to see if it works on v12, but I think this might work for you. I should say that THIS DELETES ALL THE CONTENT INSIDE THE CHANNEL (Nested command)
exports.run = (bot, message, args) => {
let filter = m => message.author.id === message.author.id;
message.channel.send("Are you sure you wanna delete all messages? (y/n)").then(() => {
message.channel.awaitMessages(filter, {
max: 1,
time: 30000,
errors: ['time']
})
.then(message => {
message = message.first();
if (message.content.toUpperCase() == "YES" || message.content.toUpperCase() == "Y") {
message.channel.bulkDelete(100);
} else if (message.content.toUpperCase() == "NO" || message.content.toUpperCase() == "N") {
message.channel.send("Terminated").then(() => {message.delete(2000)});
} else {
message.delete();
}
})
.catch(collected => {
message.channel.send("Timeout").then(() => {message.delete(2000)});
});
}).catch(error => {
message.channel.send(error);
});
};