aboutsummaryrefslogtreecommitdiff
path: root/src/handler.rs
blob: 7b4568f6666dd5cc075ffc391d3ab9364ffd8381 (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
use poise::serenity_prelude as serenity;

use crate::models::ReactionRole;
use crate::{Data, Error};

use tracing::info;

/**
 * Handles specific events, including ReactionAdd, which is needed for the reaction role handler to
 * function properly
 */
pub async fn event_handler(
    ctx: &serenity::Context,
    event: &poise::Event<'_>,
    data: &Data,
) -> Result<(), Error> {
    {
        let pool = data.pg.lock().unwrap().clone();
        match event {
            poise::Event::ReactionAdd { add_reaction } => {
                let current_user = ctx.http.get_current_user().await?;
                if add_reaction.user_id.unwrap() == current_user.id {
                    return Ok(());
                }
                // This fetches the role and lets us query extra data including role ID
                let rrole = sqlx::query_as!(
                    ReactionRole,
                    "SELECT * FROM reaction_roles WHERE message_id=$1 AND reaction=$2",
                    add_reaction.message_id.0.to_string(),
                    add_reaction.emoji.to_string()
                )
                .fetch_one(&pool)
                .await?;
                let member = ctx
                    .http
                    .get_member(
                        rrole.guild_id.parse::<u64>()?,
                        add_reaction.user_id.unwrap().0,
                    )
                    .await?;
                // Honestly, not really needed.
                let member_roles = member.roles;
                let role_id = serenity::RoleId(rrole.role_id.parse::<u64>()?);
                if member_roles.contains(&role_id) {
                    ctx.http
                        .remove_member_role(
                            member.guild_id.0,
                            member.user.id.0,
                            role_id.0,
                            Some("Reaction Role Menu"),
                        )
                        .await?;
                } else {
                    ctx.http
                        .add_member_role(
                            rrole.guild_id.parse::<u64>()?,
                            add_reaction.user_id.unwrap().0,
                            rrole.role_id.parse::<u64>()?,
                            Some("Reaction Role"),
                        )
                        .await?;
                }

                if let Ok(dm_chan) = add_reaction
                    .user_id
                    .unwrap()
                    .create_dm_channel(&ctx.http)
                    .await {
                        dm_chan.say(ctx, format!("Toggled the role!")).await?;
                    } else {
                        info!("Could not DM user, but we did the role anyways");
                    }

                add_reaction.delete(&ctx.http).await?;
            }
            _ => (),
        }
    }

    Ok(())
}