@@ -176,8 +176,10 @@ public enum Status {
176176
177177 /**
178178 * Registered Event API handlers.
179+ * Note that only limited set of events allow having multiple handlers.
180+ * As of v1.27.1, only MessageEvent.class ones can be multiple.
179181 */
180- private final Map <String , BoltEventHandler <Event >> eventHandlers = new HashMap <>();
182+ private final Map <String , List < BoltEventHandler <Event > >> eventHandlers = new HashMap <>();
181183
182184 /**
183185 * Primitive Event API handler.
@@ -612,15 +614,32 @@ public App use(Middleware middleware) {
612614 // Events API
613615 // https://api.slack.com/events-api
614616
615- public <E extends Event > App event (Class <E > eventClass , BoltEventHandler <E > handler ) {
617+ public <E extends Event > App event (
618+ Class <E > eventClass ,BoltEventHandler <E > handler ) {
619+ // Note that having multiple handlers is allowed only for message event handlers.
620+ // If we revisit this to unlock the option to all event types, it should work well.
621+ // We didn't decide to do so in 2022 in respect of better backward compatibility.
622+ boolean allowMultipleEventHandlers = getEventTypeAndSubtype (eventClass ) == MessageEvent .TYPE_NAME ;
623+ return event (eventClass , allowMultipleEventHandlers , handler );
624+ }
625+
626+ protected <E extends Event > App event (
627+ Class <E > eventClass ,
628+ boolean allowMultipleEventHandlers ,
629+ BoltEventHandler <E > handler ) {
616630 String eventTypeAndSubtype = getEventTypeAndSubtype (eventClass );
617631 if (eventTypeAndSubtype == null ) {
618632 throw new IllegalArgumentException ("Unexpectedly failed to register the handler" );
619633 }
620- if (eventHandlers .get (eventTypeAndSubtype ) != null ) {
634+ List <BoltEventHandler <Event >> handlers = eventHandlers .get (eventTypeAndSubtype );
635+ if (handlers == null ) {
636+ handlers = new ArrayList <>();
637+ } else if (!allowMultipleEventHandlers ) {
621638 log .warn ("Replaced the handler for {}" , eventTypeAndSubtype );
639+ handlers = new ArrayList <>();
622640 }
623- eventHandlers .put (eventTypeAndSubtype , (BoltEventHandler <Event >) handler );
641+ handlers .add ((BoltEventHandler <Event >) handler );
642+ eventHandlers .put (eventTypeAndSubtype , handlers );
624643 return this ;
625644 }
626645
@@ -634,15 +653,15 @@ public App message(String pattern, BoltEventHandler<MessageEvent> messageHandler
634653 }
635654
636655 public App message (Pattern pattern , BoltEventHandler <MessageEvent > messageHandler ) {
637- event (MessageEvent .class , (event , ctx ) -> {
656+ event (MessageEvent .class , true , (event , ctx ) -> {
638657 String text = event .getEvent ().getText ();
639658 if (log .isDebugEnabled ()) {
640659 log .debug ("Run a message event handler (pattern: {}, text: {})" , pattern , text );
641660 }
642661 if (text != null && pattern .matcher (text ).matches ()) {
643662 return messageHandler .apply (event , ctx );
644663 } else {
645- return ctx . ack () ;
664+ return null ;
646665 }
647666 });
648667 return this ;
@@ -1103,10 +1122,15 @@ protected Response runHandler(Request slackRequest) throws IOException, SlackApi
11031122 return Response .ok ();
11041123 }
11051124 EventRequest request = (EventRequest ) slackRequest ;
1106- BoltEventHandler <Event > handler = eventHandlers .get (request .getEventTypeAndSubtype ());
1107- if (handler != null ) {
1108- EventsApiPayload <Event > payload = buildEventPayload (request );
1109- return handler .apply (payload , request .getContext ());
1125+ List <BoltEventHandler <Event >> handlers = eventHandlers .get (request .getEventTypeAndSubtype ());
1126+ if (handlers != null ) {
1127+ for (BoltEventHandler <Event > handler : handlers ) {
1128+ EventsApiPayload <Event > payload = buildEventPayload (request );
1129+ Response result = handler .apply (payload , request .getContext ());
1130+ if (result != null && result .getStatusCode () == 200 ) {
1131+ return result ;
1132+ }
1133+ }
11101134 }
11111135 if (config ().isAllEventsApiAutoAckEnabled ()) {
11121136 // If the flag is true, Bolt acknowledges all the events anyway
@@ -1346,10 +1370,15 @@ protected Response runHandler(Request slackRequest) throws IOException, SlackApi
13461370 return Response .ok ();
13471371 }
13481372 EventRequest request = new EventRequest (stepRequest .getRequestBodyAsString (), stepRequest .getHeaders ());
1349- BoltEventHandler <Event > handler = eventHandlers .get (request .getEventTypeAndSubtype ());
1350- if (handler != null ) {
1351- EventsApiPayload <Event > payload = buildEventPayload (request );
1352- return handler .apply (payload , request .getContext ());
1373+ List <BoltEventHandler <Event >> handlers = eventHandlers .get (request .getEventTypeAndSubtype ());
1374+ if (handlers != null ) {
1375+ for (BoltEventHandler <Event > handler : handlers ) {
1376+ EventsApiPayload <Event > payload = buildEventPayload (request );
1377+ Response result = handler .apply (payload , request .getContext ());
1378+ if (result != null && result .getStatusCode () == 200 ) {
1379+ return result ;
1380+ }
1381+ }
13531382 }
13541383 log .warn ("No BoltEventHandler registered for event: {}\n {}" ,
13551384 request .getEventTypeAndSubtype (), ListenerCodeSuggestion .WORKFLOW_STEP );
0 commit comments