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
Related
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(' ');
I'm trying to replace the user flags with emojis but I have no idea how to do it.
I tried that but it didn't work
const flags = {
"HOUSE_BRILLIANCE":"<:house_brilliance:773066280303198218>",
"HOUSE_BRAVERY":"<:house_bravery:773066279967522868>",
"HOUSE_BALANCE":"<:house_balance:773066280319057930>",
"EARLY_SUPPORTER":"<:early_supporter:773066280416444466>",
"HYPESQUAD_EVENTS":"<:hypesquad_events:773066279892418613>",
"BUGHUNTER_LEVEL_1":"<:bughunter:773066280269512714>",
"BUGHUNTER_LEVEL_2":"<:bughunter:773066280269512714>",
"DISCORD_EMPLOYEE":"<:early_verified_bot_developer:773066280135688212>",
"PARTNERED_SERVER_OWNER":"<:partnered_server_owner:773066279996751872>",
"TEAM_USER":"",
"SYSTEM":"",// tf is this one
}
let mflags = message.mentions.users.first().flags.toArray().join(' ')
let fres = mflags.replace(/#(\w+)/g, (match,key)=>flags[key]||match);```
I have a search input and I need to bold a mathcing part of the string in result.
For example:
input: mac
Search results:
mac book pro 16
iMac 27"
Important macOS tips
I tried do something like that:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let startText = resultText.toLowerCase().indexOf(searchInput.value.toLowerCase());
let matchingWord = resultText.toLowerCase().substring(startText);
let newWord = `${resultText.substring(0, startText)}<b>${matchingWord}</b>${partAfterMatchingWordHere}`;
result.children[0].innerHTML = newWord;
})
But in that case I don't know how to get the end index
So in word "mac book pro" - the first index need to be 0 and the last need to be 2.
If you have a solution for it or a best way to do that please help me
I was able to do it thanks to https://stackoverflow.com/users/12270289/klaycon
Code:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let newWord = resultText.toLowerCase().replace(searchInput.value.toLowerCase(), `<b>${searchInput.value}</b>`);
result.children[0].innerHTML = newWord;
})
You can add (String.length-1) to the start index to get the ending index
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)
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]);
}