Replacing and trimming messages - javascript

I'm trying to toLowerCase, replace and then trim that replace so something like
Hello [- the re _- wo rl d.
will turn into a string with no spaces or punctuation like
hellothereworld
I'm using this
let msg = message.content.toLowerCase()
let originalMessage = msg.split(" ");
let removePunctuation = originalMessage.toString().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"");
let checkMessage = removePunctuation.toString().trim();
then this to filter the message:
for (let i = 0; i < checkMessage.length; i++) {
if(allowed.includes(checkMessage[i])) {
continue;
}
if(curse.includes(checkMessage[i])) {
const filterViolation = new Discord.RichEmbed()
.setColor('#ff0000')
.setAuthor(message.author.username, message.author.avatarURL)
.setTitle('Filter Violation')
.setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
.setTimestamp()
.setFooter(copyright);
message.delete()
message.author.send(filterViolation)
message.channel.send(msgvio).then(msg => {msg.delete(15000)})
logger.write(logviolation)
}
//More code
}
Thanks to Tarazed for the help with the filter in general.
But when I type any message that goes against the filter, nothing happens and no errors are thrown in the console. Any ideas on what I did wrong?
New Code:
let checkMessage = message.content.toLowerCase().replace(/[^\w ]/g,"");
console.log(checkMessage);
// let checkMessage = msg.split(" ");
for (let i = 0; i < checkMessage.length; i++) {
if(checkMessage.includes(allowed[i])) {
continue;
}
//--------------------------------------- CURSE
if(checkMessage.includes(curse[i])) {
const filterViolation = new Discord.RichEmbed()
.setColor('#ff0000')
.setAuthor(message.author.username, message.author.avatarURL)
.setTitle('Filter Violation')
.setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
.setTimestamp()
.setFooter(copyright);
message.delete()
message.author.send(filterViolation)
message.channel.send(msgvio).then(msg => {msg.delete(15000)})
logger.write(logviolation)
}
}
It logs the check message correctly console.log(checkMessage); but it doesn't go through the filter, neither allowed or unallowed.
It logs the message correctly but the word violates the filter, but nothing is done.
New Code 2:
if(curse.some(word => checkMessage.includes(word) && !allowed.some(allow => allow.includes(word) && checkMessage.includes(allow)))) {
const filterViolation = new Discord.RichEmbed()
.setColor('#ff0000')
.setAuthor(message.author.username, message.author.avatarURL)
.setTitle('Filter Violation')
.setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
.setTimestamp()
.setFooter(copyright);
message.delete()
message.author.send(filterViolation)
message.channel.send(msgvio).then(msg => {msg.delete(15000)})
logger.write(logviolation)
return;
}

Your current problem is that you're iterating over literally just a string like "test" and checking if each letter is a curse word.
That is, checkMessage[0] will be 't', checkMessage[1] will be 'e', etc. I'm guessing no single character will match anything in your curse or even allowed array.
You can get rid of the loop entirely and simply check if(curse.includes(checkMessage)), the entire message... but be wary this may easily return false positives. Heaven forbid someone sends a message like "it was a nice pic until i looked closer" and pic until put together triggers a certain c-word in your filter.
Anyway, I'd like to also point out that your code for stripping out spaces and punctuation does some rather strange things. I'll comment what I expect to be happening at each stage. Assume an input message of " Hello - world. "
let originalMessage = msg //" hello - world. "
.split(" "); //["", "hello", "-", "world.", ""]
let removePunctuation = originalMessage
.toString() //",hello,-,world.," (why even split?)
.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,""); //"helloworld"
let checkMessage = removePunctuation
.toString() //"helloworld" (does nothing ever)
.trim(); //"helloworld" (does nothing ever)
You can achieve the same thing very easily by using the regex class \W which matches all non-word characters:
let checkMessage = message.content.toLowerCase().replace(/\W/g,""); //"helloworld"
It looks like there's still issues related to the loop. I suggest using Array#some to test if the message contains any curse words:
let checkMessage = message.content.toLowerCase().replace(/[^\w ]/g,"");
if(curse.some(word => //search through the curse words
checkMessage.includes(word) && //if message has this curse word
!allowed.some(allow => //and there's no allowed word which:
allow.includes(word) && //1. contains this curse word
checkMessage.includes(allow) //2. is in the message
)
)) {
//then send violation
}

