Slack Slash commands返回operation_timeout错误但任务正常执行如何解决
问题根源
你对Slack的响应要求理解存在偏差。Slack要求的3秒内返回的200 OK,是Slack向你的Lambda发起请求后,Lambda直接返回给Slack的原生HTTP响应,并非你调用response_url主动发起的POST消息。
你当前的代码逻辑中,整个Lambda函数需要等待所有任务(包括你用来复现问题的5秒sleep)执行完成后,才会向Slack返回响应,总耗时超过Slack的3秒硬限制,自然会触发operation_timeout报错。你之前写的slack_acknowledgment_response函数只是用来向用户推送后续消息的,完全起不到请求确认的作用。
解决方案
核心逻辑是:当前接收Slack请求的Lambda只做参数解析和任务分发,立刻返回200响应给Slack,所有耗时任务交给异步单元处理,不要阻塞主请求的返回。
推荐两种落地方式:
方式1:通过SQS队列异步解耦(最稳妥)
新增一个SQS队列和对应的任务处理Lambda,主Lambda只负责接收Slack请求、把参数投递到SQS、立刻返回200,耗时逻辑全部放到任务处理Lambda中执行。
示例代码如下:
import json import time import boto3 import requests from urllib.parse import parse_qs # 初始化SQS客户端,替换为你自己的SQS队列URL sqs = boto3.client('sqs') SQS_QUEUE_URL = "https://sqs.<区域>.amazonaws.com/<账号ID>/<队列名>" # 接收Slack请求的主Lambda def main(event, context): payload = parse_qs(event['postBody']) response_url = payload['response_url'][0] # 把任务参数投递到SQS sqs.send_message( QueueUrl=SQS_QUEUE_URL, MessageBody=json.dumps({ "response_url": response_url, "payload": payload }) ) # 立刻给Slack返回200确认,这才是Slack要求的响应 return { "statusCode": 200, "body": "" } # 处理SQS消息的任务Lambda,独立执行耗时逻辑 def process_slack_task(event, context): for record in event['Records']: task_params = json.loads(record['body']) response_url = task_params['response_url'] # 这里执行你的耗时任务逻辑 time.sleep(5) # 任务执行完成后调用response_url推送结果给用户 requests.post( response_url, json={"text": "任务执行完成"} )
方式2:异步调用Lambda(无需新增额外服务)
如果不想新增SQS队列,可以在主Lambda中异步调用自身处理耗时任务,主逻辑依然直接返回200即可。需要注意给Lambda配置对应的调用权限。
注意事项
- Slack的3秒超时是不可修改的硬限制,所有接收Slack交互请求的服务必须在3秒内返回HTTP 200响应
response_url的有效期是30分钟,只要在这个窗口内推送执行结果都可以正常展示给用户
内容的提问来源于stack exchange,提问作者Mervin Hemaraju
相关产品推荐
相关产品推荐

