So, I'm creating the bot for my Discord channel. I created a special system based on requests. For example, the user sends a request to be added to the chat he wants. Each request is paired with a unique ID. The request is formed and sent to the service channel where the moderator can see those requests. Then, once the request is solved, moderator types something like .resolveRequest <ID> and this request is copied and posted to 'resolved requests' channel.
There is some code I wrote.
Generating request:
if (command === "join-chat") {
const data = fs.readFileSync('./requestID.txt');
let requestID = parseInt(data, 10);
const emb = new Discord.RichEmbed()
.setTitle('New request')
.setDescription('Request to add to chat')
.addField('Who?', `**User ${msg.author.tag}**`)
.addField('Which chat?', `**Chat: ${args[0]}**`)
.setFooter('Request\'s ID: ' + requestID)
.setColor('#fffb3a');
let chan = client.channels.get('567959560900313108');
chan.send(emb);
requestID++;
fs.writeFileSync('./requestID.txt', requestID.toString(10));
}
Now the .resolveRequest <ID>:
if (command === '.resolveRequest') {
msg.channel.fetchMessages({limit : 100}) //getting last 100 messages
.then((messages) => messages.forEach(element => { //for each message get an embed
element.embeds.forEach(element => {
msg.channel.send(element.fields.find('value', args[0].toString(10))); //send a message containing the ID mentioned in 'args[0]' that was taken form the message
})
}));
}
.join-chat <chat_name> works flawlessly, but .resolveRequest <ID> does't work at all, even no errors.
Any way to fix it?
Using .find('value', 'key') is deprecated, use .find(thing => thing.value == 'key') instead.
Also you should use a DataBase to store things, but your Code actually is not broken, its just that you check for: command === '.resolveRequest', wich means you need to run ..resolveRequest, as in the command variable the prefix gets cut away so change that to: command === 'resolveRequest'
Related
Revoking A Ban Using Code
So, I am making a moderation discord bot using VS Code and I have already set up a ban command. I want to make a unban command (revoking a ban) too so that the user can easily unban a user and not have to go into Server Settings to do it.
I know you can do it because I have been using another bot, GAwesomeBot, that is able to do it.
Link to GAwesomeBot: https://gawesomebot.com
I am a little new to Stack Overflow and this is my first question so pardon me if I am doing anything wrong.
Consider using GuildMemberManager#unban
https://discord.js.org/#/docs/main/stable/class/GuildMemberManager?scrollTo=unban
let guildMemberManager, toUnbanSnowflake;
guildMemberManager.unban(toUnbanSnowflake); // Takes UserResolveable as argument
First you want to define the user that you are unbanning.
Because the user is already banned you will have to mention the user by their ID and then unbanning them.
let args = message.content.split(/ +/g); //Split the message by every space
let user = message.guild.members.cache.get(args[1]); //getting the user
user.unban({ reason: args[2].length > 0 ? args[2] : 'No reason provided.' }); //Unbanning the user
The full example:
//Define your variables
const Discord = require('discord.js');
const client = new Discord.Client();
var prefix = 'your-prefix-here';
//Add a message event listener
client.on('message', () => {
let args = message.content.split(/ +/g); //Split the message by every space
if (message.content.toLowerCase() === prefix + 'unban') {
let user = message.guild.members.cache.get(args[1]); //getting the user
if (!user) return message.channel.send('Please specify a user ID');
user.unban({ reason: args[2].length > 0 ? args[2] : 'No reason provided.' }).then(() => message.channel.send('Success');
}
});
I would like to have some kind of reaction roles into my bot. For that I have to test If the message ID that the User sends to the bot is valid. Can someone tell me how to do that?
You can do that with .fetch() as long as you also know what channel you're looking in.
If the message is in the same channel the user sent the ID in then you can use message.channel to get the channel or if it's in another channel then you have to get that channel using its ID using message.guild.channels.cache.get(CHANNEL_ID).
So your code could be like this if it's in the same channel:
const msg = message.channel.messages.fetch(MESSAGE_ID)
or if it's in a different channel:
const channel = message.guild.channels.cache.get(CHANNEL_ID)
const msg = channel.messages.fetch(MESSAGE_ID)
This works for me (Discord.js v12)
First you need to define the channel where you want your bot to search for a message.
(You can find it like this)
const targetedChannel = client.channels.cache.find((channel) => channel.name === "<Channel Name>");
Then you need to add this function:
async function setMessageValue (_messageID, _targetedChannel) {
let foundMessage = new String();
// Check if the message contains only numbers (Beacause ID contains only numbers)
if (!Number(_messageID)) return 'FAIL_ID=NAN';
// Check if the Message with the targeted ID is found from the Discord.js API
try {
await Promise.all([_targetedChannel.messages.fetch(_messageID)]);
} catch (error) {
// Error: Message not found
if (error.code == 10008) {
console.error('Failed to find the message! Setting value to error message...');
foundMessage = 'FAIL_ID';
}
} finally {
// If the type of variable is string (Contains an error message inside) then just return the fail message.
if (typeof foundMessage == 'string') return foundMessage;
// Else if the type of the variable is not a string (beacause is an object with the message props) return back the targeted message object.
return _targetedChannel.messages.fetch(_messageID);
}
}
After this procedure, just get the function value to another variable:
const messageReturn = await setMessageValue("MessageID", targetedChannel);
And then you can do with it whetever you want.Just for example you can edit that message with the following code:
messageReturn.edit("<Your text here>");
The following code is resulting in no errors to the console. After I type the command, the first message.reply line executes properly, but the bot doesn't seem to acknowledge someone types 'accept' or 'deny'. Been messing with this for quite a long time. I've done commands like this in private messages and it works. But for some reason since this is in a public channel, it doesn't seem to work.
module.exports.run = async(bot, message, args) => {
//!endbrawl winner [username] loser [username]
let messageArray = message.content.split(" ")
let winner = messageArray[2]
let loser = messageArray[4]
message.reply(`${message.author} wants to close this brawl with ${winner} as the victor and ${loser} as the loser. \n ${winner}, do you accept the result? If yes, type 'accept'. If not, type 'deny'.`);
let winnerUser = message.mentions.users.first();
let filter = m => m.author.id == winnerUser.id;
message.channel.awaitMessages(filter, {
maxMatches: 1,
}).then(collected => {
if (message.author.bot) return;
if (collected.first().content === "accept") {
return message.reply(`${winner} has accepted the proposed result.`)
// put in code asking loser to agree with proposed result
} else if (collected.first().content === "deny") {
return message.reply(`${winner} has denied the proposed result.`)
} else {
return message.reply(`${winner}, your reply was invalid.`)
}
})
}
I have looked for ways to solve this, but most involve private messaging or what was told doesn't work for me. No errors in any of those attempts. It just seems like it isn't even looking at the replies.
Thanks for any and all help! It is greatly appreciated!
message.channel.awaitMessages(filter, {
max: 1,
}).then(...);
That max means that the maximun number of messages that will be processed will be 1: that means that if the next message is not sent by the author the bot will stop listening for new messages. The other message could even be your bot's reply, since you're not waiting for that to be finished before setting the awaitMessages.
Try using maxMatches instead of max.
message.channel.awaitMessages(filter, {
maxMatches: 1,
}).then(...);
Reference: MessageCollectorOptions
With that said, you want the winner to be able to send that message and so you'll need to change your filter function.
You'll first need to get the User object of the winner, then make the filter so that it checks for their id.
let winnerUser = message.mentions.users.first();
let filter = m => m.author.id == winnerUser.id;
You could also match the id from the plain mention, but I find it easier to use the object instead.
I have been wondering how can I send messages when someone invites my bot to their server.
Please help me in this area I can't figure it out it's there in Python but I have not used to it.
Thank you for your help
All the above answers assume you know something about the server and in most cases you do not!
What you need to do is loop through the channels in the guild and find one that you have permission to text in.
You can get the channel cache from the guild.
Take the below example:
bot.on("guildCreate", guild => {
let defaultChannel = "";
guild.channels.cache.forEach((channel) => {
if(channel.type == "text" && defaultChannel == "") {
if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
defaultChannel = channel;
}
}
})
//defaultChannel will be the channel object that the bot first finds permissions for
defaultChannel.send('Hello, Im a Bot!')
});
You can of course do further checks to ensure you can text before texting but this will get you on the right path
Update discord.js 12+
Discord.JS now uses cache - here is the same answer for 12+
bot.on("guildCreate", guild => {
let found = 0;
guild.channels.cache.map((channel) => {
if (found === 0) {
if (channel.type === "text") {
if (channel.permissionsFor(bot.user).has("VIEW_CHANNEL") === true) {
if (channel.permissionsFor(bot.user).has("SEND_MESSAGES") === true) {
channel.send(`Hello - I'm a Bot!`);
found = 1;
}
}
}
}
});
})
You can simply send the owner for example a message using guild.author.send("Thanks for inviting my bot");
Or you can also send a message to a specific user:
client.users.get("USER ID").send("My bot has been invited to a new server!");
I'm not sure if you're using a command handler or not since you seem new to JS I'm going to assume you're not. The following is a code snippet for what you're trying to do:
client.on('guildCreate', (guild) => {
guild.channels.find(t => t.name == 'general').send('Hey their Im here now!'); // Change where it says 'general' if you wan't to look for a different channel name.
});
Is there any way to make a command send a private message to all members of the discord group using discord.js?
Exemple: /private TEST
This message is sent to everyone in the group in private chat instead of channel chat.
You can iterate through Guild.members.
When you receive a message that starts with /private, you take the rest and send it to every member of the guild by using Guild.members.forEach().
Here's a quick example:
client.on('message', msg => {
if (msg.guild && msg.content.startsWith('/private')) {
let text = msg.content.slice('/private'.length); // cuts off the /private part
msg.guild.members.forEach(member => {
if (member.id != client.user.id && !member.user.bot) member.send(text);
});
}
});
This is just a basic implementation, you can obviously use this concept with your command checks or modify that by adding additional text and so on.
Hope this solves the problem for you, let me know if you have any further questions :)
The updated code for discord.js v12 is just adding cache to the forEach.
client.on('message', msg => {
if (msg.guild && msg.content.startsWith('/private')) {
let text = msg.content.slice('/private'.length); // cuts off the /private part
msg.guild.members.cache.forEach(member => {
if (member.id != client.user.id && !member.user.bot) member.send(text);
});
}
});