Reputation: 2534
I'm sending a Twilio SMS message using a status callback with an ID query string:
const TwilioClient = Twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
TwilioClient.messages.create({
body: message,
from: fromNumber,
to: toNumber,
statusCallback: 'https://example.com/webhook/twilio?id=12345',
});
These requests are handled with the provided Express middleware for signature validation:
router.post(
'/twilio',
twilio.webhook({
authToken: process.env.TWILIO_AUTH_TOKEN,
host: 'example.com',
validate: true,
}),
async (req, res) => { /* ... */ },
);
However, the requests are being blocked (403) when I use the URL with the query string. Without the query string, the request is properly validated. I added a breakpoint within the validation middleware and I can see that it is using the URL with the query string for the validation (https://example.com/webhook/twilio?id=12345
). I tried calling the validation function with different variations of the URL (with/without query string, with/without port, trailing ?
, trailing /
), but none of the things I tried seemed to work.
Is there some option I need to use with the middleware to make it properly work with query strings?
Using v4.12.0 of the twilio
package (latest at time of writing)
Upvotes: 0
Views: 715
Reputation: 3871
I can confirm that this approach doesn't work. I assume that it's because you use the .webhook()
function for a statusCallback
--- but I'm not sure about this one, maybe it expects different parameters than the ones of the status callback.
But it definitely works when you use the validateRequest()
function from the node package. You can find more information on the docs page and a working MVP here. The next step would be to convert this into proper middleware.
const twilio = require("twilio"), express = require("express");
const bodyParser = require('body-parser');
const server = new express({});
server.use(bodyParser.urlencoded({ extended: true }));
const DOMAIN = "https://INSERT HERE"; // TODO Replace this
server.all(
'/twilio',
async (req, res) => {
// Check if the incoming signature is valid for your application URL and the incoming parameters
console.log(twilio.validateRequest(process.env.TWILIO_AUTH_TOKEN, req.headers["x-twilio-signature"], `${DOMAIN}${req.url}`, req.body));
res.send("hello")
},
);
server.listen(3000)
Upvotes: 2