Since checkMessage is a string, your for loop is looping over and testing individual characters.
For example:
let checkMessage = "hellothereworld";
for (let i = 0; i < checkMessage.length; i++) {
console.log(checkMessage[i]);
}
Perhaps you'd rather keep the spaces in your string and operate on individual words:
let originalMessage = "Hello [-the world"
// Use regex that keeps spaces
let removePunctuation = originalMessage.toString().replace(/[^\w ]/g,"");
let checkMessage = removePunctuation.toString().trim();
// Split into words
let messageArray = checkMessage.split(' ');
// Loop over words
for (let i = 0; i < messageArray.length; i++) {
console.log(messageArray[i]);
}

Related

DOMException while copying text to clipboard in javascript

I am trying to make a simple encoder in javascript, and copying the output to the clipboard, but the code gives an error.
I tried this code:
function encode() {
let alphabet = " abcdefghijklmnopqrstuvwxyz1234567890-=!##$%^&*()_+[];'/.,'{}|:~";
const a_list = alphabet.split('');
const m_list = prompt("message: ").split('');
let return_message = "";
for (let i = 0; i < m_list.length; i++) {
let current_letter = m_list[i];
let translated_letter = a_list[a_list.indexOf(current_letter) + 5];
return_message += translated_letter;
}
navigator.clipboard.writeText(return_message);
}
encode()
but the console gives this error:
Error: DOMException {INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, …}
I host the server in replit.
When I try to do an alert with the encoded words, it works fine.
navigator.clipboard.writeText requires a transient user activation. That is why it works when you click on an alert box.
Transient user activation is required. The user has to interact with the page or a UI element in order for this feature to work.
The "clipboard-write" permission of the Permissions API is granted automatically to pages when they are in the active tab.
https://devdocs.io/dom/clipboard/writetext
The error you are getting is because the indexOf function returns -1 when the sought character is not found in the a_list array.
You can check whether the index returned by indexOf is greater than or equal to zero before accessing the element in the a_list array. If the index returned is less than zero, you can simply add the original character to return_message.
Here is an example:
function encode() {
// Define the list of characters to be substituted
const alphabet = "abcdefghijklmnopqrstuvwxyz";
const charList = alphabet.split('');
// Receive the string to be substituted from the user
const inputString = prompt("Enter the string to be substituted:");
// Convert the string to an array of characters
const inputChars = inputString.split('');
// Create a new array with the substituted characters
const outputChars = inputChars.map(char => {
// Find the index of the current character in the character list
const index = charList.indexOf(char.toLowerCase());
// If the character is not in the character list, keep the original character
if (index === -1) {
return char;
}
// Find the next character in the character list
const nextIndex = (index + 1) % charList.length;
const nextChar = charList[nextIndex];
// Return the next substituted character
return char.toUpperCase() === char ? nextChar.toUpperCase() : nextChar;
});
// Convert the array of characters back to a string
const outputString = outputChars.join('');
// Display the substituted string in the console
navigator.clipboard.writeText(outputString);
}
encode()
And as answered in #dotnetCarpenter reply navigator.clipboard.writeText requires a transient user activation. That's why it works when an alert box is clicked.

Discord bot unit conversion command returns "undefined"

