2025-06-30 18:35:00 +01:00

58 lines
1.9 KiB
TypeScript

import { createHmac, timingSafeEqual } from "node:crypto";
import type { RequestHandler } from "@sveltejs/kit";
import { HASH_SECRET } from "$env/static/private";
import { twitchFollowEvent } from "$lib/twitch";
import { client } from "$lib";
const getHmacMessage = (request: Request, body: string): string => {
return (
request.headers.get(TWITCH_MESSAGE_ID)! +
request.headers.get(TWITCH_MESSAGE_TIMESTAMP)! + body
);
};
const getHmac = (secret: string, message: string): string => {
return createHmac("sha256", secret).update(message).digest("hex");
};
const verifyMessage = (hmac: string, verifySignature: string): boolean => {
return timingSafeEqual(Buffer.from(hmac), Buffer.from(verifySignature));
};
const HMAC_PREFIX = "sha256=";
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();
export const fallback: RequestHandler = async ({ request }) => {
const body = await request.text();
const message = getHmacMessage(request, body);
const hmac = HMAC_PREFIX + getHmac(HASH_SECRET, message);
if (!verifyMessage(hmac, request.headers.get(TWITCH_MESSAGE_SIGNATURE)!)) {
console.log("Invalid request");
throw new Error("go away");
} else {
// Get JSON object from body, so you can process the message.
const jsonBody = JSON.parse(body);
console.log(jsonBody);
const event = twitchFollowEvent.safeParse(jsonBody);
if (!event.success) {
console.log("Not a follow event");
console.log(event.error);
return new Response();
}
const { user_name } = event.data.event;
client.setRave(5_000);
console.log(`${user_name} has just subscribed`);
return new Response();
}
};