Custom Backend verbinden
blog-maker kann Artikel an jedes Backend veröffentlichen, das einen JSON-HTTP-Endpoint anbietet, nicht nur an WordPress. Diese Seite ist die technische Referenz, um dein eigenes PHP-, Node- oder anderes Backend anzubinden.
Wann sinnvoll
Nutze einen Custom-REST-Endpoint, wenn deine Seite auf einem proprietären CMS, einem eigenen PHP-Backend oder etwas anderem als WordPress/WooCommerce läuft. Einmal im Dashboard deiner Brand eingerichtet, veröffentlicht danach jeder Artikel direkt in deinen eigenen Speicher.
Konfigurations-Schema
Die Verbindung wird über ein kleines JSON-Config mit diesen Feldern beschrieben:
| Feld | Typ | Beschreibung |
|---|---|---|
endpoint | string, required | Die URL, an die wir den veröffentlichten Beitrag senden. |
method | "POST" | "PUT" | "PATCH", optional | HTTP-Methode für die Anfrage. Standard: POST. |
auth | object, required | Wie wir uns authentifizieren: Bearer-Token, Basic Auth, ein eigener Header oder keine. |
payloadTemplate | JSON, required | Der JSON-Body, den wir senden, mit {{tokens}} aus dem Artikel gefüllt. |
successPath | string, optional | Gepunkteter Pfad in der Antwort, der truthy sein muss, damit die Veröffentlichung als erfolgreich zählt. |
postIdPath | string, optional (default "id") | Gepunkteter Pfad zur neuen Post-ID in der Antwort. |
postUrlPath | string, optional | Gepunkteter Pfad zur veröffentlichten URL in der Antwort. |
pingEndpoint | string, optional | Eine separate URL, die nur für den Verbindungstest genutzt wird. |
timeoutMs | number, optional (default 30000) | Anfrage-Timeout in Millisekunden. |
Authentifizierung
Vier Wege, sich zu authentifizieren, pro Verbindung wählbar:
| Typ | Felder | Gesendet als | Hinweis |
|---|---|---|---|
bearer | token | Authorization: Bearer <token> | Empfohlen. |
basic | username, password | Authorization: Basic base64(user:pass) | Nur für Altsysteme. |
header | headerName, headerValue | <headerName>: <headerValue> | Ein beliebiger Header, den dein Backend erwartet. |
none | (none) | no auth header | Für Endpoints ohne eigene Authentifizierung. |
Verfügbare Tokens
Nutze diese in deinem Payload-Template; jeder String im Template wird durchsucht und Tokens werden mit den Artikeldaten gefüllt.
| Token | Beschreibung |
|---|---|
{{id}} | Numerische Artikel-ID. |
{{title}} / {{seoTitle}} | SEO-Titel. |
{{seoDescription}} | Meta-Description. |
{{html}} / {{htmlContent}} | Vollständiger HTML-Body. |
{{slug}} / {{urlSlug}} | URL-Slug. |
{{primaryKeyword}} | Fokus-Keyword. |
{{secondaryKeywords}} | Weitere Keywords, kommagetrennt. |
{{postId}} | Post-ID, nur bei der Aktualisierung eines bestehenden Beitrags vorhanden. |
Beispiel-Payload-Template
{
"title": "{{title}}",
"slug": "{{slug}}",
"html": "{{html}}",
"metaDescription": "{{seoDescription}}",
"primaryKeyword": "{{primaryKeyword}}"
}Beispiel-Request und erwartete Antwort
POST https://example.com/api/receive-post
Content-Type: application/json
Accept: application/json
Authorization: Bearer sk_live_xxxxx
{
"title": "How to set up blog automation",
"slug": "how-to-set-up-blog-automation",
"html": "<p>...</p>",
"metaDescription": "Learn step by step how content automation works.",
"primaryKeyword": "blog automation"
}{
"ok": true,
"id": "post-123",
"url": "https://example.com/blog/how-to-set-up-blog-automation"
}- successPath (z.B. "ok"): muss truthy sein, sonst gilt die Veröffentlichung als fehlgeschlagen.
- postIdPath (Standard "id"): Pfad zur Post-ID, auch verschachtelt möglich, z.B. "data.id".
- postUrlPath (optional): Pfad zur veröffentlichten URL.
Bei einem Fehler (kein 2xx, oder successPath falsy) erscheinen die ersten Zeichen deiner Antwort als Fehlermeldung im Dashboard, damit du von dort aus debuggen kannst.
Receiver-Beispiel
Ein fertiger Mini-Server, den du deinem Entwickler geben kannst. Er prüft den Bearer-Token, speichert den Artikel und antwortet im erwarteten Format.
PHP
<?php
// Minimal blog-maker custom_rest receiver.
// Expects: Authorization: Bearer <token>, JSON body per your payload template.
$expectedToken = getenv('BLOG_MAKER_TOKEN') ?: 'change-me';
$headers = getallheaders();
$auth = $headers['Authorization'] ?? '';
if ($auth !== "Bearer $expectedToken") {
http_response_code(401);
echo json_encode(['ok' => false, 'error' => 'Unauthorized']);
exit;
}
$body = json_decode(file_get_contents('php://input'), true);
if (!$body || empty($body['title']) || empty($body['html'])) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Missing title or html']);
exit;
}
// postId is present on updates; create a new id otherwise.
$postId = $body['postId'] ?? bin2hex(random_bytes(6));
$posts = json_decode(@file_get_contents('posts.json') ?: '{}', true) ?: [];
$posts[$postId] = [
'title' => $body['title'],
'slug' => $body['slug'] ?? '',
'html' => $body['html'],
'metaDescription' => $body['metaDescription'] ?? '',
];
file_put_contents('posts.json', json_encode($posts));
echo json_encode([
'ok' => true,
'id' => $postId,
'url' => "https://example.com/blog/{$body['slug']}",
]);Node.js
// Minimal blog-maker custom_rest receiver (plain Node, no framework).
// Run with: node receiver.js
import { createServer } from "node:http";
import { randomBytes } from "node:crypto";
const TOKEN = process.env.BLOG_MAKER_TOKEN || "change-me";
const posts = new Map();
const server = createServer((req, res) => {
if (req.method !== "POST" && req.method !== "PUT") {
res.writeHead(405).end();
return;
}
if (req.headers.authorization !== `Bearer ${TOKEN}`) {
res.writeHead(401, { "Content-Type": "application/json" });
res.end(JSON.stringify({ ok: false, error: "Unauthorized" }));
return;
}
let raw = "";
req.on("data", (chunk) => (raw += chunk));
req.on("end", () => {
const body = JSON.parse(raw || "{}");
if (!body.title || !body.html) {
res.writeHead(400, { "Content-Type": "application/json" });
res.end(JSON.stringify({ ok: false, error: "Missing title or html" }));
return;
}
// postId is present on updates; create a new id otherwise.
const postId = body.postId || randomBytes(6).toString("hex");
posts.set(postId, body);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({
ok: true,
id: postId,
url: `https://example.com/blog/${body.slug}`,
}));
});
});
server.listen(3999, () => console.log("Receiver listening on :3999"));Sicherheit
- •Zugangsdaten (Tokens, Passwörter, Header-Werte) werden mit AES-256-GCM verschlüsselt gespeichert.
- •Eine Verbindung ist an deine Brand gebunden; nur du oder Nutzer mit Schreibzugriff auf diese Brand können sie anlegen oder testen.
- •Wir blockieren Anfragen an private und interne Netzwerk-Adressen, auch wenn dein Endpoint dorthin weiterleitet.
- •Verbindungstests sind pro Nutzer rate-limitiert.
- •Custom-REST-Endpoints sind ab dem Basic-Plan verfügbar.