Detecting Guild ID - discord.js

I want to make certain commands so they can only be used in a specific guild.
I've tried an if statement that checks if message.guild.id = the guild id, but the command still will execute in any guild, perhaps I'm doing something wrong.
client.on("message", msg => {
var bcid = "585676550544949248"
if (msg.guild.id = bcid) {
if (msg.content.toLowerCase().startsWith(prefix + "ping")) {
msg.channel.send("Pong! :ping_pong:");
}
}
});

One = symbol is used for assigning a value to a variable, two == or three = symbols are used for checking if a value equals another value. In if statements you use the two or thee equals symbol operator.
Thus to fix your problem, change the if to:
if (msg.guild.id === bcid) {
// Your code here
}
Check out this link to learn about the difference between == and ===.

Related

how would i get embed messages from a specific channel? [Discord.js V12]

I am trying to get a number from an embed field value from all the embeds in a specific channel and combine those numbers into one big number
Currently fetching messages from a specific channel like this
async function fetchMessagesUntil(channel, endDate, lastID) {
let messages = [];
try {
messages = (await channel.messages.fetch({ limit: 100, before: lastID })).array();
for (let i = 0; i < messages.length; i++) {
if (messages[i].createdAt.getTime() < endDate.getTime()) {
return messages.slice(0, i);
}
}
return messages.concat(await fetchMessagesUntil(channel, endDate, messages[messages.length - 1].id));
} catch {
return messages;
}
}
let end = new Date();
end.setDate(end.getDate() - 2); // Subtract two days from now
(await fetchMessagesUntil(channel, end)).forEach(x => console.log(x.content));
message.delete()
but embeds are empty when logging it to console
any ideas?
You can look here at the docs. The Message class has many properties. Message.content can be empty, but the message object may contain other properties like Message.embeds, Message.attachments, etc.
So in your code you would access the embeds like this:
let result = 0;
(await fetchMessagesUntil(channel, end)).forEach((message) => {
message.embeds.forEach((embed) => {
console.log(embed);
// result += ...
});
});
Also take a look at MessageEmbed at the docs. There you can see all the methods and properties it has, access them and get what you want from the embeds.
When getting a value from embed's field, I would check if it is the field you want to extract a value from, for example by checking its name. If you know that it is the wanted field, you can get the value from there. First use !isNaN(fieldValue), so you know that the field value is a number. Then I would use parseInt(fieldValue) to parse the string into an integer. And finally using the += operator, add the field's numeric value to the final result variable.

How can I make my bot ping a person with a command example: !eat #the user i want, the bot: #the user has been eated

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

TypeScript array find() method saying, "No overload matches this call"

Problem Statement
I am using TypeScript's find() method for an array, but when I input a value, it does not work and says, "No overload matches this call".
Code
addOption(event: MatChipInputEvent) {
const input = event.input;
const value = event.value;
// Makes sure that the same element is not inserted in the the options array
if (value !== this.options.find(value)) {
// Add our option
if ((value || '').trim()) {
this.options.push(value.trim());
}
}
// Reset the input value
if (input) {
input.value = '';
}
}
Explanation of Code
As you can see, I am using the find method in the first if condition to check and prevent the same element from coming into the array. The value you see there has a red underline and gives me the error, "No overload matches this call". I seem to be doing everything syntactically correct but the error is still there.
Actual Results
The find method gives me the error, "No overload matches this call" and does not accept the value in the parameters.
Expected Results
The find method to take in the value and find the element in the array.
Instead of find, you should use includes.
if (!this.options.includes(value)) {
In case you really want to use find, it can be done as follows:
if (this.options.find(o => o === value) == undefined) {

How to make a discord.js bot repeat a user's message without including the prefix and command name?

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', ''))
}
}
}

Deleting my messages in a server using bulkDelete (discord.js)

I am new to discord.js but learned that I can delete my messages using bulkDelete and it will delete them all, even if they are older than 2 weeks. I clear my messages in a server I moderate manually once a month and needless to say it takes forever. I was wondering if anyone would be able to help me make a command that will do this automatically whenever I call it?
Thanks,
K
I would set up a recursive function that checks if there are messages in the channel (100 max every time): if there are no messages it stops otherwise it deletes them and restarts.
function clean(channel, limit = 100) {
return channel.fetchMessages({limit}).then(async collected => {
let mine = collected.filter(m => m.author.id == 'your_id_here'); // this gets only your messages
if (mine.size > 0) {
await channel.bulkDelete(mine, true);
clean(channel);
} else channel.send("The channel is now empty!").delete(5000); // this message is deleted after 5 s
});
}
You can adapt this idea to your existing command parser or, if you don't know how to implement this, try:
client.on('message', msg => {
if (msg.author.bot || msg.author != YOU) return;
// with YOU i mean your User object, to check permissions
let command = 'clean', // the name of your command
args = msg.content.split(' ');
if (args[0].toLowerCase() == command)
clean(msg.channel, !isNaN(args[1]) ? args[1] : undefined); //<-- THIS is how to use the function
// used a ternary operator to check if the other arg is a number
});
This is just a very basic implementation, there are a lot of better ways to detect commands.
I've just found a way to filter messages.
You can fetch messages and then check for each message if its yours
await message.channel.fetchMessages({
limit: 100
}).then((msgCollection) => {
msgCollection.forEach((msg) => {
if(msg.author.id == message.author.id) {
msg.delete();
}
})
});

Resources