-
Notifications
You must be signed in to change notification settings - Fork 74
Closed
Description
What is the problem?
I just taken the code from official example: https://dev.twitch.tv/docs/eventsub/handling-webhook-events/#simple-nodejs-example
And only changed the secret to "TestTwitchWebhookSecret".
The result - command "event verify-subscription" successfully passed but "event trigger" fails.
Twitch CLI version : twitch-cli_1.1.23_Windows_x86_64
Operating System: Windows 10
Architecture Version: x64
Steps to reproduce
Trimmed from here: https://dev.twitch.tv/docs/eventsub/handling-webhook-events/#simple-nodejs-example
- Create a new project with
npm init - Run
npm install express --save - Create a file and name it
app.jswith the following content (here is only the secret is changed):
Click me - code is here
const crypto = require('crypto')
const express = require('express');
const app = express();
const port = 8080;
// Notification request headers
const TWITCH_MESSAGE_ID = 'Twitch-Eventsub-Message-Id'.toLowerCase();
const TWITCH_MESSAGE_TIMESTAMP = 'Twitch-Eventsub-Message-Timestamp'.toLowerCase();
const TWITCH_MESSAGE_SIGNATURE = 'Twitch-Eventsub-Message-Signature'.toLowerCase();
const MESSAGE_TYPE = 'Twitch-Eventsub-Message-Type'.toLowerCase();
// Notification message types
const MESSAGE_TYPE_VERIFICATION = 'webhook_callback_verification';
const MESSAGE_TYPE_NOTIFICATION = 'notification';
const MESSAGE_TYPE_REVOCATION = 'revocation';
// Prepend this string to the HMAC that's created from the message
const HMAC_PREFIX = 'sha256=';
app.use(express.raw({ // Need raw message body for signature verification
type: 'application/json'
}))
app.post('/eventsub', (req, res) => {
let secret = getSecret();
let message = getHmacMessage(req);
let hmac = HMAC_PREFIX + getHmac(secret, message); // Signature to compare
if (true === verifyMessage(hmac, req.headers[TWITCH_MESSAGE_SIGNATURE])) {
console.log("signatures match");
// Get JSON object from body, so you can process the message.
let notification = JSON.parse(req.body);
if (MESSAGE_TYPE_NOTIFICATION === req.headers[MESSAGE_TYPE]) {
// TODO: Do something with the event's data.
console.log(`Event type: ${notification.subscription.type}`);
console.log(JSON.stringify(notification.event, null, 4));
res.sendStatus(204);
}
else if (MESSAGE_TYPE_VERIFICATION === req.headers[MESSAGE_TYPE]) {
res.set('Content-Type', 'text/plain').status(200).send(notification.challenge);
}
else if (MESSAGE_TYPE_REVOCATION === req.headers[MESSAGE_TYPE]) {
res.sendStatus(204);
console.log(`${notification.subscription.type} notifications revoked!`);
console.log(`reason: ${notification.subscription.status}`);
console.log(`condition: ${JSON.stringify(notification.subscription.condition, null, 4)}`);
}
else {
res.sendStatus(204);
console.log(`Unknown message type: ${req.headers[MESSAGE_TYPE]}`);
}
}
else {
console.log('403'); // Signatures didn't match.
res.sendStatus(403);
}
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
})
function getSecret() {
// !!! THE SECRET CHANGED !!!!
return 'TestTwitchWebhookSecret';
// !!! THE SECRET CHANGED !!!!
}
// Build the message used to get the HMAC.
function getHmacMessage(request) {
return (request.headers[TWITCH_MESSAGE_ID] +
request.headers[TWITCH_MESSAGE_TIMESTAMP] +
request.body);
}
// Get the HMAC.
function getHmac(secret, message) {
return crypto.createHmac('sha256', secret)
.update(message)
.digest('hex');
}
// Verify whether our hash matches the hash that Twitch passed in the header.
function verifyMessage(hmac, verifySignature) {
return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(verifySignature));
}- Run
node app.js - Run Twitch CLI command
twitch event verify-subscription channel.raid -F http://localhost:8080/eventsub -s TestTwitchWebhookSecretand check that it's successful. - Then run Twitch CLI command
twitch event trigger channel.raid -F http://localhost:8080/eventsub -s TestTwitchWebhookSecret- it fails
Relevant log output
c:\__Work\twitch-cli_1.1.23_Windows_x86_64>twitch event verify-subscription channel.raid -F http://localhost:8080/eventsub -s TestTwitchWebhookSecret
✔ Valid response. Received challenge 888003fe-92ec-88a5-3355-c4facddf9265 in body
✔ Valid content-type header. Received type text/plain with charset utf-8
✔ Valid status code. Received status 200
c:\__Work\twitch-cli_1.1.23_Windows_x86_64>twitch event trigger channel.raid -s TestTwitchWebhookSecret -F http://localhost:8080/eventsub
✗ Invalid response. Received Status Code: 403
✗ Server Said: Forbidden
{"subscription":{"id":"","status":"enabled","type":"channel.raid","version":"1","condition":{"to_broadcaster_user_id":"22473690"},"transport":{"method":"webhook","callback":"null"},"created_at":"2024-07-01T15:27:01.4937421Z","cost":0},"event":{"to_broadcaster_user_id":"22473690","to_broadcaster_user_login":"testBroadcaster","to_broadcaster_user_name":"testBroadcaster","from_broadcaster_user_id":"57779910","from_broadcaster_user_login":"testFromUser","from_broadcaster_user_name":"testFromUser","viewers":78266}}Metadata
Metadata
Assignees
Labels
No labels
