slackapi / bolt-python

A framework to build Slack apps using Python

Home Page:https://slack.dev/bolt-python/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Avoid duplicate messages on app_mention event

NirmalVatsyayan opened this issue · comments

Whenever a message processing take more than a certain time, i am receiving duplicate events for app_mention.

Reproducible in:

The slack_bolt version

    slack-sdk==3.26.1
    slack-bolt==1.18.1

Python runtime version

        Python 3.11.6

OS info

 ProductName:            macOS
 ProductVersion:         13.5
 BuildVersion:           22G74
 Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:52 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T8103

Steps to reproduce:

import uvicorn
from slack_bolt.app import App
from slack_bolt.authorization import AuthorizeResult
from slack_bolt.adapter.fastapi import SlackRequestHandler

from fastapi import FastAPI

def authorize(enterprise_id, team_id, user_id, client: WebClient, logger):
    token = "bot-token"
    
    return AuthorizeResult.from_auth_test_response(
        auth_test_response=client.auth_test(token=token),
        bot_token=token
    )

app = FastAPI()
bolt_app = App(process_before_response=True, signing_secret="signing-secret", authorize=authorize)
app_handler = SlackRequestHandler(bolt_app)

@bolt_app.event("app_mention")
def handle_app_mention(body, say, ack):
    ack()
    print("message body: ", body)

    # Extract relevant information from the event payload
    event = body["event"]
    channel_id = event["channel"]
    thread_ts = event["ts"]  # Timestamp of the original message
    text = event["text"]

    say(text=response_text_1, channel=channel_id, thread_ts=thread_ts)
    time.sleep(10) #assuming this is the processing time
    say(text=response_text_2, channel=channel_id, thread_ts=thread_ts)


@app.post("/slack/events")
async def endpoint(req: Request):
    return await app_handler.handle(req)


if __name__ == "__main__":
    uvicorn.main(["main:app", "--host", "127.0.0.1", "--port", "3000"])

Expected result:

Always avoid duplicate message

Actual result:

API call happening multiple times for same event and message

Hey @NirmalVatsyayan 👋 It sounds like automatic retries might be happening due to a delayed ack response even though your function is still running!

It does seem like you're calling ack right away, but with process_before_response being True this timeout might still be happening because the response is being delayed. I think "lazy listeners" might be useful for exactly this though!

The docs have an example of setting this up and I think sending the ack response before continuing the long running process might be helpful here. Please let me know if you give this a try, whether it works or not, or have other questions!

FWIW I've also found "duplicate" events can be common if I forget to start my app while developing. Then a flood of events comes all at once, over some period of time! I don't think this is exactly the problem you're seeing, but just wanted to give ya a heads up 😉

Thanks, let me revert after testing with changes.

👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.

As this issue has been inactive for more than one month, we will be closing it. Thank you to all the participants! If you would like to raise a related issue, please create a new issue which includes your specific details and references this issue number.