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(())
}
|