Twilio Authentication on Webhook Callbacks

Twilio authenticates webhooks by calculating a signature based on the webhook url and parameters.  The parameters are sorted and all spaces (%20) are replaced with a plus sign.

For example, if one issues url and parameters as follows

https://example.com/voiceCallback?name=Jane%20Doe&assoc=123&id=abc

The callback function will receive an event with the following property:

"queryStringParameters": {
        "assoc": "123",
        "id":"abc",
        "name": "Jane Doe"
    },

There’s no way for the callback function to determine the original parameter order.  As a result, in order to calculate the right signature to validate this as a Twilio request in the callback function, the point of issue must have the parameters in alphabetical order and replace all %20 with +(plus) symbols.  Also, use &, not & or %26 as the parameter separator.

See this link on how to construct a Twilio webhook url.

Here’s a quick glance:

const url = req.protocol + '://' + req.get('host') + req.originalUrl; 
// Sort the params
  const sortedParams = qs
    .stringify(params, { arrayFormat: 'brackets' })
    .split('&')
    .sort(sortByPropertyOnly)
    .join('&')
    .replace(/%20/g, '+');