Webhooks
How to setup Opinly webhooks
What are webhooks?
Webhooks are how services notify each other of events.
At their core they are just a POST request to a pre-determined endpoint. The endpoint can be whatever you want, and you can just add them from the UI. You normally use one endpoint per service, and that endpoint listens to all of the event types.
What are webhooks used for with Opinly?
Currently, Opinly uses webhooks to notify you when your blog content has been updated.
This is useful if you want to invalidate your cache when your blog content has been updated rather than guessing when to revalidate.
How to setup webhooks
We use Svix to handle webhooks.
-
Go to Settings > Developers
-
Add a new webhook
-
Add the endpoint URL. This is the URL of the endpoint you want to receive the webhook.
To test locally you can use:
-
Select
content.paths-invalidated
-
Copy your webhooks and paste them into your
.env
file
OPINLY_WEBHOOK_SIGNING_SECRET=xxxxx
- Add the following to your
app/api/opinly/route.ts
file
(or wherever you want to handle the webhook, just make sure it matches the endpoint URL you added in the previous step)
// app/api/opinly/route.ts
import { Webhook } from "svix";
import { OpinlyWebhookEvent } from "@opinly/backend";
import { revalidatePath } from "next/cache";
export async function POST(request: Request) {
const svix_id = request.headers.get("svix-id");
const svix_timestamp = request.headers.get("svix-timestamp");
const svix_signature = request.headers.get("svix-signature");
if (!svix_id || !svix_timestamp || !svix_signature) {
return new Response("Invalid request", { status: 400 });
}
const raw = await request.arrayBuffer();
const buf = Buffer.from(raw);
const wh = new Webhook(process.env.OPINLY_WEBHOOK_SIGNING_SECRET!);
let evt: OpinlyWebhookEvent;
// Verify the payload with the headers
try {
evt = wh.verify(buf, {
"svix-id": svix_id,
"svix-timestamp": svix_timestamp,
"svix-signature": svix_signature,
}) as OpinlyWebhookEvent;
} catch (err) {
console.log("Error verifying webhook", JSON.stringify(err, null, 2));
return new Response("Error verifying webhook", { status: 400 });
}
switch (evt.type) {
case "content.paths-invalidated":
for (const path of evt.data.paths) {
revalidatePath(
path === "/sitemap"
? ""
: `${`${process.env.OPINLY_BLOG_PREFIX}`}${path}`
);
}
return new Response("ok", { status: 200 });
}
}
You're done!
Start editing your blog content and you should see the changes reflected in your webhooks.