@@ -177,14 +177,15 @@ async fn process_zulip_request(ctx: Arc<Context>, req: Request) -> anyhow::Resul
177177async fn handle_command < ' a > (
178178 ctx : Arc < Context > ,
179179 mut gh_id : u64 ,
180- command : & ' a str ,
180+ message : & ' a str ,
181181 message_data : & ' a Message ,
182182) -> anyhow:: Result < Option < String > > {
183- log:: trace!( "handling zulip command {:?}" , command) ;
184- let mut words: Vec < & str > = command. split_whitespace ( ) . collect ( ) ;
183+ log:: trace!( "handling zulip message {:?}" , message) ;
185184
186185 // Missing stream means that this is a direct message
187186 if message_data. stream_id . is_none ( ) {
187+ let mut words: Vec < & str > = message. split_whitespace ( ) . collect ( ) ;
188+
188189 // Handle impersonation
189190 let mut impersonated = false ;
190191 #[ expect( clippy:: get_first, reason = "for symmetry with `get(1)`" ) ]
@@ -252,7 +253,7 @@ async fn handle_command<'a>(
252253
253254 let sender = & message_data. sender_full_name ;
254255 let message = format ! (
255- "{sender} ran `{command }` on your behalf. Output:\n {}" ,
256+ "{sender} ran `{message }` on your behalf. Output:\n {}" ,
256257 output. as_deref( ) . unwrap_or( "<empty>" )
257258 ) ;
258259
@@ -270,33 +271,47 @@ async fn handle_command<'a>(
270271 Ok ( output)
271272 } else {
272273 // We are in a stream, where someone wrote `@**triagebot** <command(s)>`
273- let cmd_index = words
274- . iter ( )
275- . position ( |w| * w == "@**triagebot**" )
276- . unwrap_or ( words. len ( ) ) ;
277- let cmd_index = cmd_index + 1 ;
278- if cmd_index >= words. len ( ) {
279- return Ok ( Some ( "Unknown command" . to_string ( ) ) ) ;
280- }
274+ //
275+ // Yet we need to process each lines separately as the command can only be
276+ // one line.
277+ for line in message. lines ( ) {
278+ let words: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
279+
280+ // Try to find the ping, continue to the next line if we don't find it here.
281+ let Some ( cmd_index) = words. iter ( ) . position ( |w| * w == "@**triagebot**" ) else {
282+ continue ;
283+ } ;
281284
282- let cmd = parse_cli :: < StreamCommand , _ > ( words[ cmd_index..] . iter ( ) . copied ( ) ) ?;
283- tracing:: info!( "command parsed to {cmd:?}" ) ;
285+ let cmd = parse_cli :: < StreamCommand , _ > ( words[ cmd_index..] . iter ( ) . copied ( ) ) ?;
286+ tracing:: info!( "command parsed to {cmd:?}" ) ;
284287
285- match cmd {
286- StreamCommand :: EndTopic => post_waiter ( & ctx, message_data, WaitingMessage :: end_topic ( ) )
287- . await
288- . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) ) ,
289- StreamCommand :: EndMeeting => {
290- post_waiter ( & ctx, message_data, WaitingMessage :: end_meeting ( ) )
291- . await
292- . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) )
293- }
294- StreamCommand :: Read => post_waiter ( & ctx, message_data, WaitingMessage :: start_reading ( ) )
295- . await
296- . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) ) ,
297- StreamCommand :: PingGoals ( args) => ping_goals_cmd ( ctx, gh_id, message_data, & args) . await ,
298- StreamCommand :: DocsUpdate => trigger_docs_update ( message_data, & ctx. zulip ) ,
288+ // Process the command and early return (we don't expect multi-commands in the
289+ // same message)
290+ return match cmd {
291+ StreamCommand :: EndTopic => {
292+ post_waiter ( & ctx, message_data, WaitingMessage :: end_topic ( ) )
293+ . await
294+ . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) )
295+ }
296+ StreamCommand :: EndMeeting => {
297+ post_waiter ( & ctx, message_data, WaitingMessage :: end_meeting ( ) )
298+ . await
299+ . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) )
300+ }
301+ StreamCommand :: Read => {
302+ post_waiter ( & ctx, message_data, WaitingMessage :: start_reading ( ) )
303+ . await
304+ . map_err ( |e| format_err ! ( "Failed to await at this time: {e:?}" ) )
305+ }
306+ StreamCommand :: PingGoals ( args) => {
307+ ping_goals_cmd ( ctx, gh_id, message_data, & args) . await
308+ }
309+ StreamCommand :: DocsUpdate => trigger_docs_update ( message_data, & ctx. zulip ) ,
310+ } ;
299311 }
312+
313+ tracing:: warn!( "no command found, yet we were pinged, weird" ) ;
314+ Ok ( Some ( "Unknown command" . to_string ( ) ) )
300315 }
301316}
302317
0 commit comments