summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: b78c80bccd7a3d8f273363a50b2e287304973bd0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use derive_deref::{Deref, DerefMut};
use serenity::framework::StandardFramework;
use serenity::model::prelude::*;
use serenity::prelude::*;
use serenity::utils::Colour;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[derive(Default)]
struct Handler {
    inactive_map: Arc<Mutex<HashMap<GuildId, InactiveThreads>>>,
}

#[derive(Debug, Deref, DerefMut)]
struct InactiveThreads(HashMap<ChannelId, bool>);

impl InactiveThreads {
    fn new(guild: Guild) -> Self {
        Self(
            guild
                .threads
                .iter()
                .map(|thread| (thread.id, thread.thread_metadata.unwrap().archived))
                .collect(),
        )
    }
}

#[serenity::async_trait]
impl EventHandler for Handler {
    async fn thread_update(&self, ctx: Context, thread: GuildChannel) {
        let parent_channel = loop {
            let mut inactive_map = self.inactive_map.lock().unwrap();
            let inactive_threads = inactive_map
                .entry(thread.guild_id)
                .or_insert_with(|| InactiveThreads::new(ctx.cache.guild(thread.guild_id).unwrap()));
            let current = thread.thread_metadata.unwrap().archived;
            let previous = inactive_threads.insert(thread.id, current);
            if !(previous.unwrap_or_default() && !current) {
                return;
            }
            break thread.parent_id.unwrap();
        };

        println!(
            "notifying about thread {} in parent channel {}",
            thread.name, parent_channel
        );
        if let Err(why) = parent_channel
            .send_message(&ctx.http, |msg| {
                msg.embed(|e| {
                    e.colour(Colour::TEAL)
                        .title("New activity in thread")
                        .description(thread.mention())
                })
            })
            .await
        {
            println!("got error while sending embed: {}", why);
        }
    }

    async fn guild_create(&self, _: Context, guild: Guild, _is_new: bool) {
        println!("discovered guild {}", guild.name);
        self.inactive_map
            .lock()
            .unwrap()
            .insert(guild.id, InactiveThreads::new(guild));
    }

    async fn ready(&self, _: Context, ready: Ready) {
        println!("logged in as {}", ready.user.name);
    }
}

#[tokio::main]
async fn main() {
    let token = std::env::var("CESSPOOL_TOKEN")
        .expect("Need discord bot token at environment variable CESSPOOL_TOKEN");
    Client::builder(&token, GatewayIntents::GUILDS)
        .framework(StandardFramework::new())
        .event_handler(Handler::default())
        .await
        .unwrap()
        .start()
        .await
        .unwrap();
}