I was coding a simple unit conversion command for my discord bot that would convert meters to centimetres. I read over my code several times and couldn't find anything possibly wrong with it, however, when I run the command, it simply returns "undefined" for the result value. I also made a point to double check the scope of my code blocks to make sure all the variables are properly accessible.
Code:
if (message.content.startsWith(prefix + 'convert ')) {
let content = message.content.replace(prefix + 'convert ', '');
content.split(' ');
let value = content[0];
let firstUnit = content[1];
let convertedUnit = content[3];
let result;
let description;
let embedFormula;
if (firstUnit === 'm' && convertedUnit === 'cm') {
const formula = (inputValue) => {
return inputValue * 100;
}
result = formula(value);
description = `${value} m to cm = **${result} cm**`;
embedFormula = '`Multiply the length value by 100`';
}
const conversionEmbed = new Discord.MessageEmbed()
.setTitle('Unit Conversion')
.setDescription(description)
.setColor('#F942FF')
.addFields(
{ name: 'Formula', value: embedFormula }
)
message.delete();
message.channel.send(conversionEmbed);
}
Result:
The command runs when the user types "_convert 1 m to cm" (1 can of course be swapped with any number).
Is there anything missing here?
Thanks in advance.
content.split() won't edit existing variables:
let content = 'Hello!';
content.split();
console.log(content); // Still 'Hello!'
console.log(content[0]); // This just gets the first character
So instead of this:
let content = message.content.replace(prefix + 'convert ', '');
content.split(' ');
You should do this:
let content = message.content.replace(prefix + 'convert ', '').split(' ');

Telegram app to remove multiple words from input message

I'm trying to create a small app that reads a chat message and echoes a filtered text
I need it to take this message:
INPUT:
#notthis/remove
remove this line
This one too
Output:
notthis
At the moment all it does is remove the second word + the first hashtag:
"hello#hello" which becomes hello
I tried adding the / like this input.split("#","/"); but all it does is crash the program.
Not asking to do the program for me, but I'd really appreciate any hints.
Thank you!
const Telegraf = require('telegraf');
const bot = new Telegraf('182049');
const helpMessage = `
Say something to me
/start - start the bot
/help - command reference
`;
bot.start((ctx) => {
ctx.reply("Hi I am echoo bot");
ctx.reply(helpMessage);
});
bot.help((ctx) => {
ctx.reply(helpMessage)
});
bot.on("text", (ctx) => {
let input = ctx.message.text;
let inputArray = input.split("#");
console.log(inputArray);
let message = "";
if (inputArray.length == 1) {
message = "no separator";
} else {
inputArray.shift();
message = inputArray.join(" ");
}
ctx.reply(message);
});
bot.launch()
Regular Expression (regex) is a great way to find substrings in an unknown string, even though it might be a bit daunting to work with. You can use this website to create your regex.
To find a substring starting with # and ending with /, you can use the following expression:
/#\w+\//g
This will match 1 or more word characters that are in between a # and a /.
For example:
#foo/ will match
#f/ will match
#/ will not match
#foo bar/ will not match (whitespace is not a word character)
An example JavaScript code:
const regex = /#\w+\//g;
const text = "something#fooo/bar #lorem/ipsum";
const found = text.match(regex);
// For each found item, remove the first and last characters
const cleaned = found.map((a) => a.slice(1, -1));
console.log(cleaned);
I think I made it
const Telegraf = require('telegraf');
const bot = new Telegraf('18204DjYLa9o9Y');
const regex = /#\w+\//g;
const helpMessage = `
Say something to me
/start - start the bot
/help - command reference
`;
bot.start((ctx) => {
ctx.reply("Hi I am echoo bot");
ctx.reply(helpMessage);
})
bot.help((ctx) => {
ctx.reply(helpMessage)
})
bot.on("text", (ctx) => {
let input = ctx.message.text;
let inputArray = input.split("#");
console.log(inputArray);
let message = "";
inputArray.shift();
message = inputArray.join(" ");
let messageArray = message.split("/");
console.log(messageArray);
for(let index = 0; message[index] != '/'; index++ )
{
ctx.reply("/ta " + message[index]);
}
return null
})
bot.hears("cat", (ctx) =>{
ctx.reply("Meow");
})
bot.launch()
Only a little issue: if my coin has more than 3 letters it gets truncated.
For loop solves the problem but every letter starts with a new line, and the second imput gets messed up
Eg: echobot, [13.05.21 00:54]
E
echobot, [13.05.21 00:54]
O
echobot, [13.05.21 00:54]
S
2nd attempt:
echobot, [13.05.21 00:54]
S
echobot, [13.05.21 00:54]
O
echobot, [13.05.21 00:54]
E

