@@ -22,6 +22,7 @@ pub struct Request {
2222
2323#[ derive( Debug , serde:: Deserialize ) ]
2424struct Message {
25+ id : u64 ,
2526 sender_id : u64 ,
2627 #[ allow( unused) ]
2728 recipient_id : u64 ,
@@ -188,6 +189,15 @@ fn handle_command<'a>(
188189 } )
189190 . unwrap ( ) ,
190191 } ,
192+ // @triagebot prio #12345 P-high
193+ Some ( "prio" ) => return match add_comment_to_issue ( & ctx, message_data, words, CommentType :: AssignIssuePriority ) . await {
194+ Ok ( r) => r,
195+ Err ( e) => serde_json:: to_string ( & Response {
196+ content : & format ! ( "Failed to await at this time: {:?}" , e) ,
197+ } )
198+ . unwrap ( ) ,
199+ } ,
200+
191201 _ => { }
192202 }
193203 }
@@ -203,6 +213,105 @@ fn handle_command<'a>(
203213 } )
204214}
205215
216+ #[ derive( PartialEq ) ]
217+ enum CommentType {
218+ AssignIssuePriority ,
219+ }
220+
221+ // https://docs.zulip.com/api/outgoing-webhooks#outgoing-webhook-format
222+ #[ derive( serde:: Deserialize , Debug ) ]
223+ struct ZulipReply {
224+ message : ZulipMessage ,
225+ }
226+
227+ #[ derive( serde:: Deserialize , Debug ) ]
228+ struct ZulipMessage {
229+ subject : String , // ex.: "[weekly] 2023-04-13"
230+ }
231+
232+ async fn get_zulip_msg ( ctx : & Context , id : u64 ) -> anyhow:: Result < ZulipReply > {
233+ let bot_api_token = env:: var ( "ZULIP_API_TOKEN" ) . expect ( "ZULIP_API_TOKEN" ) ;
234+ let zulip_resp = ctx
235+ . github
236+ . raw ( )
237+ . get ( format ! (
238+ "https://rust-lang.zulipchat.com/api/v1/messages/{}" ,
239+ id
240+ ) )
241+ . basic_auth ( BOT_EMAIL , Some ( & bot_api_token) )
242+ . send ( )
243+ . await ?;
244+
245+ let zulip_msg_data = zulip_resp. json :: < ZulipReply > ( ) . await . expect ( "TODO" ) ;
246+ log:: debug!( "Zulip reply {:?}" , zulip_msg_data) ;
247+ Ok ( zulip_msg_data)
248+ }
249+
250+ // Add a comment to a Github issue/pr issuing a @rustbot command
251+ async fn add_comment_to_issue (
252+ ctx : & Context ,
253+ message : & Message ,
254+ mut words : impl Iterator < Item = & str > + std:: fmt:: Debug ,
255+ ty : CommentType ,
256+ ) -> anyhow:: Result < String > {
257+ // retrieve the original Zulip message to build the complete URL
258+ let zulip_msg = get_zulip_msg ( ctx, message. id ) . await ?;
259+
260+ // comment example:
261+ // WG-prioritization assigning priority ([Zulip discussion](#)).
262+ // @rustbot label -I-prioritize +P-XXX
263+ let mut issue_id = 0 ;
264+ let mut comment = String :: new ( ) ;
265+ if ty == CommentType :: AssignIssuePriority {
266+ let zulip_stream = "245100-t-compiler/wg-prioritization/alerts" ;
267+ let mut zulip_msg_link = format ! (
268+ "https://rust-lang.zulipchat.com/#narrow/stream/{}/topic/{}/near/{}" ,
269+ zulip_stream, zulip_msg. message. subject, message. id
270+ ) ;
271+ // Encode url and replace "%" with "."
272+ // (apparently Zulip does that to public URLs)
273+ urlencoding:: encode ( & zulip_msg_link) ;
274+ zulip_msg_link = zulip_msg_link. replace ( "%" , "." ) ;
275+
276+ issue_id = words
277+ . next ( )
278+ . unwrap ( )
279+ . replace ( "#" , "" )
280+ . parse :: < u64 > ( )
281+ . unwrap ( ) ;
282+ let p_label = words. next ( ) . unwrap ( ) ;
283+
284+ comment = format ! (
285+ "WG-prioritization assigning priority ([Zulip discussion]({}))
286+ \n \n @rustbot label -I-prioritize +{}" ,
287+ zulip_msg_link, p_label
288+ ) ;
289+ }
290+ // else ... handle other comment type
291+
292+ let github_resp = ctx
293+ . octocrab
294+ . issues ( "owner" , "repo" )
295+ . create_comment ( issue_id. clone ( ) , comment. clone ( ) )
296+ . await ;
297+
298+ let _reply = match github_resp {
299+ Ok ( data) => data,
300+ Err ( e) => {
301+ return Ok ( serde_json:: to_string ( & Response {
302+ content : & format ! ( "Failed to post comment on Github: {:?}." , e) ,
303+ } )
304+ . unwrap ( ) ) ;
305+ }
306+ } ;
307+ log:: debug!( "Created comment on issue #{}: {:?}" , issue_id, comment) ;
308+
309+ Ok ( serde_json:: to_string ( & ResponseNotRequired {
310+ response_not_required : true ,
311+ } )
312+ . unwrap ( ) )
313+ }
314+
206315// This does two things:
207316// * execute the command for the other user
208317// * tell the user executed for that a command was run as them by the user
0 commit comments