kovi_plugin_copycat/
lib.rs1mod config;
2
3use kovi::{
4 PluginBuilder as plugin, RuntimeBot, bot::runtimebot::kovi_api::SetAccessControlList,
5 event::GroupMsgEvent, log::info, tokio::sync::Mutex,
6};
7use std::{
8 collections::HashMap,
9 sync::Arc,
10};
11
12use crate::config::CONFIG;
13
14struct State {
15 text: String,
16 count: u32,
17 sender: i64,
18}
19
20#[kovi::plugin]
21async fn init() {
22 let bot = plugin::get_runtime_bot();
23 let config = config::init(&bot).await.unwrap();
24
25 let state: Arc<Mutex<HashMap<i64, State>>> = Arc::new(Mutex::new(HashMap::new()));
26
27 match &config.allow_groups {
28 Some(groups) => {
29 bot.set_plugin_access_control("copycat", true).unwrap();
30 bot.set_plugin_access_control_list(
31 "copycat",
32 true,
33 SetAccessControlList::Adds(groups.clone()),
34 )
35 .unwrap();
36 }
37 None => {
38 bot.set_plugin_access_control("copycat", false).unwrap();
39 }
40 }
41
42 plugin::on_group_msg({
43 let bot = bot.clone();
44 let state = state.clone();
45 move |e| on_group_msg(e, bot.clone(), state.clone())
46 });
47}
48
49async fn on_group_msg(
50 event: Arc<GroupMsgEvent>,
51 bot: Arc<RuntimeBot>,
52 state: Arc<Mutex<HashMap<i64, State>>>,
53) {
54 let config = CONFIG.get().unwrap();
55
56 let msgs = event.message.get("text");
57 if msgs.len() > 1
58 || msgs.is_empty()
59 || !event.message.clone().into_iter().all(|m| m.type_ == "text")
60 {
61 info!("[copycat] Not a plain text message, ignored.");
62 return;
63 }
64
65 let msg = msgs[0].data["text"].as_str().unwrap().to_string();
66
67 {
68 let mut s = state.lock().await;
69 let s = match s.get_mut(&event.group_id) {
70 Some(s) => s,
71 None => {
72 s.insert(
73 event.group_id,
74 State {
75 text: String::new(),
76 count: 0,
77 sender: -1,
78 },
79 );
80 s.get_mut(&event.group_id).unwrap()
81 }
82 };
83
84 if s.text == msg {
85 if s.sender != event.sender.user_id {
86 s.count += 1;
87 info!(
88 "[copycat] Received repeated message, current count: {} / {}",
89 s.count, config.repeat_after
90 );
91 }
92 } else {
93 s.text = msg;
94 s.count = 1;
95 s.sender = event.sender.user_id;
96 }
97
98 if s.count == config.repeat_after {
99 bot.send_group_msg(event.group_id, &s.text);
100 s.count += 1;
101
102 info!(
103 "[copycat] Meow! Current count: {} / {}",
104 s.count, config.repeat_after
105 );
106 }
107 }
108}