JasonGenX
JasonGenX

Reputation: 5434

Slack blocks + sending response doesn't work in python, not even when async - only in CURL

I don't get why slack rejects the posted return message with 404 when the very same response_url works when used in curl outside of python.

my webhook processor:

def slack_webhook(request):
    json_dict = json.loads(request.body.decode('utf-8'))
    token = json_dict['token'] if 'token' in json_dict else None
    message = json_dict['message'] if 'message' in json_dict else None
    trigger_id = json_dict['trigger_id'] if 'trigger_id' in json_dict else None
    response_url = json_dict['response_url'] if 'response_url' in json_dict else None
    actions = json_dict['actions'] if 'actions' in json_dict else None

    for action in actions:
        print(f"** received action {action['action_id']}")
        print(f"** response_url: {response_url}")
        print(f"** trigger_id: {trigger_id}")

        payload = {
            "replace_original": True,
            "text": "Success!",
        }

        # async via Celery...
        send_slack_interactive_response.delay(response_url, payload, trigger_id)
        
        return HttpResponse(status=200) 

the async celery task which sends the

@app.task(bind=True, retry_kwargs={'max_retries': 10, 'countdown': 5})
def send_slack_interactive_response(self, response_url, payload, trigger_id):

    print(f"**  -> response_url: {response_url}")
    print(f"** -> trigger_id: {trigger_id}")

    if response_url and payload and trigger_id:
        headers = {"Content-Type": "application/json"}
        payload['trigger_id'] = trigger_id
        print(json.dumps(payload))
        r = requests.post(response_url, data=payload, headers=headers)
        print(r.__dict__)

This function fails with 404. however, when i take the response_url, trigger_id and create the exact same POST with command line curl - it works.

What am I doing wrong?

Upvotes: 0

Views: 965

Answers (1)

MaximeK
MaximeK

Reputation: 2061

Just a comment on your code : You can do token = json_dict.get("token", None) that save you lot of code

On your problem :

  1. Be sure Celery parameters is not weird encoded (response_url is send to messagerie and is encoded)
  2. Be sure request parameters are well used (like using json instead of data...)

Upvotes: 2

Related Questions