After you subscribe to the webhook, Twitch send send a GET request to your callback URL with hub.challenge as a querystring parameter, this is to confirm your callback is reachable and active (thus, why you can’t use localhost, as localhost to Twitch is their own servers so would serve you no purpose), all you have to do at this point is respond with that same hub challenge.
After that has been successfully done, just wait. When there is a notification, Twitch will send a POST request to your callback URL with the data in the body, the data will have the exact same structure as the underlying API topic. When you receive a notification, respond with a 200, otherwise Twitch’s assumes delivery failure and attempts redelivery with a growing backoff timer.
it is also HIGHLY recommend that you use a hub.secret when subscribing, as this will allow you to confirm all notifications have come from Twitch, otherwise there’d be nothing stopping some random user who has found your callback URL from just POST’ing data to it. An example of how I handle this with express is:
const verifyNotice = (req, res, buf, encoding) => {
const expected = req.headers['x-hub-signature'];
const calculated = 'sha256=' + crypto.createHmac('sha256', WEBHOOK_SECRET).update(buf).digest('hex');
req.verified = expected === calculated;
};
app.use(bodyParser.json({ verify: verifyNotice }));
and that will add a ‘verified’ value to the requests.