diff --git a/config/keywords.json b/config/keywords.json index bbc75cd..4c57e6d 100644 --- a/config/keywords.json +++ b/config/keywords.json @@ -1,5 +1,5 @@ { - "scams":{ + "keywords":{ "verbs":[ "earn", "make", "making", "made", @@ -15,6 +15,7 @@ "upload", "login", "send", + "join", "buy", "check", "private" @@ -32,8 +33,6 @@ "nft", "token", "free", - "meet", - "upload", "gift", "card", "nude", @@ -59,10 +58,9 @@ "wickr", "kik", "instagram", + "dm me", "👇", "👆️", "+1", "+2" - ], - "response":"Warning! This message is likely to be a scam, hoping to lure you in and steal your money! Please visit these resources for more information:\n- https://www.sec.gov/oiea/investor-alerts-and-bulletins/digital-asset-and-crypto-investment-scams-investor-alert \n [!mods !modhelp]", - "response_md":"Warning! This message is likely to be a scam, hoping to lure you in and steal your money! Please visit these resources for more information:
[!mods !modhelp]" + ] } } diff --git a/config/responses.json b/config/responses.json new file mode 100644 index 0000000..c8fe659 --- /dev/null +++ b/config/responses.json @@ -0,0 +1,18 @@ +{ + "reply": { + "Ok": null, + "MaybeScam": null, + "LikelyScam": { + "plain": "Watch out, the message you replied to has been detected as a scam! Please don't do anything they ask you to do! Stay safe", + "html": "Watch out, the message you replied to has been detected as a scam! Please don't do anything they ask you to do! Stay safe" + } + }, + "message": { + "Ok": null, + "MaybeScam": null, + "LikelyScam": { + "plain": "Warning! This message is likely to be a scam, seeking to lure you in and steal your money! Please visit these resources for more information:\n- https://www.sec.gov/oiea/investor-alerts-and-bulletins/digital-asset-and-crypto-investment-scams-investor-alert \n [!mods !modhelp]", + "html": "Warning! This message is likely to be a scam, seeking to lure you in and steal your money! Please visit these resources for more information: [!mods !modhelp]" + } + } +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 10d3f8e..9682c74 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,15 +2,20 @@ use serde_json::Value; pub struct Config { pub keywords: Value, + pub responses: Value, } impl Config { pub fn load() -> Config { let keywords_reader = std::fs::File::open("config/keywords.json").expect("Couldn't find keywords.json"); - let keywords: Value = serde_json::from_reader(keywords_reader).expect("Couldn't read keywords.json"); + let keywords: Value = serde_json::from_reader(keywords_reader).expect("Couldn't read keywords"); + let responses_reader = std::fs::File::open("config/responses.json").expect("Couldn't find responses.json"); + let responses: Value = serde_json::from_reader(responses_reader).expect("Couldn't read responses"); + Self { - keywords + keywords, + responses } } } \ No newline at end of file diff --git a/src/judge.rs b/src/judge.rs index c719b75..e9aff13 100644 --- a/src/judge.rs +++ b/src/judge.rs @@ -2,27 +2,37 @@ use crate::{CONFIG, keywords::{Keywords, KeywordCategory}}; use matrix_sdk::{room::Joined, ruma::events::room::message::{RoomMessageEventContent, OriginalRoomMessageEvent}}; use serde_json::json; +#[derive(Debug)] pub enum JudgementResult { Ok, MaybeScam, // hit atleast one category LikelyScam, // hit all categories } +impl JudgementResult { + pub fn to_json_var(&self) -> &str { + match self { + Self::Ok => "Ok", + Self::MaybeScam => "MaybeScam", + Self::LikelyScam => "LikelyScam" + } + } +} + pub struct Judgement { - pub text: String, + pub text: String } impl Judgement { pub fn judge(&self) -> anyhow::Result{counter:?}
{count_all}/{total}
{result:?}
"));
+ room.send(msg, None).await.expect("Couldn't send message");
+
+ Ok(())
+ }
+
+ pub async fn alert(room: &Joined, event: &OriginalRoomMessageEvent, result: JudgementResult, is_reply: bool) -> anyhow::Result<()> {
+ let mut responses = CONFIG.responses.clone();
+ let responses = responses.as_object_mut().unwrap();
+
+ // Add stats to end of response
+ let section = if is_reply {
+ responses["reply"].as_object().unwrap()
+ } else {
+ responses["message"].as_object().unwrap()
+ };
+
+ let response_type = section.get(result.to_json_var()).unwrap();
+ if response_type.is_null() {
+ anyhow::bail!("Called alert with result that has no detection message");
+ }
+
+ let response_type = response_type.as_object().unwrap();
+ let plain = response_type["plain"].as_str().unwrap();
+ let html = response_type["html"].as_str().unwrap();
+
+ // Send message
+ let msg = RoomMessageEventContent::text_html(plain, html);
let reply = msg.make_reply_to(event);
room.send(reply, None).await.expect("Couldn't send message");
// Send reaction
- room.send_raw(json!({
- "m.relates_to": {
- "rel_type": "m.annotation",
- "event_id": event.event_id.to_string(),
- "key": "🚨🚨 SCAM 🚨🚨"
- }}), "m.reaction", None).await.expect("Couldn't send reaction");
+ if !is_reply {
+ room.send_raw(json!({
+ "m.relates_to": {
+ "rel_type": "m.annotation",
+ "event_id": event.event_id.to_string(),
+ "key": "🚨🚨 SCAM 🚨🚨"
+ }}), "m.reaction", None).await.expect("Couldn't send reaction");
+ }
Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index aa6a1c1..8d3d28c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
use matrix_sdk::{
room::Room,
ruma::{events::room::message::{
- MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, Relation, RoomMessageEvent
+ MessageType, OriginalSyncRoomMessageEvent, Relation, RoomMessageEvent
}, OwnedRoomId},
Error, LoopCtrl,
};
@@ -23,14 +23,16 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
return Ok(());
};
- // Ignore own messages
- if event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) }
-
// Too short to be a scam lol
if text_content.body.chars().count() < 12 { return Ok(()) }
let text_content = text_content.body.to_lowercase();
+ let debug = text_content.contains(";spdebug");
+
+ // Ignore own messages
+ if !debug && event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) }
+
let judgement = judge::Judgement { text: text_content };
// Handle replies
@@ -52,15 +54,20 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
let event = event.as_original().unwrap();
let content = event.content.to_owned().body().to_lowercase();
- if event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) }
+ if !debug && event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) }
let reply_judgement = judge::Judgement { text: content };
+ if debug {
+ reply_judgement.send_debug(&room).await?;
+ return Ok(());
+ }
+
match reply_judgement.judge()? {
judge::JudgementResult::Ok => (),
judge::JudgementResult::MaybeScam => (),
judge::JudgementResult::LikelyScam => {
- judge::Judgement::alert(&room, &orig_event).await?;
+ judge::Judgement::alert(&room, &orig_event, judge::JudgementResult::LikelyScam, true).await?;
return Ok(());
}
}
@@ -71,7 +78,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
judge::JudgementResult::Ok => return Ok(()),
judge::JudgementResult::MaybeScam => return Ok(()),
judge::JudgementResult::LikelyScam => {
- judge::Judgement::alert(&room, &orig_event).await?;
+ judge::Judgement::alert(&room, &orig_event, judge::JudgementResult::LikelyScam, false).await?;
return Ok(());
}
}