Opinly SDK

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.

  1. Go to Settings > Developers

  2. Add a new webhook

  3. Add the endpoint URL. This is the URL of the endpoint you want to receive the webhook.

To test locally you can use:

  • ngrok to create a tunnel to your local server.
  • Svix Play to test webhooks in your browser.
  1. Select content.paths-invalidated

  2. Copy your webhooks and paste them into your .env file

OPINLY_WEBHOOK_SIGNING_SECRET=xxxxx
  1. 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.