Added detect long message spam

main
David 2023-01-10 16:40:32 +01:00
parent 341821e63d
commit 45b2c5d605
3 changed files with 77 additions and 18 deletions

13
example_config.ini 100644
View File

@ -0,0 +1,13 @@
[credentials]
user_id = @account:matrix.org
homeserver = matrix.org
password = some_password
[room]
room = !some_room_id:matrix.org
[swear_list]
url = https://raw.githubusercontent.com/chucknorris-io/swear-words/master/en
[rules]
allow_swear = false

View File

@ -170,6 +170,12 @@ pub mod bot {
};
bot.detect_spam(&event).await;
bot.detect_command(&event, &text).await;
if bot.detect_whitespace_spam(&text) {
bot.delete_message_from_room(id, "Spamming").await;
bot.update_reputation_for_member(&member, -1)
.await
.expect("Failed to subtract reputation from member");
}
if detect_caps(&text) {
bot.delete_message_from_room(id, "Caps").await;
@ -190,7 +196,6 @@ pub mod bot {
.await
.expect("Failed to subtract reputation from member");
};
bot.detect_spam(&event).await;
if detect_caps(&text) {
bot.delete_message_from_room(&edited_msg_event_id, "Caps")
.await;
@ -201,6 +206,18 @@ pub mod bot {
}
}
fn detect_whitespace_spam(&self, message: &str) -> bool {
let mut counter: f32 = 0.0;
if message.len() >= 20{
for char in message.chars() {
if char.is_ascii_whitespace() || char.is_ascii_punctuation() {
counter += 1.0
}
}
}
counter/message.len() as f32 >= 0.8
}
async fn delete_message_from_room(&self, event_id: &OwnedEventId, reason: &str) {
let result = self.joined_room.redact(event_id, Some(reason), None).await;
if result.is_err() {
@ -245,11 +262,10 @@ pub mod bot {
let member_id: &str = member.user_id().as_str();
if member.power_level() <= 50 {
// Won't kick mods and admins
if let Some(_) = self
if let Ok(_) = self
.joined_room
.kick_user(member.user_id(), Some(reason))
.await
.ok()
{
dbg!(self.database_handle.remove(member_id).unwrap());
self.send_message(&format!("Member {} has been kicked.", member_id))
@ -267,7 +283,6 @@ pub mod bot {
}
async fn detect_spam(&mut self, event: &OriginalSyncRoomMessageEvent) {
let author = self
.joined_room
.get_member(&event.sender)
@ -276,12 +291,14 @@ pub mod bot {
.unwrap();
let author_name = author.user_id().as_str().to_string();
let curr_utc = Utc::now().timestamp();
if !self.spam_info.author_msg_times.contains_key(&author_name) || self.spam_info.author_msg_times.is_empty() {
if !self.spam_info.author_msg_times.contains_key(&author_name)
|| self.spam_info.author_msg_times.is_empty()
{
self.spam_info
.author_msg_times
.insert(author_name.clone(), vec![curr_utc]);
} else if let Some(msg_times) = self.spam_info.author_msg_times.get_mut(&author_name) {
msg_times.push(curr_utc)
msg_times.push(curr_utc)
}
let expire_time: i64 = curr_utc - self.spam_info.detection_window;
@ -323,7 +340,12 @@ pub mod bot {
async fn detect_command(&self, event: &OriginalSyncRoomMessageEvent, message: &str) {
let words: Vec<&str> = message.split_whitespace().collect();
let member = self.joined_room.get_member(&event.sender).await.unwrap().unwrap();
let member = self
.joined_room
.get_member(&event.sender)
.await
.unwrap()
.unwrap();
if words.first().unwrap().deref() == "!modbot" {
if words[1] == "award" || words[1] == "warn" {
let result = dbg!(self.database_handle.get(words[2]));
@ -332,7 +354,8 @@ pub mod bot {
let (timestamp, _) = convert_from_bytes_sled(&result.unwrap().unwrap());
let curr_utc = Utc::now().timestamp();
if self.check_if_member_exists(words[2]) {
if curr_utc - timestamp > 86400 || member.power_level() >= 50 { // Does
if curr_utc - timestamp > 86400 || member.power_level() >= 50 {
// Does
// not affect room admins
let user_data =
dbg!(self.database_handle.get(words[2]).unwrap());
@ -342,7 +365,10 @@ pub mod bot {
reputation -= 1
}
if words[1] == "warn" && member.power_level() < 50 {
self.send_message("This command is for moderators and admins only!").await;
self.send_message(
"This command is for moderators and admins only!",
)
.await;
}
if words[1] == "award" {
reputation += 1;
@ -355,8 +381,7 @@ pub mod bot {
words[2], reputation
))
.await;
}
else {
} else {
let mut time_left = (curr_utc - timestamp) / 60;
time_left = 24 - time_left;
self.send_message(
@ -365,14 +390,14 @@ pub mod bot {
.await;
}
}
},
}
Ok(None) => {
self.send_message(
"Cannot find user. Check if the User ID provided is correct",
)
.await;
},
}
Err(_) => {
self.send_message(

View File

@ -7,6 +7,7 @@ pub mod utils {
};
use matrix_sdk::ruma::OwnedEventId;
use sled::IVec;
use std::str::Chars;
use std::{
collections::HashMap,
fs::File,
@ -92,6 +93,30 @@ pub mod utils {
*bytes
}
pub fn convert_str_to_vec(input: &str) -> Vec<i64> {
// Implementation 1:
// input
// .split_at(input.len() - 1)
// .0
// .split_at(1)
// .1 // Deletes the first and last character of a string (deletes the brackets)
// .chars()
// .filter(|c| !c.is_whitespace()) // Deletes all whitespaces
// .collect::<String>()
// .as_str()
// .split(',')
// .collect::<Vec<&str>>()
// .iter_mut()
// .map(|x| x.parse::<i64>().unwrap()) // Changes from &str to i64
// .collect::<Vec<i64>>();
//
// Improved implementation
input[1..input.len() - 1]
.split(',')
.map(|n| n.trim().parse().unwrap())
.collect()
}
pub fn detect_caps(message: &str) -> bool {
let characters = message.chars().collect::<Vec<char>>();
let msg_length: f32 = characters.len() as f32;
@ -102,10 +127,6 @@ pub mod utils {
}
}
if counter / msg_length >= 0.8 {
true
} else {
false
}
counter / msg_length >= 0.8
}
}