im working on my discord.js bot and it just got added onto top.gg and the prefix is Kei and people want to use kei or KEI how do I have multiple prefixes in 1 project
Let's say your prefix variable is called prefix.
var prefix = "Kei";
if(message.content.startsWith(prefix) || message.content.startsWith(prefix.toLowerCase()) || message.content.startsWith(prefix.toUpperCase())) {
//do something
}
In this example the code would run if the message starts with the prefix (Kei) or the prefix to lowercase, which means the prefix in lowercase letters (kei) or the prefix to uppercase, which means the prefix in uppercase letters (KEI).
So the prefix is the same only the letters change. You don't have to use multiple prefixes for that.
This is very simple thanks to JavaScript's native .toLowerCase() method. You can simply convert the message's content to lowercase and then check for the prefix.
e.g.
const prefix = "Kei";
client.on("message", async message => {
if (message.content.toLowerCase().startsWith(prefix)) {
// do stuff
}
});
Put this code in the message event:
const prefixes = ['!', '?', '/'];
let prefix = false;
for (const thisPrefix of prefixes) {
if (message.content.startsWith(thisPrefix)) prefix = thisPrefix;
}
if (!prefix) return;
It is just simple.
client.on('message', (message) => {
const prefixes = ['!', '?', '.'];
let hasPrefix = false;
prefixes.some(p => message.content.startsWith(p)) ? hasPrefix = true : null;
if(!hasPrefix) return;
//Start coding :)
}
Related
I want to do so that when I use !pm (user) (some message), my bot will send a private message to the user, although I have no idea how to select everything after the (user) and assign it to a variable, to send it to the user.
My current code looks like this:
module.exports = {
name: 'pm',
description: 'Sends a personal message!',
execute(message, args, client) {
const pmMessage = args[1];
client.users.cache.get('464839066781745167').send(pmMessage);
}
}
Since you know the array index of the pmMessage, with the help of that index, you can use the slice method which returns the array from specified stating to end index.
Eg:
let pmMessage = args.slice(2); //returns array.
Note: If the end index is not specified, then it considers till the last index of the array.
Now, using the join method, you can join all the indexes with whatever specified character. Eg:
let MessageContent = pmMessage.join(' '); //joined by space.
let args = ["UserID","This","represents","the","message","content","to","be","sent"];
console.log(args.slice(1));
console.log(args.slice(1).join(' '));
Try this, I think this should work:
let pm_args = args.slice(1).join(' ')
if(args[0]){
let user = getUserFromMention(args[0])
if(!user){
return message.reply('please mention a user.');
}
return client.users.cache.get(user.id).send(pm_args);
}
return message.reply('please mention a user.');
(This is what I used for mention thingie:)
function getUserFromMention(mention){
if(!mention) return;
if(mention.startsWith('<#') && mention.endsWith('>')){
mention = mention.slice(2, -1);
if(mention.startsWith('!')){
mention = mention.slice(1);
}
return bot.users.cache.get(mention);
}
};
client.on("message", message => {
if(!message.content.startsWith(config.prefix)) return;
const withoutPrefix = message.content.slice(config.prefix.length);
const split = withoutPrefix.split(/ +/);
const command = split[0];
const args = split.slice(1);
// Code...
});
if (msg.content === 'SWEARWORD') {
msg.reply('No swearing u nub >:) ');
}
How do I fix it and make it autodelete the swear words messages?
You should use an array to store your words and check if the message's content contains them:
const words = [ 'bread', 'apple', 'tea' ];
const forbiddenWord = words.some((word) => message.content.includes(word));
if (forbiddenWord ) {
message.delete();
message.channel.send('your message should not include : '+forbiddenWord);
}
I am doing a regex where I am checking for the condition with certain names.
const nameMatch = () => {
return ( !this.state.name.match("^Jen.*") || !this.state.name.endsWith("ez") );
}
In this, I get the values of nameMatch as () => { return ( !this.state.name.match("^Jen.*") || this.state.name.endsWith("ez") ); } rather than true or not
I am doing if(nameMatch) {...}
but rather I would need the ones that match.
What am I doing wrong?
A breakdown of the regex "^Jen.*":
^ asserts the position the start of a line, where lines are delimited by \n.
Jen is a case sensitive match for the characters "Jen".
.* matches any character except for line terminators (\n) between zero and unlimited times.
Therefore as I understand your question, you're asking how to find and return every name which does not start with "Jen" or end with "ez".
If this.state.name is an Array of names, then you can return all of the names that do not start with "Jen" or end with "ez" using the following example:
var names = ['menez', 'asJenas', 'benez', 'destruction', 'present', 'Jenosus', 'ezJen'];
const nameMatch = names.filter((word) => {
return !(word.startsWith("Jen") || word.endsWith("ez"));
});
console.log(nameMatch);
// expected output: Array ["asJenas", "destruction", "present", "ezJen"]
If this.state.name is a String containing multiple names with new line (\n) delimiters in it, then you can first extract an array of names from the string and then use the above code, for example:
var names = "menez\nasJenas\nbenez\ndestruction\npresent\nJenosus\nezJen"
const namesArray = names.split("\n");
const nameMatch = namesArray.filter((word) => {
return !(word.startsWith("Jen") || word.endsWith("ez"));
});
console.log(nameMatch);
// expected output: Array ["asJenas", "destruction", "present", "ezJen"]
If this.state.name is a String containing a single name, then you can use the following function, which will return true if the name does not start with "Jen" or end with "ez":
const nameMatch = (name) => {
return !(name.startsWith("Jen") || name.endsWith("ez"));
};
You can use it like so:
const nameMatch = (name) => {
return !(name.startsWith("Jen") || name.endsWith("ez"));
};
var names = "Ben";
if (nameMatch(names)) {
console.log("This name matched");
}
// expected output: "This name matched"
Please keep in mind that where I have used names, you will need to swap it to this.state.name.
You are assigning a function to the const nameMatch.
These types of functions are called fat arrow functions.
If you wanted to get the value in the nameMatch variable, you can try:
const nameMatch = (!this.state.name.match("^Jen.*") || !this.state.name.endsWith("ez"))
A simpler way of expressing the logic is:
const nameMatch = !(this.state.name.match("^Jen.*") && this.state.name.endsWith("ez"))
nameMatch is a function, so you need execute it to get the result, just call nameMatch() instead nameMatch
I know that firestore doesn't support full text search and it giving us solution to use third party services. However I found a simple solution to simple "full text search" and I think this might help others who doesn't want to use third party services as me for such a simple task.
I'm trying to search for company name which is saved in firestore collection under my companyName which can be in any format for example "My Awesome Company". When adding new company with companyName or updating a value in companyName I'm also saving searchName with it which is the same value as company name but in lower case without spaces
searchName: removeSpace(companyName).toLowerCase()
removeSpace is my simple custom function which remove all spaces from a text
export const removeSpace = (string) => {
return string.replace(/\s/g, '');
}
That turns our company name to myawesomecompany which is saved in searchName
Now I've got a firestore function to search for company which indexing through searchName and returning companyName. Minumum search value is a searched value without last character and maximum search value is a searched value with added "zzzzzzzzzzzzzzzzzzzzzzzz" transformed to lower case. That means if you search for My Aw then min value will be mya and max value will be myawzzzzzzzzzzzzzzzzzzzzzzz
exports.handler = ((data) => {
const searchValue = data.value.replace(/\s/g, '').toLowerCase()
const minName = searchValue.substr(0, searchName.length-1)
const maxName = searchValue + "zzzzzzzzzzzzzzzzzzzzzzzz"
let list = []
const newRef = db.collection("user").where("profile.searchName", ">=", minName).where("profile.searchName", "<=", maxName)
return newRef.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
list.push({ name: doc.data().profile.companyName})
})
return list
})
})
I didn't have time to fully test it but so far it works without any problems. Please let me know if you spot anything wrong with it. Now the question is
Is "z" character the highest value character in firestore or is there any other more decent way to add into the search value maximum amount without adding "zzzzzzzzzzzzz"?
I like your decision to preprocess the text so that it can be queried, but you could provide for a more flexible search by storing lowercase keywords with the users and searching those. In other words, transform:
"My Awesome Company"
to...
{ my: true, awesome: true, company: true }
...and test against that.
When adding/updating the property:
// save keywords on the user
let keywords = {}
companyName.split(' ').forEach(word => keywords[word.toLowerCase()] = true)
When querying:
let searchKeywords = userInputString.split(' ').map(word => word.toLowerCase())
let collection = db.collection("user")
searchKeywords.forEach(keyword => {
collection = collection.where(`keywords.${keyword}` , '==' , true);
});
With a little modification of previous answer I have made another simple text search. I'm saving keyword to an array instead of saving it in object like this
nameIndex: textIndexToArray(companyName)
where textIndexToArray is my custom function
export const textIndexToArray = (str) => {
const string = str.trim().replace(/ +(?= )/g,'')
let arr = []
for (let i = 0; i < string.trim().length; i++) {
arr.push(string.substr(0,i+1).toLowerCase());
}
return arr
}
which transfer a text into array. For example
"My Company"
will return
[m, my, my , my c, my co, my com, my comp, my compa, my compan, my company]
with nameIndex saved in firestore we can simply query the data thorough nameIndex and return companyName
exports.handler = ((data) => {
const searchValue = data.value.toLowerCase()
let list = []
const newRef = db.collection("user").where("nameIndex", "array-contains", searchValue)
return newRef.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
list.push({ name: doc.data().companyName, })
})
return list
})
})
I am making a request like this:
fetch("https://api.parse.com/1/users", {
method: "GET",
headers: headers,
body: body
})
How do I pass query string parameters? Do I simply add them to the URL? I couldn't find an example in the docs.
Your first thought was right: just add them to the URL.
Remember you can use template strings (backticks) to simplify putting variables into the query.
const data = {foo:1, bar:2};
fetch(`https://api.parse.com/1/users?foo=${encodeURIComponent(data.foo)}&bar=${encodeURIComponent(data.bar)}`, {
method: "GET",
headers: headers,
})
Short answer
Just substitute values into the URL like this:
const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);
Longer answer
Yes, you just need to add the query string to the URL yourself. You should take care to escape your query string parameters, though - don't just construct a URL like
`https://example.com/foo?bar=${someVariable}`
unless you're confident that someVariable definitely doesn't contain any &, =, or other special characters.
If you were using fetch outside of React Native, you'd have the option of encoding query string parameters using URLSearchParams. However, React Native does not support URLSearchParams. Instead, use encodeURIComponent.
For example:
const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);
If you want to serialise an object of keys and values into a query string, you could make a utility function to do that:
function objToQueryString(obj) {
const keyValuePairs = [];
for (const key in obj) {
keyValuePairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
}
return keyValuePairs.join('&');
}
... and use it like this:
const queryString = objToQueryString({
key1: 'somevalue',
key2: someVariable,
});
fetch(`https://example.com/foo?${queryString}`);
Here's an es6 approach
const getQueryString = (queries) => {
return Object.keys(queries).reduce((result, key) => {
return [...result, `${encodeURIComponent(key)}=${encodeURIComponent(queries[key])}`]
}, []).join('&');
};
Here we're taking in a queries object in the shape of key: param
We iterate and reduce through the keys of this object, building an array of encoded query strings.
Lastly we do a join and return this attachable query string.
I did a small riff on Mark Amery's answer that will pass Airbnb's eslint definitions since many teams seem to have that requirement these days.
function objToQueryString(obj) {
const keyValuePairs = [];
for (let i = 0; i < Object.keys(obj).length; i += 1) {
keyValuePairs.push(`${encodeURIComponent(Object.keys(obj)[i])}=${encodeURIComponent(Object.values(obj)[i])}`);
}
return keyValuePairs.join('&');
}
My simple function to handle this:
/**
* Get query string
*
* #param {*} query query object (any object that Object.entries() can handle)
* #returns {string} query string
*/
function querystring(query = {}) {
// get array of key value pairs ([[k1, v1], [k2, v2]])
const qs = Object.entries(query)
// filter pairs with undefined value
.filter(pair => pair[1] !== undefined)
// encode keys and values, remove the value if it is null, but leave the key
.map(pair => pair.filter(i => i !== null).map(encodeURIComponent).join('='))
.join('&');
return qs && '?' + qs;
}
querystring({one: '##$code', two: undefined, three: null, four: 100, 'fi###ve': 'text'});
// "?one=%23%40%24code&three&four=100&fi%23%23%40ve=text"
querystring({});
// ""
querystring('one')
// "?0=o&1=n&2=e"
querystring(['one', 2, null, undefined]);
// "?0=one&1=2&2" (edited)
Yes you should, there are a few classes in JS, that can help you a handy one is https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
e.g. if you had the params in a javascript object say
let params = {one: 'one', two: 'two'}
you could say this function
let queryString = new URLSearchParams()
for(let key in params){
if(!params.hasOwnkey())continue
queryString.append(key, params[key])
}
then you can get your nicely formatted query string by saying
queryString.toString()
The accepted answer works, but if you have more params than one it doesn't generalize. I suggest the following approach, which also handles array parameters:
let route = 'http://test.url.com/offices/search';
if (method == 'GET' && params) {
const query = Object.keys(params)
.map((k) => {
if (Array.isArray(params[k])) {
return params[k]
.map((val) => `${encodeURIComponent(k)}[]=${encodeURIComponent(val)}`)
.join('&');
}
return `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`;
})
.join('&');
route += `?${query}`;
}