question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Req: Support matching multiple message events

See original GitHub issue

If a message contains multiple matches, it seems that Bolt will only call the first message handler that matches, and then stop processing the message event.

I would like to see Bolt have a way to continue handling other message events.

Category

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components

Example

    @app.message("ping")
    async def message_ping(self, message: Dict, say: AsyncSay):
        await say("Pong!")

    @app.message("pong")
    async def message_pong(self, message: Dict, say: AsyncSay):
        await say("Ping!")

If I send the message Testing ping pong responders, I expect Bolt to respond twice, saying both Pong! and Ping!, but it only returns Pong!

This is a silly example meant to demonstrate the issue, but there are real-world use cases where a message can contain multiple “triggers” that should all be processed by the app.

I’m thinking that this could be implemented like middleware, where message handlers could (optionally) call next() to have Bolt continue processing other message handlers.

(Unfortunately this is a blocking issue for me, so if you have any ideas on how to work around it, I’m open to suggestions!)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
seratchcommented, Feb 15, 2021

Can you provide any context about this comment?

The second line in the comment was a bit unclear. I just updated the line. The reason why there are two patterns is Slack app’s permission model migration: https://api.slack.com/authentication/token-types#bot

Messages posted by most apps with the current permission model don’t have the subtype. On the other hand, messages by “classic” apps always have the subtype. Other apps in a workspace may send a message with the subtype.

If I want to ignore any events from a “bot”, is there an easy way to look at the is_bot field in the authorizations section of the Events metadata? Would it be possible to use global middleware to just “skip” all events where is_bot is True?

The is_bot flag under authorizations is not suitable for the purpose. The flag tells whether an event is a bot event. Here is a screenshot of Slack app configuration page: Most apps utilize bot events to receive notifications from Slack. In this case, is_bot is always true. If an event is the one on behalf of users, the field is false.

If you want to have a global middleware that does the same with the listener matcher I shared above, the code can be like this:

from slack_bolt import BoltResponse

@app.middleware
def skip_bot_message_events(body, logger, next):
    event = body.get("event", {})
    is_message_event = event.get("type") == "message"
    is_bot_message = event.get("subtype") is None and event.get("bot_id") is not None
    is_classic_bot_message = event.get("subtype") == "bot_message"
    if is_message_event and (is_bot_message or is_classic_bot_message):
        # just acknowledge the request
        logger.debug("Skipped a message from a bot user")
        return BoltResponse(status=200, body="")
    # continue processing
    next()
1reaction
seratchcommented, Feb 14, 2021

I do not know about your app but probably the approach may work well.

One thing I can suggest is that your app may want to filter subtypes this way:

@app.event({"type": "message", "subtype": (None, "bot_message")})
def handle_only_new_messages(event):
    your_own_message_processor.handle(event)

@app.event("message")
def acknowledge_other_message_subtypes():
    # just for acknowledging other subtypes
    pass

The handle_only_new_messages handler matches only newly posted messages. If you want to handle others as well, you can add more subtypes to the tuple in the constraints. See https://api.slack.com/events/message#message-event-type__message-subtypes for the list of available subtypes.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple events matching algorithm - Stack Overflow
Example: We have several events with different types and properties. Type SEEN is cumulative event (several events could be merged for matching) and...
Read more >
Messages, events and commands • NServiceBus • Particular ...
"Events can have multiple recipient so they should be published." - this exception will occur when attempting to use 'Send()' to send an...
Read more >
Modeling message events - IBM
Message events can be used to enable roll-forward scenarios in which the same message needs to be passed through multiple steps until it...
Read more >
RFC 3265 SIP-Specific Event Notification - IETF
Introduction The ability to request asynchronous notification of events proves ... MUST match the "Event" header in the corresponding SUBSCRIBE message.
Read more >
How-To: Route messages to different event handlers
Learn how to route messages from a topic to different event handlers based on CloudEvent fields.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found