1+ use  crate :: github:: User ; 
12use  crate :: zulip:: api:: Recipient ; 
3+ use  crate :: zulip:: render_zulip_username; 
24use  crate :: { 
35    config:: { NotifyZulipConfig ,  NotifyZulipLabelConfig ,  NotifyZulipTablesConfig } , 
46    github:: { Issue ,  IssuesAction ,  IssuesEvent ,  Label } , 
57    handlers:: Context , 
68} ; 
9+ use  futures:: future:: join_all; 
710use  tracing as  log; 
811
912pub ( super )  struct  NotifyZulipInput  { 
@@ -214,10 +217,15 @@ pub(super) async fn handle_input<'a>(
214217                topic :  & topic, 
215218            } ; 
216219
220+             // Issue/PR authors/reviewers will receive a mention if the template has `{recipients}`. 
221+             let  recipients = & mut  event. issue . assignees . clone ( ) ; 
222+             recipients. push ( event. issue . user . clone ( ) ) ; 
223+ 
217224            for  msg in  msgs { 
218225                let  msg = msg. replace ( "{number}" ,  & event. issue . number . to_string ( ) ) ; 
219226                let  msg = msg. replace ( "{title}" ,  & event. issue . title ) ; 
220227                let  msg = replace_team_to_be_nominated ( & event. issue . labels ,  msg) ; 
228+                 let  msg = msg. replace ( "{recipients}" ,  & get_zulip_ids ( ctx,  & recipients) . await ) ; 
221229
222230                let  req = crate :: zulip:: MessageApiRequest  { 
223231                    recipient, 
@@ -236,6 +244,33 @@ pub(super) async fn handle_input<'a>(
236244    Ok ( ( ) ) 
237245} 
238246
247+ async  fn  get_zulip_ids ( ctx :  & Context ,  recipients :  & [ User ] )  -> String  { 
248+     let  gh_ids_fut = recipients
249+         . iter ( ) 
250+         . map ( |recipient| async  move  {  ctx. team . github_to_zulip_id ( recipient. id ) . await  } ) ; 
251+     let  zulip_ids = join_all ( gh_ids_fut) . await ; 
252+ 
253+     let  zulip_ids = zulip_ids
254+         . iter ( ) 
255+         . filter_map ( |x| { 
256+             if  let  Ok ( id2)  = x. as_ref ( ) 
257+                 && let  Some ( id)  = * id2
258+             { 
259+                 Some ( render_zulip_username ( id) ) 
260+             }  else  { 
261+                 None 
262+             } 
263+         } ) 
264+         . collect :: < Vec < String > > ( ) ; 
265+ 
266+     if  !zulip_ids. is_empty ( )  { 
267+         zulip_ids. join ( ", " ) 
268+     }  else  { 
269+         "" . to_string ( ) 
270+     } 
271+ } 
272+ 
273+ /// Replace the placeholder "{team}" with the correct team name 
239274fn  replace_team_to_be_nominated ( labels :  & [ Label ] ,  msg :  String )  -> String  { 
240275    let  teams = labels
241276        . iter ( ) 
0 commit comments