slackapi / bolt-js

A framework to build Slack apps using JavaScript
https://tools.slack.dev/bolt-js/
MIT License
2.74k stars 393 forks source link

Hello! I'm getting this error as well. I expressly `ack` the slash command right at the beginning of the handler. #1727

Closed asontha closed 1 year ago

asontha commented 1 year ago

Hello! I'm getting this error as well. I expressly ack the slash command right at the beginning of the handler.

// The /ask command entry point.
app.command('/ask', async ({ command, ack, client, logger }) => {

  // Acknowledge shortcut request
  await ack();
image

Originally posted by @asontha in https://github.com/slackapi/bolt-js/issues/1435#issuecomment-1406819093

mwbrooks commented 1 year ago

Hi @asontha 👋🏻 Thanks for reaching out!

The operation_timeout error is typically returned if the app hasn't acknowledged the slash command request after 3 seconds. Since you're correctly using await ack();, I think you should double-check that your app is receiving the slash command request.

Can you try to add a log message before your await ack(); to confirm that the slash command request is hitting your command function?

asontha commented 1 year ago

I am receiving the slash command as my app is replying as expected to the slash command (look at app message posted before the Slackbot error). The behavior is to immediately reply to the command saying that we'll get the answer, and then replying with the answer as a threaded response.

asontha commented 1 year ago

Here's the flow of /ask

User: /ask <QUESTION> BOT: @User asked: <QUESTION> Let me get you the answer for that! I'll reply to this message :smile: BOT (in thread): <ANSWER>

asontha commented 1 year ago

Here is proof that Slack is not waiting 3 seconds for timeout

image image
asontha commented 1 year ago

Here's how I've configured my receiver

// Initialize your custom receiver
const awsLambdaReceiver = new AwsLambdaReceiver({
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// Initializes your app with your bot token and signing secret
const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  receiver: awsLambdaReceiver
});
asontha commented 1 year ago

Another example

image image
seratch commented 1 year ago

This behavior can happen when lambda runtime initialization + your listener takes more than 3 seconds. The say() method call and whatever you do in the function can be successful like you observed. However, ack() can fail as the response is sent at the end.

asontha commented 1 year ago

So then if you guys are pushing everyone to use AWS Lambda for deployment but the deployment platform itself can't support it, doesn't it make sense to increase the timeout value to something more reasonable?

seratch commented 1 year ago

@asontha I do understand your frustration on this and we hear you. This seems to be an issue on our documentation side. The getting started guide and other resources should clearly mention the things developers need to be aware of.

As for utilizing AWS Lambda for Slack apps, we believe that the platform is a great option to run those apps in terms of const efficiency and easiness of operations. I myself run many of my personal Slack apps on AWS Lambda. So, it's still recommended but our documents should be improved. Sorry about the confusion you encountered.

I believe that everything is clear (I know the cause is not great for you, though). If you have further questions on this, please feel free to write in. Otherwise, let us close this issue now.

asontha commented 1 year ago

Given this problem is such a massive and reoccurring one, could you guys create a fully fleshed out example of how the solution proposed here would work?

https://github.com/slackapi/bolt-js/issues/914#issuecomment-870079306

seratch commented 1 year ago

Thanks for the suggestion! I've created a new issue for it: https://github.com/slackapi/bolt-js/issues/1728 Let us close this issue now but please feel free to write in whenever you have more to ask.

Timendainum commented 1 year ago

This is not a documentation issue, the length of the timeout is too short. Slack fix this, something is broken on your side.

I get my response back BEFORE your timeout error gets here.

Please fix this.

acerbisgianluca commented 1 year ago

Hi @seratch, thanks for the clarification. Just to be sure, if await ack() is the first call of an handler, the response will still be sent back to Slack when all the other work inside the handler is done, is it correct? What is the recommended solution if the work between await ack() and the end of the handler takes more than 3 seconds?

PS: I'm talking about AWS Lambda

filmaj commented 1 year ago

@Timendainum this is an intentional design decision. The timeout is short so that the user experience within the Slack client is relatively responsive to Slack client user interactivity.

@acerbisgianluca since the HTTP request from Slack is tied to the lifecycle of the AWS Lambda execution, immediately responding to the HTTP request would effectively terminate the Lambda. Therefore, the acknowledgement to the request from Slack is done as a final step in the Lambda execution. This is limitation of HTTP request integrations with AWS Lambda. However, there are many well-documented ways to work around this limitation, and in fact, make your application more resilient as a result. I would recommend to employ event-driven programming best practices, which are a necessity in a cloud environment and particularly in a function-as-as-service architecture. I highly suggest familiarizing yourself with techniques such as:

SNS is generally sufficient for most use cases. Hope this helps!

acerbisgianluca commented 1 year ago

Hey @filmaj, thanks for the detailed reply! I will start exploring the first solution.