Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid slack command timeout error?

I am working with slack command (python code is running behind this), it works fine, but this gives error

This slash command experienced a problem: 'Timeout was reached' (error detail provided only to team owning command).

How to avoid this ?

like image 783
Vikas Saini Avatar asked Jan 20 '16 10:01

Vikas Saini


People also ask

How do you increase Slack timeout?

It is not possible to increase the default timeout from Slack to slash commands. It's always 3 seconds. But it's possible to send a delayed response for up to 30 minutes. For that you need to first respond within 3 secs to acknowledge the initial request by sending back a HTTP 200 OK.

How do I run a command in Slack?

Slack has a lot of built-in slash commands that act as shortcuts for specific actions in Slack. You simply need to type the slash key (/) then followed by some keywords in any Slack channel or direct message to trigger specific actions in Slack (e.g. type /away to mark your status to “away” quickly).


2 Answers

According to the Slack slash command documentation, you need to respond within 3000ms (three seconds). If your command takes longer then you get the Timeout was reached error. Your code obviously won't stop running, but the user won't get any response to their command.

Three seconds is fine for a quick thing where your command has instant access to data, but might not be long enough if you're calling out to external APIs or doing something complicated. If you do need to take longer, then see the Delayed responses and multiple responses section of the documentation:

  1. Validate the request is okay.
  2. Return a 200 response immediately, maybe something along the lines of {'text': 'ok, got that'}
  3. Go and perform the actual action you want to do.
  4. In the original request, you get passed a unique response_url parameter. Make a POST request to that URL with your follow-up message:
    • Content-type needs to be application/json
    • With the body as a JSON-encoded message: {'text': 'all done :)'}
    • you can return ephemeral or in-channel responses, and add attachments the same as the immediate approach

According to the docs, "you can respond to a user commands up to 5 times within 30 minutes of the user's invocation".

like image 113
rcoup Avatar answered Oct 14 '22 14:10

rcoup


After dealing with this issue myself and having my Flask app hosted on Heroku I found that the simplest solution was to use threading. I followed the example from here: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xi-email-support

from threading import Thread  def backgroundworker(somedata,response_url):      # your task      payload = {"text":"your task is complete",                 "username": "bot"}      requests.post(response_url,data=json.dumps(payload))      @app.route('/appmethodaddress',methods=['POST','GET']) def receptionist():      response_url = request.form.get("response_url")      somedata = {}      thr = Thread(target=backgroundworker, args=[somedata,response_url])     thr.start()      return jsonify(message= "working on your request")   

All the slow heavy work is performed by the backgroundworker() function. My slack command points to https://myappaddress.com/appmethodaddress where the receptionist() function takes the response_url of the received Slack message and passes it alongside any other optional data to the backgroundworker(). As the process is now split it simply returns the "working on your request" message to your Slack channel pretty much instantly and upon completion backgroundworker() sends the second message "your task is complete".

like image 27
dom Avatar answered Oct 14 '22 15:10

dom