messagebird-nodejs
messagebird-nodejs copied to clipboard
Webhook signature problems with Nextjs
Hey guys, I can't seem to get the webhook verification working.
The docs seem to be out of date and the variables as I needed to manually construct the headers, currently getting "Signatures not match."
const signature = headers().get("Messagebird-Signature");
const timestamp = headers().get("Messagebird-Request-Timestamp");
const body = await req.text();
const result = validate(
{
headers: {
"messagebird-request-timestamp": timestamp,
"messagebird-signature": signature,
},
body,
query: {
statusDatetime: "2019-01-11T09:17:11+00:00",
},
url: `https://${process.env.NGROK_DEVELOPER_URL || process.env.NEXT_PUBLIC_WEB_URL}/api/webhooks/bird`,
},
process.env.BIRD_SHARED_SECRET || ""
)
Attaching more code here, to be clear, still need help - Can someone from the technical team please reach out!
following these docs: https://docs.bird.com/api/notifications-api/api-reference/webhooks/verifying-a-webhook
import { NextApiRequest, NextApiResponse } from 'next';
import crypto from 'crypto';
import { NextRequest } from 'next/server';
import { type IncomingHttpHeaders } from "http2";
import { headers } from 'next/headers'
export async function POST(
req: NextRequest & {
headers: IncomingHttpHeaders & {
"Messagebird-Request-Timestamp": string;
"Messagebird-Signature": string;
};
},
) {
const headersList = headers()
const signature = headersList.get('messagebird-signature')
const timestamp = headersList.get('messagebird-request-timestamp')
if (!signature || !timestamp) {
return new Response(JSON.stringify({ message: 'Missing required headers' }), { status: 400 });
}
const body = await req.text();
const url = req.url
if (!verifyWebhook(signature, timestamp, body, url)) {
return new Response(JSON.stringify({ message: 'Invalid signature' }), { status: 401 });
}
// Webhook is verified, process the payload
const payload = JSON.parse(body.toString());
console.log('Verified webhook payload:', payload);
// Your webhook handling logic here
return new Response(JSON.stringify({ message: 'Webhook received and verified' }), { status: 200 });
}
function verifyWebhook(signature: string, timestamp: string, body: string, url: string): boolean {
// Base64 decode the messagebird-signature header return string;
const decodedSignature = Buffer.from(signature, 'base64').toString('utf-8');
// Create a SHA256 hash checksum of the request body as a binary result;
const hash = crypto.createHash('sha256');
const checksumBody = hash.update(body).digest("binary");
const payload = [timestamp, url, checksumBody].join('\n')
// Calculate HMACSHA256 using the signing key as the secret and the joined payload as the message;
const hmac = crypto.createHmac('sha256', process.env.BIRD_SHARED_SECRET || "");
const checksum = hmac.update(payload).digest('base64');
// Compare the calculated checksum with the decoded signature;
return checksum === decodedSignature;
}