kovi_plugin_like/
lib.rs

1pub use kovi::tokio;
2use kovi::{
3    async_move,
4    log::info,
5    utils::{load_json_data, save_json_data},
6    PluginBuilder as p,
7};
8use serde::{Deserialize, Serialize};
9use serde_json::json;
10use std::{
11    sync::{Arc, Mutex},
12    time::{SystemTime, UNIX_EPOCH},
13};
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16struct Config {
17    today: Vec<i64>,
18    /// 储存秒级别时间戳
19    data_time: u64,
20    like_times: usize,
21    msg: Msg,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25struct Msg {
26    cmd: String,
27    like: String,
28    today: String,
29    do_not_like_you: String,
30}
31
32#[kovi::plugin]
33async fn main() {
34    let bot = p::get_runtime_bot();
35    let mut path = bot.get_data_path();
36    path.push("config.json");
37
38    let config: Config = {
39        let config: Config = serde_json::from_value(json!({
40            "today": [],
41            "data_time": 1,
42            "like_times": 10,
43            "msg": {
44                "cmd": "赞我",
45                "like": "已为你点赞10次",
46                "today": "今天赞过了,一边呆着去!",
47                "do_not_like_you": "就不给你点,略略略"
48            }
49        }))
50        .unwrap();
51
52        let mut config: Config = match load_json_data(config.clone(), &path) {
53            Ok(v) => v,
54            Err(e) => {
55                // 是json解析报错的话?
56                if let Some(_parse_error) = e.downcast_ref::<serde_json::Error>() {
57                    save_json_data(&config, &path).unwrap();
58                    config
59                } else {
60                    panic!("{e}")
61                }
62            }
63        };
64        let now = SystemTime::now()
65            .duration_since(UNIX_EPOCH)
66            .unwrap()
67            .as_secs();
68        if config.data_time / 86400 != now / 86400 {
69            config.today = Vec::new();
70            config.data_time = now;
71            save_json_data(&config, &path).unwrap();
72        }
73        config
74    };
75
76    let msg = Arc::new(config.msg.clone());
77    let path = Arc::new(path);
78    let config_arc = Arc::new(Mutex::new(config));
79
80    p::on_msg(async_move!(e; bot, msg, config_arc, path; {
81        if e.borrow_text() != Some(&msg.cmd) {
82            return;
83        }
84
85        {
86            let config_lock = config_arc.lock().unwrap();
87
88            if config_lock.today.contains(&e.user_id) {
89                e.reply_and_quote(&msg.today);
90                return;
91            }
92        }
93
94        let res = bot.send_like_return(e.user_id, 10).await;
95
96        {
97            let mut config_lock = config_arc.lock().unwrap();
98
99            match res {
100                Ok(_) => {
101                    e.reply_and_quote(&msg.like);
102                    config_lock.today.push(e.user_id);
103                    save_json_data(&*config_lock, &*path).unwrap();
104                }
105                Err(_) => e.reply_and_quote(&msg.do_not_like_you),
106            };
107        }
108    }));
109
110    p::cron("0 0 * * *", move || {
111        let config_clone_for_reset = config_arc.clone();
112        let path = path.clone();
113        async move {
114            // 清空 `today`
115            let mut config = config_clone_for_reset.lock().unwrap();
116            config.today.clear();
117            config.data_time = SystemTime::now()
118                .duration_since(UNIX_EPOCH)
119                .unwrap()
120                .as_secs();
121            info!("like插件正在清理");
122            save_json_data(&*config, &*path).unwrap();
123        }
124    })
125    .unwrap();
126}