0
votes

I was hosting a simple slack slash command on heroku which worked fine. I moved it to lambda, but now it is getting:

Darn - that slash command didn't work (error message: `400_client_error`). Manage the command at ????.

The error doesn't provide more information and doesn't say what failed.

I can hit the endpoint with curl and it returns what looks to me like correctly formatted json:

curl -X POST \
  https://5hi90e8v8e.execute-api.us-east-2.amazonaws.com/Prod \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: eacb33ee-96ac-457e-a325-9fdc132f808e' \
  -H 'cache-control: no-cache'
{
    "text": "Have suggestions to improve this bot? Message <@UC8R7PA87>",
    "response_type": "in_channel"
}

Headers:

Date →Sat, 09 Mar 2019 01:12:02 GMT
Content-Type →application/json
Content-Length →922
Connection →keep-alive
x-amzn-RequestId →57cec19a-4208-11e9-924c-89367de80c6d
x-amz-apigw-id →WP_jLFWYiYcFiXg=
X-Amzn-Trace-Id →Root=1-5c8312e1-327ac177db85f799dcd267c1;Sampled=0

The response from my old heroku endpoint:

{
    "response_type": "in_channel",
    "text": "Have suggestions to improve this bot? Message <@UC8R7PA87>"
}

Headers:

Connection →keep-alive
Server →gunicorn/19.6.0
Date →Sat, 09 Mar 2019 01:01:36 GMT
Content-Type →application/json
Content-Length →946
Via →1.1 vegur

Any ideas on how to find the actual error / how to debug?

2

2 Answers

4
votes

Update: Easy solution would be to use API Gateway Lambda Proxy Integrations, which moves the heavy lifting from the API Gateway to the Lambda function: Understand API Gateway Lambda Proxy Integration


Lambda is always going to expect to receive data from an API Gateway as JSON, and there are cases where the data being sent to the API isn’t JSON. That’s the case with slash commands coming from Slack. They make POST requests with an application/x-www-form-urlencoded Content-Type, so the body of the request looks something like:

token=gIkuvaNzQIHg97ATvDxqgjtO&command=/weather&text=lorem

In API Gateway, the Mapping Templates section of the Integration Request, you have to add a template for the Content-Type of the request we are expecting. In this case it’s application/x-www-form-urlencoded.

You can simply wrap the request body as-is in a JSON object, so that we can get the value to Lambda for parsing.

{
  "postBody" : $input.json("$")
}

This info was taken from https://medium.com/@farski/learn-aws-api-gateway-with-the-slack-police-ca8d636e9fc0

1
votes

Probably, problem in AWS Gateway and how it transform request. Try to use:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  }
}

in Integration Request/Mapping Templates/application/json for debug.