如何避免松弛命令超时错误?

Vik*_*ini 24 python slack-api slack

我正在使用slack命令(python代码在此后运行),它工作正常,但这给出了错误

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

怎么避免这个?

rco*_*oup 37

根据Slack 斜杠命令文档,您需要在3000毫秒(3秒)内响应.如果您的命令需要更长时间,则会Timeout was reached出现错误.您的代码显然不会停止运行,但用户将无法获得对其命令的任何响应.

如果您的命令可以即时访问数据,那么三秒钟就可以快速完成,但如果您正在调用外部API或执行复杂操作,则可能不够长.如果确实需要更长时间,请参阅文档的延迟响应和多个响应部分:

  1. 验证请求是否正常.
  2. 200马上回复一个回复,也许就是回事{'text': 'ok, got that'}
  3. 去执行您想要执行的实际操作.
  4. 在原始请求中,您将传递一个唯一response_url参数.做一个POST与你的后续消息网址:
    • Content-type 需要是 application/json
    • 将正文作为JSON编码的消息: {'text': 'all done :)'}
    • 您可以返回短暂或通道内响应,并添加与即时方法相同的附件

根据文档,"您可以在用户调用的30分钟内响应用户最多5次命令".


小智 9

在我自己处理这个问题并将我的Flask应用程序托管在Heroku之后,我发现最简单的解决方案是使用线程.我按照这里的例子: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")  
Run Code Online (Sandbox Code Playgroud)

所有缓慢繁重的工作都由该backgroundworker()功能执行.我的松弛命令指向https://myappaddress.com/appmethodaddress的其中receptionist()函数采用response_url接收到的时差信息的,并将其传递沿着任何其它任选的数据到backgroundworker().由于该过程现在被拆分,它只是立即将"working on your request"消息返回到Slack通道,并在完成后backgroundworker()发送第二条消息"your task is complete".


non*_*ing 8

我也经常遇到这个错误:

"Darn - 斜杠命令不起作用(错误消息:) Timeout was reached.在slash-command管理命令"

在AWS Lambda上编写了Slack slash-command"bot",有时需要执行慢速操作(调用其他外部API等).在某些情况下,Lambda函数需要大于3秒的时间才会导致Timeout was reachedSlack出错.

我在这里找到了@ rcoup的优秀答案,并将其应用于AWS Lambda的上下文中.该错误不再出现.

我用两个独立的Lambda函数做到了这一点.一个是"调度员"或"接待员",它用"200 OK"迎接传入的Slack斜杠命令,并向用户返回简单的"Ok,got that"类型的消息.另一个是实际的"worker"Lambda函数,它以异步方式启动long-ish操作,并在response_url稍后将该操作的结果发布到Slack .

这是调度员/接待员Lambda函数:

def lambda_handler(event, context):
    req_body = event['body']

    try:
        retval = {}

        # the param_map contains the 'response_url' that the worker will need to post back to later
        param_map = _formparams_to_dict(req_body)
        # command_list is a sequence of strings in the slash command such as "slashcommand weather pune"
        command_list = param_map['text'].split('+')

        # publish SNS message to delegate the actual work to worker lambda function
        message = {
            "param_map": param_map,
            "command_list": command_list
        }

        sns_response = sns_client.publish(
            TopicArn=MY_SNS_TOPIC_ARN,
            Message=json.dumps({'default': json.dumps(message)}),
            MessageStructure='json'
        )

        retval['text'] = "Ok, working on your slash command ..."
    except Exception as e:
        retval['text'] = '[ERROR] {}'.format(str(e))

    return retval


def _formparams_to_dict(req_body):
    """ Converts the incoming form_params from Slack into a dictionary. """
    retval = {}
    for val in req_body.split('&'):
        k, v = val.split('=')
        retval[k] = v
    return retval
Run Code Online (Sandbox Code Playgroud)

从上面可以看出,我没有直接从调度程序调用worker Lambda Function(尽管这是可能的).我选择使用AWS SNS发布工作人员接收和处理的消息.

基于此StackOverflow答案,这是更好的方法,因为它是非阻塞(异步)和可伸缩的.此外,使用SNS在AWS Lambda的上下文中分离这两个函数更容易,直接调用对于此用例来说更为棘手.

最后,这是我在工作人员Lambda函数中使用SNS事件的方法:

def lambda_handler(event, context):
    message = json.loads(event['Records'][0]['Sns']['Message'])
    param_map = message['param_map']
    response_url = param_map['response_url']

    command_list = message['command_list']
    main_command = command_list[0].lower()

    # process the command as you need to and finally post results to `response_url`
Run Code Online (Sandbox Code Playgroud)

  • 像这里提到的那样在“调度员”和“工人”Lambda 函数之间拆分工作是一个不错的设计选择。但是,在我遇到的一种情况下,“调度程序”使用了 3 秒以上,我无法从中删除更多代码(由于 AWS SSM 中的外部资源而导致延迟)。我对此的解决方案是简单地增加调度程序功能的内存,因为在 Lambda 中,CPU 性能与内存设置有关。 (2认同)