Webhook-Sync mit CRM
Halte dein CRM automatisch mit OptimoCMS über Webhooks synchron. Lerne, wie du Webhooks einrichtest, Payloads verarbeitest und Signaturen verifizierst.
Webhook-Sync mit deinem CRM
Webhooks senden Echtzeit-Benachrichtigungen an deinen Server, wenn etwas in OptimoCMS passiert — ein Formular wird eingereicht, eine Bestellung aufgegeben oder eine Seite veröffentlicht.
In diesem Tutorial:
- Webhook über das SDK erstellen
- Express-Server zum Empfangen von Payloads
- Kryptographische Signaturverifizierung
- Payloads verarbeiten und an ein CRM weiterleiten
Voraussetzungen
- Node.js 18+
npm install @optimocms/sdk express- Ein öffentlich erreichbarer Endpoint (verwende ngrok für lokales Testen)
Schritt 1 — Webhook erstellen
SDK
import { OptimoCMS } from '@optimocms/sdk';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
const webhook = await client.webhooks.create('site_abc123', {
url: 'https://dein-server.de/webhooks/optimocms',
events: ['form.submitted', 'order.created', 'booking.created'],
});
console.log(`Webhook erstellt: ${webhook.id}`);
console.log(`Secret: ${webhook.secret}`);REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/webhooks \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://dein-server.de/webhooks/optimocms",
"events": ["form.submitted", "order.created", "booking.created"]
}'Antwort:
{
"id": "wh_abc123",
"url": "https://dein-server.de/webhooks/optimocms",
"events": ["form.submitted", "order.created", "booking.created"],
"secret": "whsec_k7x9m2p4q8r1t5w3",
"active": true,
"createdAt": "2026-05-26T14:00:00Z",
"failCount": 0,
"lastDeliveredAt": null
}Schritt 2 — Webhook-Endpoint bauen
Erstelle einen Express-Server, der Webhook-Payloads empfängt und verarbeitet:
import express from 'express';
import crypto from 'node:crypto';
const app = express();
const WEBHOOK_SECRET = process.env.OPTIMOCMS_WEBHOOK_SECRET!;
app.post(
'/webhooks/optimocms',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-optimocms-signature'] as string;
const timestamp = req.headers['x-optimocms-timestamp'] as string;
if (!verifySignature(req.body, signature, timestamp)) {
console.error('Ungültige Webhook-Signatur');
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body.toString());
switch (event.type) {
case 'form.submitted':
handleFormSubmission(event.data);
break;
case 'order.created':
handleNewOrder(event.data);
break;
case 'booking.created':
handleNewBooking(event.data);
break;
default:
console.log(`Unbekannter Event-Typ: ${event.type}`);
}
res.status(200).json({ received: true });
}
);
app.listen(3000, () => {
console.log('Webhook-Server läuft auf Port 3000');
});Schritt 3 — Signaturverifizierung
OptimoCMS signiert jeden Webhook mit HMAC-SHA256. Verifiziere dies immer vor der Verarbeitung:
function verifySignature(
body: Buffer,
signature: string,
timestamp: string
): boolean {
if (!signature || !timestamp) return false;
const timestampMs = parseInt(timestamp, 10);
const ageMs = Date.now() - timestampMs;
if (ageMs > 5 * 60 * 1000) {
console.error(`Webhook zu alt: ${ageMs}ms`);
return false;
}
const payload = `${timestamp}.${body.toString()}`;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
const expectedBuffer = Buffer.from(expected, 'hex');
const receivedBuffer = Buffer.from(signature, 'hex');
if (expectedBuffer.length !== receivedBuffer.length) return false;
return crypto.timingSafeEqual(expectedBuffer, receivedBuffer);
}Schritt 4 — Payloads an CRM weiterleiten
Beispiel: Formulardaten an HubSpot CRM weiterleiten:
interface FormSubmission {
formId: string;
siteId: string;
fields: Record<string, string>;
submittedAt: string;
}
async function handleFormSubmission(data: FormSubmission): Promise<void> {
const { fields } = data;
const response = await fetch('https://api.hubapi.com/crm/v3/objects/contacts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HUBSPOT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
properties: {
firstname: fields.firstName || fields.name?.split(' ')[0] || '',
lastname: fields.lastName || fields.name?.split(' ').slice(1).join(' ') || '',
email: fields.email,
phone: fields.phone || '',
company: fields.company || '',
hs_lead_status: 'NEW',
source: `OptimoCMS form: ${data.formId}`,
},
}),
});
if (!response.ok) {
const error = await response.text();
console.error(`HubSpot-Sync fehlgeschlagen: ${error}`);
throw new Error(`CRM sync failed: ${response.status}`);
}
console.log(`✓ Kontakt in HubSpot erstellt für ${fields.email}`);
}
async function handleNewOrder(data: { orderId: string; customer: { email: string; name: string }; totalCents: number }) {
console.log(`Neue Bestellung: ${data.orderId} von ${data.customer.name} (€${(data.totalCents / 100).toFixed(2)})`);
}
async function handleNewBooking(data: { bookingId: string; customer: { name: string; email: string }; date: string; startTime: string }) {
console.log(`Neue Reservierung: ${data.bookingId} - ${data.customer.name} am ${data.date} um ${data.startTime}`);
}Schritt 5 — Webhook-Zustellungen überwachen
Überprüfe, ob Webhooks erfolgreich zugestellt werden:
SDK
for await (const delivery of client.webhooks.listDeliveries('site_abc123', 'wh_abc123')) {
const status = delivery.success ? '✓' : '✗';
console.log(`${status} ${delivery.event} → ${delivery.statusCode} (${delivery.durationMs}ms)`);
}
const replay = await client.webhooks.replay('site_abc123', 'wh_abc123', {
since: '2026-05-25T00:00:00Z',
eventTypes: ['form.submitted'],
});
console.log(`${replay.replayed} Events erneut gesendet`);REST
curl https://api.optimocms.com/v1/sites/$SITE_ID/webhooks/$WEBHOOK_ID/deliveries \
-H "Authorization: Bearer $API_KEY"
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/webhooks/$WEBHOOK_ID/replay \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "since": "2026-05-25T00:00:00Z" }'Verfügbare Webhook-Events
| Event | Auslöser |
|---|---|
form.submitted | Besucher reicht ein Formular ein |
order.created | Neue Webshop-Bestellung |
order.updated | Bestellstatus ändert sich |
booking.created | Neue Reservierung |
booking.cancelled | Reservierung storniert |
page.created | Neue Seite erstellt |
page.updated | Seiteninhalt geändert |
page.deleted | Seite gelöscht |
site.published | Site in Produktion veröffentlicht |
Best Practices
- Signatur immer verifizieren — Vertraue eingehenden Requests niemals blind
- Schnell mit 200 antworten — Verarbeite die Payload asynchron, wenn es länger dauert
- Idempotenz — Verwende das
id-Feld zur Duplikat-Erkennung - Retry-tolerant — OptimoCMS wiederholt fehlgeschlagene Zustellungen automatisch (max 5x)
- Logging — Logge jeden eingehenden Webhook für Debugging
Nächste Schritte
- API Referenz: Webhooks — Vollständige Webhook-API-Dokumentation
- CI/CD Pipeline — Deployments automatisieren
- Restaurantseite erstellen — Beispielseite mit Formularen
Multi-Site-Automatisierung
Erstelle und verwalte Dutzende von Sites programmatisch mit dem OptimoCMS SDK. Ideal für Franchises, Agenturen und White-Label-Plattformen.
CI/CD-Pipeline
Automatisiere Content-Updates und Veröffentlichungen mit GitHub Actions und dem OptimoCMS SDK. Von Staging zu Produktion in einem Push.