@@ -22,6 +22,7 @@ pub struct Request {
22
22
23
23
#[ derive( Debug , serde:: Deserialize ) ]
24
24
struct Message {
25
+ id : u64 ,
25
26
sender_id : u64 ,
26
27
#[ allow( unused) ]
27
28
recipient_id : u64 ,
@@ -188,6 +189,15 @@ fn handle_command<'a>(
188
189
} )
189
190
. unwrap ( ) ,
190
191
} ,
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
+
191
201
_ => { }
192
202
}
193
203
}
@@ -203,6 +213,105 @@ fn handle_command<'a>(
203
213
} )
204
214
}
205
215
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
+
206
315
// This does two things:
207
316
// * execute the command for the other user
208
317
// * tell the user executed for that a command was run as them by the user
0 commit comments