@@ -18,8 +18,28 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
18
18
mod commands;
19
19
20
20
use anyhow:: Context as _;
21
+ use std:: collections:: HashMap ;
21
22
22
- struct Data { }
23
+ use poise:: { Context as PoiseContext , Framework , FrameworkOptions , PrefixFrameworkOptions } ;
24
+ use serenity:: {
25
+ client:: Context as SerenityContext ,
26
+ client:: FullEvent ,
27
+ model:: {
28
+ channel:: ReactionType ,
29
+ gateway:: GatewayIntents ,
30
+ id:: { MessageId , RoleId } ,
31
+ } ,
32
+ } ;
33
+
34
+ type Context < ' a > = PoiseContext < ' a , Data , Error > ;
35
+ type Error = Box < dyn std:: error:: Error + Send + Sync > ;
36
+
37
+ struct Data {
38
+ reaction_roles : HashMap < MessageId , ( ReactionType , RoleId ) > ,
39
+ }
40
+
41
+ const ARCHIVE_MESSAGE_ID : u64 = 1295815208689733703 ;
42
+ const ARCHIVE_ROLE_ID : u64 = 1208457364274028574 ;
23
43
24
44
#[ shuttle_runtime:: main]
25
45
async fn main (
@@ -29,31 +49,92 @@ async fn main(
29
49
. get ( "DISCORD_TOKEN" )
30
50
. context ( "'DISCORD_TOKEN' was not found" ) ?;
31
51
32
- let framework = poise :: Framework :: builder ( )
33
- . options ( poise :: FrameworkOptions {
52
+ let framework = Framework :: builder ( )
53
+ . options ( FrameworkOptions {
34
54
commands : commands:: get_commands ( ) ,
35
- prefix_options : poise:: PrefixFrameworkOptions {
36
- prefix : Option :: Some ( String :: from ( "$" ) ) ,
55
+ event_handler : |ctx, event, framework, data| {
56
+ Box :: pin ( event_handler ( ctx, event, framework, data) )
57
+ } ,
58
+ prefix_options : PrefixFrameworkOptions {
59
+ prefix : Some ( String :: from ( "$" ) ) ,
37
60
..Default :: default ( )
38
61
} ,
39
62
..Default :: default ( )
40
63
} )
41
64
. setup ( |ctx, _ready, framework| {
42
65
Box :: pin ( async move {
43
66
poise:: builtins:: register_globally ( ctx, & framework. options ( ) . commands ) . await ?;
44
- Ok ( Data { } )
67
+
68
+ let mut data = Data {
69
+ reaction_roles : HashMap :: new ( ) ,
70
+ } ;
71
+
72
+ let message_id = MessageId :: new ( ARCHIVE_MESSAGE_ID ) ;
73
+ let role_id = RoleId :: new ( ARCHIVE_ROLE_ID ) ;
74
+
75
+ data. reaction_roles . insert (
76
+ message_id,
77
+ ( ReactionType :: Unicode ( "📁" . to_string ( ) ) , role_id) ,
78
+ ) ;
79
+
80
+ Ok ( data)
45
81
} )
46
82
} )
47
83
. build ( ) ;
48
84
49
85
let client = serenity:: client:: ClientBuilder :: new (
50
86
discord_token,
51
- serenity:: model:: gateway:: GatewayIntents :: non_privileged ( )
52
- | serenity:: model:: gateway:: GatewayIntents :: MESSAGE_CONTENT ,
87
+ GatewayIntents :: non_privileged ( ) | GatewayIntents :: MESSAGE_CONTENT ,
53
88
)
54
89
. framework ( framework)
55
90
. await
56
91
. map_err ( shuttle_runtime:: CustomError :: new) ?;
57
92
58
93
Ok ( client. into ( ) )
59
94
}
95
+
96
+ async fn event_handler (
97
+ ctx : & SerenityContext ,
98
+ event : & FullEvent ,
99
+ _framework : poise:: FrameworkContext < ' _ , Data , Error > ,
100
+ data : & Data ,
101
+ ) -> Result < ( ) , Error > {
102
+ match event {
103
+ FullEvent :: ReactionAdd { add_reaction } => {
104
+ if let Some ( ( expected_reaction, role_id) ) =
105
+ data. reaction_roles . get ( & add_reaction. message_id )
106
+ {
107
+ if & add_reaction. emoji == expected_reaction {
108
+ if let Some ( guild_id) = add_reaction. guild_id {
109
+ // TODO: Use try_join to await concurrently?
110
+ if let Ok ( member) =
111
+ guild_id. member ( ctx, add_reaction. user_id . unwrap ( ) ) . await
112
+ {
113
+ let _ = member. add_role ( & ctx. http , * role_id) . await ;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ FullEvent :: ReactionRemove { removed_reaction } => {
121
+ if let Some ( ( expected_reaction, role_id) ) =
122
+ data. reaction_roles . get ( & removed_reaction. message_id )
123
+ {
124
+ if & removed_reaction. emoji == expected_reaction {
125
+ if let Some ( guild_id) = removed_reaction. guild_id {
126
+ if let Ok ( member) = guild_id
127
+ . member ( ctx, removed_reaction. user_id . unwrap ( ) )
128
+ . await
129
+ {
130
+ let _ = member. remove_role ( & ctx. http , * role_id) . await ;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ _ => { }
137
+ }
138
+
139
+ Ok ( ( ) )
140
+ }
0 commit comments