Menu
Webhooks
Use webhooks to get notified about events in your Drupal site and trigger external workflows.
Creating a Webhook
You can create a webhook in the decoupled.io dashboard. You'll need to provide a URL for your webhook endpoint and select the events you want to subscribe to.
Event Payloads
When an event is triggered, decoupled.io will send a POST request to your webhook URL with a JSON payload. Here's an example of a payload for a `node.update` event:
{
"event": "node.update",
"entity": {
"type": "article",
"id": "your-article-uuid",
"attributes": {
"title": "My Updated Article"
}
}
}Securing Your Webhooks
Secure your webhook endpoints by verifying incoming requests using the revalidation secret. This is the same secret used for on-demand ISR revalidation.
// app/api/webhook/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const secret = request.headers.get('x-revalidate-secret');
if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) {
return NextResponse.json(
{ message: 'Invalid secret' },
{ status: 401 }
);
}
// Process webhook...
return NextResponse.json({ message: 'Webhook received' });
}Next.js Example
Here's how to create a Next.js API route (App Router) to handle incoming webhooks and trigger on-demand revalidation:
// app/api/webhook/route.ts
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const secret = request.headers.get('x-revalidate-secret');
if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) {
return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const { event, entity } = body;
if (event === 'node.update' || event === 'node.insert') {
console.log(`${entity.type} ${entity.id} was updated`);
// Revalidate the specific path
if (entity.path) {
revalidatePath(entity.path);
}
// Revalidate listing pages
revalidatePath('/articles');
}
return NextResponse.json({ revalidated: true });
}