Search code examples
validationaws-lambdatwiliowebhooks

Unable to validate Twilio incoming SMS webhook with AWS lambda


I'm trying to integrate my app with Twilio for SMS service. I would like to get notified each time there is an incoming SMS message.

Here is what I did

1- I define a lambda and ApiGateway with proxy integration

2- I added the endpoint url to the webhook settings in Twilio console

Once I send an SMS to the Twilio number the lambda is indeed triggered and I'm able to process the message.

However, When I try to use the Twilio validator in order to validate the even I keep getting that the event is invalid

Here is the code snippet handling the validation for post reqeust

validator = RequestValidator(<'auth token'>)
post_body_dict  = {key: value[0] for key, value in parse_qs(body).items()}
url = <'url as defined in Twilio's console'>
sig = event['headers'].get("X-Twilio-Signature")
is_valid = validator.validate(url, params, sig)

Notes

1 - The body of the request arrives as a string of query params even though it's a POST request (param1=val1&param2=val2...)

2 - I also tried removing '+' when processing the body string (except the + prefix from the phone numbers)

3 - I also tried get request but then the query params don't arrive as a string of params but a parsed dict.

4 - I only managed to validate the request if I didn't used lambda, then the request had the original query params string from the sender concatenated to the url but I did not manage to replicate this is a lambda environment .

I went over Twilio's documents but it seems to me that when I use GET request I lose the original order of the query params in the lambda even arriving from the api gateway. And regarding post, I have no idea why I'm unable to make it work.

Resources I tried: Cannot Validate Twilio Request in an AWS Lambda Custom Authorizer, Twilio Request Validation always fail for Voice Call (but works for SMS), twilio webhook: fail to validate signature, https://www.twilio.com/docs/messaging/guides/webhook-request, twilio RequestValidator not working in python wsgi

and some others.


Solution

  • With the help of Twilio support I was able to solve the issue (only for POST requests so this is was I will use). The issue was that when getting the url encoded post body, I converted it to a dictionary but without the empty values.

    parsed_dict = parse_qs(event["body"])
    result_dict = {key: value[0] for key, value in parsed_dict.items()}
    

    What I should have done was

    parsed_dict = parse_qs(event["body"], keep_blank_values=True)
    result_dict = {key: value[0] for key, value in parsed_dict.items()}
    

    then validator(url=url, params=result_dict , signiture=sig) worked

    Regarding GET, I'm still not sure how to make it work with api gateway lambda