I'm trying to make an announcement command for my discord bot running discord.js. For example, if I say +ann (#CHANNEL) (ANNOUNCEMENT) it will post it there. I don't have any code for this and have been looking for ages. May you please help?
Basic Command Setup
When making a basic command, the first thing you're gonna want to set up is something like this:
<Discord.Client instance here>.on("message", message => {
if(message.author.bot) return;
let messageArray = message.content.split(" ");
let command = messageArray[0];
let args = messageArray.slice(1);
}
What does this do?
First of all, the code inside those curly braces is called whenever the bot "receives" a message. This means that the code is run whenever a message is sent in any channel in any server it is a part of, including DMs. The first line in this function ensures that the user who sent the message was not a bot, as you don't want other bots triggering commands on your bot.
Then, this code does some simple splitting on the message, so that the messageArray is an array of each word in the message, as determined by a space. For example, this would mean that if I sent Hello there, Cloudy Sounds!, messageArray would contain the following:
['Hello', 'there,', 'Cloudy', 'Sounds!']
command is the first word of this message (in this case 'Hello'). This is important because when sends a command to the bot, such as the +ann command you wanted above, the standard format of a message is
<prefix><command> <arguments>
So, later on in your code, you can use command to get both the prefix and the command in one string, allowing you to see if someone wants the bot to do something, or if they're just chatting with a friend and want nothing to do with the bot.
Finally, args is an array of the rest of the words, in this case ['there,', 'Cloudy', 'Sounds!'].
By using the 3 of these variables in combination, you can easily extract all the important information out of a message.
Getting The Channel
Since the user's command will contain a mentioned channel, the first thing we're gonna want to do is get that channel as a Discord.js Channel Class, so we can later send messages to it.
To get this, we can store the result of message.mentions.channels() into channel. Since we're going to be mentioning a chanel in a guild, we're gonna want to make sure it's not a DM first, and that the command actually starts with our prefix, in this case '+'. So now, our code looks like this:
<Discord.Client instance here>.on("message", message => {
if(message.author.bot) return;
let messageArray = message.content.split(" ");
let command = messageArray[0];
let args = messageArray.slice(1);
if(message.channel.type === "dm") return;
if(!message.content.startsWith('+')) return;
if(command === '+ann') {
let channel = message.mentions.channels();
}
}
Extracting the Announcement
Now that we have out channel, we're gonna want to get our announcement out from the message. We'll do this using args.
So, how do we do this?
First of all, we know that args[1] is going to be the mention of the channel ('#channel'), so that's not a part of the command. Everything else, however, is a part of our announcement, so we combine that all into a string using the following:
let announcement = args.slice(1).join(" ");
Putting it all together
Now that we have our announcement and channel, we can finally send it.
The final code would be:
<Discord.Client instance here>.on("message", message => {
if(message.author.bot) return;
let messageArray = message.content.split(" ");
let command = messageArray[0];
let args = messageArray.slice(1);
if(message.channel.type === "dm") return;
if(!message.content.startsWith('+')) return;
if(command === '+ann') {
let channel = message.mentions.channels();
let announcement = args.slice(1).join(" ");
channel.send(announcement);
}
}
Welcome to Stack Overflow, and let me know if you have any problems with this answer, or need further clarification!
Try this:
.on("message", message => {
if(message.author.bot) return;
let messageArray = message.content.split(" ");
let command = messageArray[0];
let args = messageArray.slice(1);
if(message.channel.type === "dm") return;
if(!message.content.startsWith('+')) return;
if(command === '+ann') {
let channel = message.mentions.channels();
let announcement = args.slice(1).join(" ");
channel.send(announcement);
}
Related
I tried to make a command with arguments and mentions. What I do is, I want to make mention the text channel as an argument. I might explain not quite good
Here's the example
For example, I added command with syntax: <prefix> <message> <#channel> but I can't mention channel in argument [2].
What I tried:
let msg = args[1];
let channel = message.mentions.channels.first(args[2]); // It quite not make any sense, right?
message.channel.send(`Message: ${msg} \nIn channel: ${channel}!`);
and it just crashes. A little help here!
The reason why it is crashing is because you are using "args[]" wrong, for let msg = args[1]; it should be set to args[0]. Now for the channel you can use args[1] or
You could try using message.mentions So you would do the following:
let channel = message.mentions.channels.first();
Complete Code:
let msg = args[0]; //Get the first word from the message
let announceChannel = message.mentions.channels.first(); //Get the announcement channel
message.channel.send(`Message: ${msg} \nIn channel: ${announceChannel}!`); //Let the sender know the announcement has been sent
announcementChannel.send(msg); //Send the announcement
For example if the command with user input is r!test
then the bot will respond to aatest etc. as well
Is there a way to fix this issue?
I also tried command.startsWith('r!') didnt work bot didnt respond at all.
If you need it here is code
if(command === 'slap') {
const taggedUser = msg.mentions.users.first();
if (!msg.mentions.users.size) {
const mentionisembed = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('Slap')
.setDescription('You cant slap nobody.')
return msg.channel.send(mentionisembed);
}
gifSearch.random('slap').then(
gifUrl =>{
const exampleEmbed = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('Slap')
.setAuthor(taggedUser.username)
.setDescription(`You slapped ${taggedUser.username}.`)
.setImage(gifUrl)
.setFooter('slapping idiots since 1972');
msg.channel.send(exampleEmbed);
}
);
}
Use
if(!message.content.startsWith(prefix)) return;
and not
if(!message.startsWith(prefix)) return;
Since the message has many properties and it cannot be a string. I think you meant "content"
So write this at the biggining of your code. This way all messages that doesn't start with your prefix (you can replace the prefix variable with your actual prefix) will be ignored by the bot
I want to do a command for example eat and i want the bot ping, here is an example :D
bot.on('message', (message) => {
const parts = message.content.split('');
if (parts [0] == '!eat'){
if (parts [1] == 'The member that i want to be pinged by the bot') {
message.channel.send('The user that i pinged on command has been eated!')
}
};
}
I have made a few changes:
I have added a global prefix variable, so that the prefix can easily be changed.
I have added checks to make sure the function exits if the message was sent by a bot or doesn't start with the prefix.
I have added some code to split the message into a command and arguments.
I have replaced the if statement with a switch statement.
I highly recommend that you read the Discord.js guide, as it's very beginner friendly and will allow you to write even better code than in this answer. Much of the code in this answer is taken from the Discord.js guide.
const prefix = '!';
bot.on('message', (message) => {
if (message.author.bot || !message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/\s+/g);
const command = args.shift().toLowerCase();
switch (command) {
case 'eat':
const member = message.mentions.members.first();
if (!member) return message.reply('Could not find the mentioned user.');
message.channel.send(`${member.user.username} has been eaten!`);
break;
default:
message.reply(`The command \`${command}\` was not recognized`);
}
});
Explanation
The command prefix is set:
const prefix = '!';
The function exits if the message was sent by a bot or doesn't start with the prefix:
if (message.author.bot || !message.content.startsWith(prefix)) return;
The prefix is removed from the start of the message, and the message is split at all whitespace gaps:
const args = message.content.slice(prefix.length).trim().split(/\s+/g);
The first argument is removed, converted to lowercase and stored in the command variable:
const command = args.shift().toLowerCase();
The first mentioned user is found:
const member = message.mentions.members.first();
If there is no mentioned user, a warning message is returned:
if (!member) return message.reply('Could not find the mentioned user.');
A message is sent to the server saying "[the user] has been eaten!":
message.channel.send(`${member.user.username} has been eaten!`);
References
Message.mentions
<#${message.member.id}> That will ping the author of the message just use (``) and not (' ') and that will ping the author
Okay this most likely has a really simple answer but I couldn't find the same thing online and I can't figure it out on my own thinking.
So in the args for responding to a prefix, i have this:
case 'say':
const usermsg = message.content
message.channel.send(usermsg)
break;
Since it's the entire contents, it responds with the c!say too then it triggers itself. But the triggering isn't the issue, I want the c!say not included in the message. (I know I don't need the const for this, I just wanted to experiment different combinations of stuff in a separate line)
Update:
So I found a second method of approaching this by using the arguments part, like this:
case 'say':
message.channel.send(args[1])
message.delete(1)
break;
So this does what I want but only for the second argument, meaning it doesn't work for more than 1 word. So my current thought is subtracting args[0] (the c!say phrase) from message.content.
Found a fix to the issue, instead of sending the arguments or subtracting text I used the replace command.
case 'say':
let saymsg = message.content
message.channel.send(saymsg.replace("c!say",""))
message.delete(1)
break;
I can't believe I didn't remember the world replace sooner, but that's it, it works.
case 'say':
const usermsg = message.content.split(' ');
message.channel.send(usermsg.slice(0).join(' '));
break;
This code will take in the full user string, slice out the first argument (the command and prefix), then join the rest of the message and send it in chat.
bot.on('message', message => {
var sender = message.author;
var msg = message.content.toUpperCase();
var prefix = '>';
var cont = message.content.slice(prefix.length).split(" ");
var args = cont.slice(1);
for (x = 0; x < profanities.length; x++) {
if (message.content.toUpperCase == profanities[x].toUpperCase()) {
message.channel.send('Hey! Don\'t say that');
message.delete();
return;
}
if (msg.startsWith(prefix + 'SAY')) {
message.delete();
var saymsg = message.content;
message.channel.send(saymsg.replace(prefix + 'say', ''))
}
}
}
I'm basically making a counting bot where one command shows a let in a message, one increments it and sends a message, and, once I get passed this little issue, one that will let me set the let in case someone goes overboard. It's for a D&D campaign using discord and is basically just a meme bot I'm making for fun. The issue I'm having is that I can't figure out how to use the let variable in the message itself. This is what I'm working with based on youtube and my previous experience in Python, of which there is little.
const { prefix, token } = require('./Config.json');
const client = new Discord.Client();
let insight = 4;
client.once('ready', () => {
console.log("Ready!")
})
client.on('message', message => {
console.log(message.content);
if(message.content.startsWith(`${prefix}insight`)) {
return message.channel.send("Ghyger had distrusted someone ", insight, " times!")
}
if(message.content.startsWith(`${prefix}distrust`)) {
insight++;
return message.channel.send("Not again Ghyger! That's ", insight, " times now!")
}
})
client.login(token);
When this is ran and I execute either command, it throws up this, followed by a bunch of paths
options.reply = reply;
^
TypeError: Cannot create property 'reply' on number '5'
It's because reply is a function, not a variable, you should be calling it options.reply(reply);.
Fix is let option.reply = reply