Discord.JS Deleting a message if it contains a certain word

So I am trying too add moderation too my bot and since my server is fully SFW I am trying too make it so that my bot will delete a message if it contains an NSFW word, Here is my code. Im not sure if its correct but It is not working so I would imagine its not
message.content.includes === ("<Insert NSFW message or word here>")
message.delete(1)
Im still looking for help btw
You are doing great so far,
First I would you should create an array of NSFW words that you want to be censored
Ex:
const noNoWords = ["sex", "condum"];
After you have done that you should irritate through the array and see if the message's content includes the a NSFW word
Ex:
const noNoWords = ["sex", "condum"];
client.on("message", message => {
var content = message.content;
for (var i = 0; i < noNoWords.length; i++) {
if (content.includes(noNoWords[i])){
message.delete();
break
}
}
}
That works and all but if people type CAPS it wouldn't detect, or if people put in spaces, like t h i s. In order to fix this we need to remove all special characters and make the string lower case.
Ex:
var stringToCheck = content;
stringToCheck.replace(/\s+/g, '').toLowerCase();
Then you plug it in and it should look like this :)
const noNoWords = ["sex", "condum"];
client.on("message", message => {
var content = message.content;
var stringToCheck = content.replace(/\s+/g, '').toLowerCase();
for (var i = 0; i < noNoWords.length; i++) {
if (content.includes(noNoWords[i])){
message.delete();
break
}
}
}
if (message.content.includes("<Insert NSFW message or word here>"))
message.delete(1)

Javascript Discord bot with command that has multiple words

So I have a piece of code like this.
case 'trait':
if (args[1] === 'aerobic'){
const embed = new RichEmbed()
.setTitle('Aerobic')
.addField('Effect','When attacking with Window, gets SPDEF - and SPD +.')
.addField('Temtem that can have this trait', 'Volarend')
message.channel.send(embed);
}else if (args[1] === 'air specialist'){
const embed = new RichEmbed()
.setTitle('Air specialist')
.addField('Effect','+15% damage with Wind techniques.')
.addField('Temtem that can have this trait', 'Saku, Barnshe, Zebhyruff')
message.channel.send(embed);
}else {
message.channel.sendMessage('Invalid trait (use "-" instaed of space, when using two word trait)')
}
break;
The first "if" is working as intended but I have problem with the second one because it has two words. I want to use this command on Discord like this
!trait air specialist
Start of the code looks like this excluding the token, prefix etc.:
bot.on('ready', () => {
console.log('This bot is online!');
})
bot.on('message', message=>{
const args = message.content.toLowerCase().slice(PREFIX.length).trim().split(/ +/);
Thank you in advance.
The issue is that your message is being split so the two words aren't both in args[1]. args[1] is "air" and args[2] is "specialist".
You could fix this by either changing how you split your message so they are in the same string, or looking at multiple args to enter the else if statement if you still need it split up.
For example your message could be split like this:
const args = message.content.toLowerCase().slice(PREFIX.length).trim().split(/ (.*)/);
Or you could enter the if statement in a way like this:
else if (args[1] === 'air' && args[2] === 'specialist') { ... }
One solution if you are only expecting one conditional argument to be included in the command is to re-combine them using concatenation. This will only work if you are expecting the command and one argument though, if you want 2 or more arguments for a single command, it's a bit more complicated.
case 'trait':
// We should always have the first one
// but you should error check this first.
let combinedArgs = args[1];
for(let i = 2; i < args.length; i++)
{
combinedArgs += " " + args[i];
}
if (combinedArgs === 'aerobic'){
... and so on

Categories

Resources