Preventing a discord bot from executing a command in a user prompt - node.js

I need some help/suggestion to prevent a discord bot from executing a command in a user prompt.
My bot currently has a feature that prompts the user a question, and it'll add whatever the user's answer is to the database. The problem that I'm trying to solve is, currently the user's able to enter a bot command as an answer, and the bot would both execute that command and take that as an answer to add to the database.
A very quick example to show how problematic this can get:
User: ?question
Bot: Cats or Dogs?
User: ?question
Bot: "?question" have been added to the database
Bot: Cats or Dogs?
I don't have a problem with the bot adding the command to the database, because that's what the user entered (it might be relevant for the user to enter a bot command there), but I don't want the bot to execute that command.
Right now I have 2 vague ideas to solve this (I don't know whether or not any of this will be valid):
I need to turn the user's answer into an "answer" type variable where the bot can't use it to search for commands, but can still use it to upload to the database and fetch from it and display in a list of answers. Although I don't know if this can be executed before the bot starts to search for the command.
I need to somehow change how this system of question & answer works.
Note: Currently my bot detects a command by slicing the first bit of the user's message .slice(config.prefix.length)
Any help or suggestion will be much appreciated.
Thanks in advance!

Here's some answers to your question:
The bot takes in a command as an answer.
If you ever change your mind, you can disallow this by simply allowing only a few selected responses ("cat" or "dog") or disallowing commands that start with a ?.
The command is executed if a command was used as an answer.
This is because you check if the message is a command down the line, somewhere in your code. Not only does the bot recognize the user's message as a valid answer, but it also recognizes that it fulfills the prefix you set and thus it runs the command.If you have a flag that indicates that the user's next response is an answer to the Q&A question, then you can check if that flag is active before executing the command. For example:
// Assume that the user's ID is in this array after they
// requested to answer a Q&A question.
var usersAwaitingResponse = [];
...
client.on("message", function(message) {
if (usersAwaitingResponse.includes(message.author.id)) {
// take in the answer and then end the function by calling "return;"
} else {
// check if the message was a command and act accordingly
}
});
Prefix Checking
Lastly, I recommend that you check if a message is a command by using .startsWith(config.prefix) on the message text. If you want the user to only input allowed characters after the prefix, then you can use a regular expression. Either method saves time and memory rather than slicing the string. An example of those can be seen below:
// using "startsWith"
function checkIfCommand(message) {
return message.content.startsWith(config.prefix);
}
// using a regular expression
function checkIfCommand(message) {
/**
* If all the matches are fulfilled, the test passes:
*
* ^ - The match should be at the beginning of the string.
* ${config.prefix} - The prefix (interpolated into the string).
* [A-Z0-9]+ - match as much characters that are A to Z or 0 to 9
* \s? - Match a whitespace character (if there is one)
* "gi" - global, case insensitive
**/
return new RegExp(`^${config.prefix}[A-Z]+\s?`, "gi").test(message.content);
}

Related

How to get bot command values of another Discord bot

I'm trying to have my bot keep track of items that are being spawned by another bot (Mee6).
The following code gives me a None output.
#client.event
async def on_message(message:discord.Message):
if message.author.bot:
print(message.content)
The command the other bot is responding to is:
/spawn-item member={member} item={item} amount={amount}
I would like to retrieve these values.
Any help would be welcome!
Your code doesn't work, because you want to get an interaction, not a message.
Unfortunately, there is no way to get the interaction of another client. At most you can have a MessageInteraction, which gives you the name of the command used.
But in your case you can make it work since MEE6 still accepts the old command format. If you use the prefix of MEE6 instead of the / command, your code should work (with a bit of reworking: you would need to look at the message right before MEE6's response, or look if a message starts with the MEE6's prefix)

Ways to include custom error messages in shorthand if-else sanity checks Discord JS

I am a beginner and probably, this is a stupid question. I am writing a command handler for a discord.js bot. Every time, a user sends a message starting with the correct command prefix, I check whether the invoke is in an Enmap of possible commands.
Currently, it looks like this:
const command = client.commands.get(invoke);
if(!command) return;
...
I would like to keep this shorthand way of writing those sanity checks, but I would like to inform the user that there is no command with this name.
Is there an elegant way of doing this or does anyone know where I can find more information about good ways to solve this?
Thanks in advance :D
I wouldn't recommend telling the user if a command is invalid, but here's how you can do it:
const command = client.commands.get(command);
if (!command) return message.channel.send("Invalid Command.");

How to mention the author of a message in another message

I am using repl.it to develop a bot. I am trying to make a command that makes the bot behave like this:
Someone: !slap #someoneelse
Bot: #Someone slapped #someoneelse
How can I get the bot to mention #someone without using ID? Multiple people will use the command and I can't just use ID since it will only work with one person. I haven't found anything that helped me, and the documentation was no help either. Hopefully, I can get help! Thank you.
Users and members have a .toString() method that is automatically called every time they are concatenated with a string: that means that if you type "Hey " + message.author you will get "Hey #author"
That's how I would do the command:
// First store the mentioned user (it will be undefiend if there's none, check that)
let mentionedUser = message.mentions.users.first();
// Reply by directly putting the User objects in the string:
message.channel.send(`${message.author} slapped ${mentionedUser}`);

Discord <#!userid> vs <#userid>

so I'm creating a bot using Node.JS / Discord.JS and I have a question.
On some servers, when you mention a user, it returns in the console as <#!userid> and on other it returns as <#userid>.
My bot has a simple points / level system, and it saves in a JSON file as <#!userid>, so on some servers when trying to look at a users points by mentioning them will work, and on others it won't.
Does anyone have any idea how to fix this? I've tried to find an answer many times, and I don't want to have it save twice, once as <#!userid> and then <#userid>. If this is the only way to fix it then I understand.
Thanks for your help!
The exclamation mark in the <#!userID> means they have a nickname set in that server. Using it without the exclamation mark is more reliable as it works anywhere. Furthermore, you should save users with their id, not the whole mention (the "<#userid>"). Parse out the extra symbols using regex.
var user = "<#!123456789>" //Just assuming that's their user id.
var userID = user.replace(/[<#!>]/g, '');
Which would give us 123456789. Their user id. Of course, you can easily obtain the user object (you most likely would to get their username) in two ways, if they're in the server where you're using the command, you can just
var member = message.guild.member(userID);
OR if they're not in the server and you still want to access their user object, then;
client.fetchUser(userID)
.then(user => {
//Do some stuff with the user object.
}, rejection => {
//Handle the error in case one happens (that is, it could not find the user.)
});
You can ALSO simply access the member object directly from the tag (if they tagged them in the message).
var member = message.mentions.members.first();
And just like that, without any regex, you can get the full member object and save their id.
var memberID = member.id;

Using user message in retryPrompt

In a given moment, my bot asks for a number.
builder.Prompts.number(session, "Cool. What's the number?", {
retryPrompt: "I couldn't understand $%##. Could you type it again?"
});
I need the message to contain the user response instead of $%##. Is there a way to do it? I tried to use session.message.text and results.response, but these are still from the outer function because of closure.
For anyone looking for this answer: currently, there is no way to change the message inside the Prompt dialog.
I looked up the code for BotFramework for nodeThe message you send as retryPrompt is as is, without replacements.

Resources