@@ -18,9 +18,10 @@ pub async fn send_register_confirmation_from_message(
1818 msg : & Message ,
1919 config : & Config ,
2020 trigger_timestamp : i64 ,
21+ target_roles : & Option < String > ,
2122) {
2223 let mut params = HashMap :: new ( ) ;
23- params. insert ( "time" . to_string ( ) , format ! ( "<t:{}:F >" , trigger_timestamp) ) ;
24+ params. insert ( "time" . to_string ( ) , format ! ( "<t:{}:t >" , trigger_timestamp) ) ;
2425 params. insert (
2526 "remaining_time" . to_string ( ) ,
2627 format ! ( "<t:{}:R>" , trigger_timestamp) ,
@@ -30,33 +31,33 @@ pub async fn send_register_confirmation_from_message(
3031 params. insert ( "content" . to_string ( ) , reminder_content. to_string ( ) ) ;
3132 }
3233
33- if !reminder_content. is_empty ( ) {
34- let _ = MessageBuilder :: system_message ( & ctx, & config)
35- . translated_content (
36- "reminder.registered_with_content" ,
37- Some ( & params) ,
38- None ,
39- None ,
40- )
41- . await
42- . to_channel ( msg. channel_id )
43- . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
44- . send ( true )
45- . await ;
34+ let has_roles = if let Some ( roles_str) = target_roles {
35+ let role_mentions: String = roles_str
36+ . split ( ',' )
37+ . filter_map ( |s| s. trim ( ) . parse :: < u64 > ( ) . ok ( ) )
38+ . map ( |id| format ! ( "<@&{}>" , id) )
39+ . collect :: < Vec < _ > > ( )
40+ . join ( ", " ) ;
41+ params. insert ( "roles" . to_string ( ) , role_mentions) ;
42+ true
4643 } else {
47- let _ = MessageBuilder :: system_message ( & ctx, & config)
48- . translated_content (
49- "reminder.registered_without_content" ,
50- Some ( & params) ,
51- None ,
52- None ,
53- )
54- . await
55- . to_channel ( msg. channel_id )
56- . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
57- . send ( true )
58- . await ;
59- }
44+ false
45+ } ;
46+
47+ let key = match ( has_roles, !reminder_content. is_empty ( ) ) {
48+ ( true , true ) => "reminder.registered_with_content_roles" ,
49+ ( true , false ) => "reminder.registered_without_content_roles" ,
50+ ( false , true ) => "reminder.registered_with_content" ,
51+ ( false , false ) => "reminder.registered_without_content" ,
52+ } ;
53+
54+ let _ = MessageBuilder :: system_message ( & ctx, & config)
55+ . translated_content ( key, Some ( & params) , None , None )
56+ . await
57+ . to_channel ( msg. channel_id )
58+ . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
59+ . send ( true )
60+ . await ;
6061}
6162
6263pub async fn send_register_confirmation_from_command (
@@ -66,9 +67,10 @@ pub async fn send_register_confirmation_from_command(
6667 command : & CommandInteraction ,
6768 config : & Config ,
6869 trigger_timestamp : i64 ,
70+ target_roles : & Option < String > ,
6971) {
7072 let mut params = HashMap :: new ( ) ;
71- params. insert ( "time" . to_string ( ) , format ! ( "<t:{}:F >" , trigger_timestamp) ) ;
73+ params. insert ( "time" . to_string ( ) , format ! ( "<t:{}:t >" , trigger_timestamp) ) ;
7274 params. insert (
7375 "remaining_time" . to_string ( ) ,
7476 format ! ( "<t:{}:R>" , trigger_timestamp) ,
@@ -78,33 +80,33 @@ pub async fn send_register_confirmation_from_command(
7880 params. insert ( "content" . to_string ( ) , reminder_content. to_string ( ) ) ;
7981 }
8082
81- if !reminder_content. is_empty ( ) {
82- let _ = MessageBuilder :: system_message ( & ctx, & config)
83- . translated_content (
84- "reminder.registered_with_content" ,
85- Some ( & params) ,
86- None ,
87- None ,
88- )
89- . await
90- . to_channel ( command. channel_id )
91- . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
92- . send_interaction_followup ( & command, true )
93- . await ;
83+ let has_roles = if let Some ( roles_str) = target_roles {
84+ let role_mentions: String = roles_str
85+ . split ( ',' )
86+ . filter_map ( |s| s. trim ( ) . parse :: < u64 > ( ) . ok ( ) )
87+ . map ( |id| format ! ( "<@&{}>" , id) )
88+ . collect :: < Vec < _ > > ( )
89+ . join ( ", " ) ;
90+ params. insert ( "roles" . to_string ( ) , role_mentions) ;
91+ true
9492 } else {
95- let _ = MessageBuilder :: system_message ( & ctx, & config)
96- . translated_content (
97- "reminder.registered_without_content" ,
98- Some ( & params) ,
99- None ,
100- None ,
101- )
102- . await
103- . to_channel ( command. channel_id )
104- . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
105- . send_interaction_followup ( & command, true )
106- . await ;
107- }
93+ false
94+ } ;
95+
96+ let key = match ( has_roles, !reminder_content. is_empty ( ) ) {
97+ ( true , true ) => "reminder.registered_with_content_roles" ,
98+ ( true , false ) => "reminder.registered_without_content_roles" ,
99+ ( false , true ) => "reminder.registered_with_content" ,
100+ ( false , false ) => "reminder.registered_without_content" ,
101+ } ;
102+
103+ let _ = MessageBuilder :: system_message ( & ctx, & config)
104+ . translated_content ( key, Some ( & params) , None , None )
105+ . await
106+ . to_channel ( command. channel_id )
107+ . footer ( format ! ( "{}: {}" , "ID" , reminder_id) )
108+ . send_interaction_followup ( & command, true )
109+ . await ;
108110}
109111
110112pub fn spawn_reminder (
@@ -250,34 +252,43 @@ async fn get_targeted_mentions(
250252 }
251253 } ;
252254
253- let mut user_ids_with_roles: HashSet < UserId > = HashSet :: new ( ) ;
254-
255- for role_id in & role_ids {
256- let role_id_obj = RoleId :: new ( * role_id) ;
257- for member in & members {
258- if member. roles . contains ( & role_id_obj) {
259- user_ids_with_roles. insert ( member. user . id ) ;
260- }
261- }
262- }
263-
264- let mut opted_out_users: HashSet < u64 > = HashSet :: new ( ) ;
265-
255+ let mut optouts_by_role: HashMap < u64 , HashSet < u64 > > = HashMap :: new ( ) ;
266256 for role_id in & role_ids {
267257 match get_optouts_for_role ( guild_id as i64 , * role_id as i64 , pool) . await {
268258 Ok ( optouts) => {
269- for user_id in optouts {
270- opted_out_users. insert ( user_id as u64 ) ;
271- }
259+ optouts_by_role. insert ( * role_id, optouts. into_iter ( ) . map ( |id| id as u64 ) . collect ( ) ) ;
272260 }
273261 Err ( e) => {
274262 eprintln ! ( "Failed to get optouts for role {}: {}" , role_id, e) ;
263+ optouts_by_role. insert ( * role_id, HashSet :: new ( ) ) ;
275264 }
276265 }
277266 }
278267
279- user_ids_with_roles
280- . into_iter ( )
281- . filter ( |user_id| !opted_out_users. contains ( & user_id. get ( ) ) )
282- . collect ( )
268+ let mut users_to_mention: Vec < UserId > = Vec :: new ( ) ;
269+
270+ for member in & members {
271+ let user_target_roles: Vec < u64 > = role_ids
272+ . iter ( )
273+ . filter ( |& & role_id| member. roles . contains ( & RoleId :: new ( role_id) ) )
274+ . copied ( )
275+ . collect ( ) ;
276+
277+ if user_target_roles. is_empty ( ) {
278+ continue ;
279+ }
280+
281+ let has_subscribed_role = user_target_roles. iter ( ) . any ( |role_id| {
282+ !optouts_by_role
283+ . get ( role_id)
284+ . map ( |optouts| optouts. contains ( & member. user . id . get ( ) ) )
285+ . unwrap_or ( false )
286+ } ) ;
287+
288+ if has_subscribed_role {
289+ users_to_mention. push ( member. user . id ) ;
290+ }
291+ }
292+
293+ users_to_mention
283294}
0 commit comments