Beitragsbild per OpenAI gpt-image-2 in Workflow 2
This commit is contained in:
@@ -22,3 +22,4 @@ CACHE_PURGE_TOKEN=
|
||||
SCORE_ZIELWERT=72
|
||||
NW_ENGINE=google.de
|
||||
NW_LANGUAGE=German
|
||||
OPENAI_API_KEY=
|
||||
|
||||
26
README.md
26
README.md
@@ -270,6 +270,7 @@ sie beim Schreiben direkt vorliegen.
|
||||
- Beitrag anlegen oder aktualisieren, immer `status: draft`
|
||||
- Meta-Felder und SEOPress-Felder im selben Request
|
||||
- Cache leeren (siehe Hinweis unten)
|
||||
- Beitragsbild erzeugen, falls noch keins gesetzt ist (siehe unten)
|
||||
- Zeile in `status-importe.json`
|
||||
6. Benachrichtigung mit Vorschaulinks
|
||||
|
||||
@@ -366,6 +367,31 @@ genauso zaehlt.
|
||||
|
||||
---
|
||||
|
||||
### Beitragsbild
|
||||
|
||||
Hat ein importierter Beitrag noch kein Beitragsbild, erzeugt Workflow 2 eins:
|
||||
|
||||
1. `bild_farbe` und `bildmotiv` aus `artikel-index.json` lesen
|
||||
2. Prompt nach `ratgeber/bildstil.md` bauen, die Farbe zusaetzlich mit Namen,
|
||||
weil das Modell reine Hexwerte etwas zu kraeftig umsetzt
|
||||
3. `POST https://api.openai.com/v1/images/generations` mit `gpt-image-2`,
|
||||
Groesse `1536x864` (16:9 direkt, kein Zuschnitt noetig), `output_format: webp`,
|
||||
`quality: medium`. Antwort in `data[0].b64_json`, Dauer rund 25 Sekunden.
|
||||
4. Als WebP in die Mediathek laden, Alt-Text "Illustration zum Artikel: <Titel>"
|
||||
5. Als `featured_media` setzen und gegenpruefen
|
||||
|
||||
Ist schon ein Beitragsbild gesetzt, passiert nichts, auch nicht beim erneuten
|
||||
Import. **Neu erzeugen:** Beitragsbild im Beitrag entfernen, Workflow 2 erneut
|
||||
starten. Motiv anpassen geht ueber `bildmotiv` in `artikel-index.json`.
|
||||
|
||||
Scheitert OpenAI (Guthaben, Verifizierung, abgelehnter Prompt), wird der Artikel
|
||||
trotzdem importiert und die Ursache gemeldet. Das Hochladen und Setzen in
|
||||
WordPress laeuft dagegen ohne Continue On Fail.
|
||||
|
||||
Schalter und Werte im Node **Konfiguration**: `bild_aktiv`, `bild_modell`,
|
||||
`bild_groesse`, `bild_qualitaet`. Credential: `OpenAI Bilder`
|
||||
(HTTP Header Auth, `Authorization: Bearer <key>`).
|
||||
|
||||
## 4. Fehlerverhalten
|
||||
|
||||
Jeder HTTP-Node hat einen eigenen Fehlerausgang mit einer Meldung, die die
|
||||
|
||||
140
build/gen_wf2.py
140
build/gen_wf2.py
@@ -6,6 +6,7 @@ CRED_NW = {"httpHeaderAuth": {"id": "U23n2O980GKWocWq", "name": "NeuronWriter
|
||||
CRED_GITEA = {"httpHeaderAuth": {"id": "VOD4JM5zwpSC8wAr", "name": "Gitea Skrift Auto Article"}}
|
||||
_js = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "stilpruefung.js"), encoding="utf-8").read()
|
||||
STIL_JS = _js.split("if (typeof module")[0] + "\n"
|
||||
CRED_OPENAI = {"httpHeaderAuth": {"id": "03NmFB2C9IFRXIu8", "name": "OpenAI Bilder"}}
|
||||
CRED_WP = {"httpBasicAuth": {"id": "WIN05TZgM0K5VOGy", "name": "WP skrift.de Redakteur"}}
|
||||
|
||||
nodes, conns = [], {}
|
||||
@@ -71,6 +72,10 @@ KONF = node("Konfiguration", "n8n-nodes-base.set", 3.4, [-240, 190], {
|
||||
{"id": nid(), "name": "score_ziel", "value": "={{ $json.body && $json.body.score_ziel ? Number($json.body.score_ziel) : 65 }}", "type": "number"},
|
||||
{"id": nid(), "name": "pause_zwischen_artikeln", "value": 5, "type": "number"},
|
||||
{"id": nid(), "name": "elementor_ausgabe", "value": False, "type": "boolean"},
|
||||
{"id": nid(), "name": "bild_aktiv", "value": True, "type": "boolean"},
|
||||
{"id": nid(), "name": "bild_modell", "value": "gpt-image-2", "type": "string"},
|
||||
{"id": nid(), "name": "bild_groesse", "value": "1536x864", "type": "string"},
|
||||
{"id": nid(), "name": "bild_qualitaet", "value": "medium", "type": "string"},
|
||||
{"id": nid(), "name": "faq_ueberschrift", "value": "Häufige Fragen", "type": "string"},
|
||||
{"id": nid(), "name": "benachrichtigung_an", "value": "privat@lucas-orth.de", "type": "string"},
|
||||
]}, "options": {}})
|
||||
@@ -561,7 +566,7 @@ const faq_ok = Array.isArray(m.faq) ? m.faq.length : -1;
|
||||
const konf = $('Konfiguration').first().json;
|
||||
return [{ json: {
|
||||
slug: v.slug, ergebnis: 'importiert', score: v.score, score_ziel: v.score_ziel,
|
||||
post_id: p.id, aktion: v.vorhanden ? 'aktualisiert' : 'neu angelegt',
|
||||
post_id: p.id, featured_media: p.featured_media || 0, aktion: v.vorhanden ? 'aktualisiert' : 'neu angelegt',
|
||||
alter_status: v.alter_status, status: p.status,
|
||||
kategorie: v.kategorie_name, kategorie_id: v.kategorie_id,
|
||||
vorschau_url: `${konf.wp_base}/?p=${p.id}&preview=true`,
|
||||
@@ -604,10 +609,138 @@ link(CACHE, CACHE_NOTIZ)
|
||||
PAUSE = node("Pause Rate Limit", "n8n-nodes-base.wait", 1.1, [4860, 420],
|
||||
{"amount": "={{ $('Konfiguration').first().json.pause_zwischen_artikeln }}", "unit": "seconds"},
|
||||
webhookId=str(uuid.uuid4()))
|
||||
for q in [CACHE_NOTIZ, NACH_OK, NACH_FEHLER, FEHLER_ART, FEHLER_EVAL]:
|
||||
for q in [NACH_OK, NACH_FEHLER, FEHLER_ART, FEHLER_EVAL]:
|
||||
link(q, PAUSE)
|
||||
link(PAUSE, LOOP)
|
||||
|
||||
# ================================================================ BEITRAGSBILD
|
||||
BILD_IF = iff("Beitragsbild fehlt?", [4860, 240],
|
||||
"={{ $('Konfiguration').first().json.bild_aktiv === true && !Number($json.featured_media) }}",
|
||||
"boolean", "true")
|
||||
link(CACHE_NOTIZ, BILD_IF)
|
||||
link(BILD_IF, "Pause Rate Limit", out=1)
|
||||
|
||||
BILD_DATEN = http("Bilddaten laden", [5080, 120], "GET",
|
||||
"={{ $('Konfiguration').first().json.gitea_base }}/api/v1/repos/{{ $('Konfiguration').first().json.gitea_owner }}/{{ $('Konfiguration').first().json.gitea_repo }}/contents/artikel-index.json?ref={{ $('Konfiguration').first().json.branch }}",
|
||||
CRED_GITEA, error_out=False, retry=True,
|
||||
extra={"options": {"response": {"response": {"neverError": True, "fullResponse": True}}, "timeout": 60000}})
|
||||
link(BILD_IF, BILD_DATEN, out=0)
|
||||
|
||||
BILD_PROMPT = code("Bildprompt bauen", [5300, 120], r"""
|
||||
// Prompt nach ratgeber/bildstil.md, Farbe und Motiv aus artikel-index.json.
|
||||
const r = $('Importergebnis merken').first().json;
|
||||
const antwort = $input.first().json;
|
||||
const K = (x) => (x && x.body !== undefined) ? x.body : ((x || {}).data);
|
||||
const konf = $('Konfiguration').first().json;
|
||||
|
||||
let zeile = null;
|
||||
const kb = K(antwort);
|
||||
if (antwort.statusCode === 200 && kb && kb.content) {
|
||||
try {
|
||||
const tab = JSON.parse(Buffer.from(kb.content, 'base64').toString('utf8'));
|
||||
zeile = (Array.isArray(tab) ? tab : []).find(z => z.slug === r.slug) || null;
|
||||
} catch (e) { zeile = null; }
|
||||
}
|
||||
if (!zeile || !zeile.bild_farbe || !zeile.bildmotiv) {
|
||||
return [{ json: { ...r, bild_prompt: null,
|
||||
bild_hinweis: 'Kein bild_farbe oder bildmotiv in artikel-index.json, Bild uebersprungen.' } }];
|
||||
}
|
||||
|
||||
const FARBNAME = { '#7B96C2': 'muted light ink blue', '#B6997F': 'muted sepia brown',
|
||||
'#8C9A82': 'muted sage green', '#C47B5E': 'muted terracotta red' };
|
||||
const farbe = String(zeile.bild_farbe).toUpperCase();
|
||||
const name = FARBNAME[farbe] ? ` (${FARBNAME[farbe]}, not more saturated)` : '';
|
||||
const leer = /price tag/i.test(zeile.bildmotiv) ? ', the price tag is completely empty' : '';
|
||||
|
||||
const prompt = [
|
||||
'Hand-drawn doodle spot illustration, flat editorial icon style.',
|
||||
`Solid flat background color ${farbe}${name}, completely uniform, no texture, no gradient, no shadow, no vignette.`,
|
||||
'In the center one simple object, drawn with thick uneven black marker outlines (#1A1A1A), slightly wobbly hand-drawn lines like a felt-tip pen, rounded line ends.',
|
||||
'Clean closed outlines, no stray marks, no hatching and no small dashes inside the shapes.',
|
||||
'Object fills are flat off-white cream (#F9F7F5), no shading, no highlights.',
|
||||
`Motif: ${zeile.bildmotiv}${leer}. Shown straight from the front, not tilted.`,
|
||||
'Minimal and iconic, lots of empty space, the object takes about 35 percent of the image height.',
|
||||
'No text, no letters, no numbers, no currency symbols, no logo, no border, no frame, no rounded corners, no people.',
|
||||
].join(' ');
|
||||
|
||||
return [{ json: { ...r, bild_prompt: prompt, bild_titel: zeile.titel || r.slug,
|
||||
openai_body: JSON.stringify({ model: konf.bild_modell, prompt, size: konf.bild_groesse,
|
||||
n: 1, output_format: 'webp', quality: konf.bild_qualitaet }) } }];
|
||||
""")
|
||||
link(BILD_DATEN, BILD_PROMPT)
|
||||
|
||||
PROMPT_IF = iff("Bildprompt vorhanden?", [5520, 120], "={{ !!$json.bild_prompt }}", "boolean", "true")
|
||||
link(BILD_PROMPT, PROMPT_IF)
|
||||
link(PROMPT_IF, "Pause Rate Limit", out=1)
|
||||
|
||||
# OpenAI darf scheitern, der Artikel ist bereits importiert. Deshalb Fehlerausgang.
|
||||
BILD_GEN = http("Bild erzeugen", [5740, 40], "POST",
|
||||
"https://api.openai.com/v1/images/generations", CRED_OPENAI,
|
||||
body="={{ $json.openai_body }}", retry=True,
|
||||
extra={"options": {"response": {"response": {"neverError": False}}, "timeout": 180000}})
|
||||
link(PROMPT_IF, BILD_GEN, out=0)
|
||||
|
||||
BILD_FEHLER = code("Fehler Bild", [5740, 260], """
|
||||
const r = $('Bildprompt bauen').first().json;
|
||||
const e = $input.first().json;
|
||||
return [{ json: { ...r, openai_body: undefined,
|
||||
bild_hinweis: 'Bild nicht erzeugt, Artikel ist trotzdem importiert. Haeufige Ursachen: '
|
||||
+ 'Guthaben leer, Organisation fuer Bildmodelle nicht verifiziert, Prompt abgelehnt. Antwort: '
|
||||
+ JSON.stringify(e).slice(0, 300) } }];
|
||||
""", onError="continueRegularOutput")
|
||||
link(BILD_GEN, BILD_FEHLER, out=1)
|
||||
link(BILD_FEHLER, "Pause Rate Limit")
|
||||
|
||||
BILD_BIN = code("Bild als Datei", [5960, 40], """
|
||||
const r = $('Bildprompt bauen').first().json;
|
||||
const a = $input.first().json;
|
||||
const b64 = a && a.data && a.data[0] && a.data[0].b64_json;
|
||||
if (!b64) throw new Error('OpenAI lieferte kein data[0].b64_json. Antwort: ' + JSON.stringify(a).slice(0, 300));
|
||||
const puffer = Buffer.from(b64, 'base64');
|
||||
const datei = await this.helpers.prepareBinaryData(puffer, `${r.slug}.webp`, 'image/webp');
|
||||
const { openai_body, ...rest } = r;
|
||||
return [{ json: { ...rest, bild_bytes: puffer.length }, binary: { bild: datei } }];
|
||||
""")
|
||||
link(BILD_GEN, BILD_BIN, out=0)
|
||||
|
||||
# Schreiben nach WordPress: kein Continue On Fail.
|
||||
node("Bild in Mediathek", "n8n-nodes-base.httpRequest", 4.3, [6180, 40], {
|
||||
"method": "POST",
|
||||
"url": "={{ $('Konfiguration').first().json.wp_base }}/wp-json/wp/v2/media?alt_text={{ encodeURIComponent('Illustration zum Artikel: ' + $json.bild_titel) }}&title={{ encodeURIComponent($json.bild_titel) }}",
|
||||
"authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth",
|
||||
"sendHeaders": True,
|
||||
"headerParameters": {"parameters": [
|
||||
{"name": "Content-Disposition", "value": "=attachment; filename=\"{{ $json.slug }}.webp\""},
|
||||
{"name": "Content-Type", "value": "image/webp"}]},
|
||||
"sendBody": True, "contentType": "binaryData", "inputDataFieldName": "bild",
|
||||
"options": {"timeout": 120000}},
|
||||
credentials=CRED_WP, retryOnFail=True, maxTries=3, waitBetweenTries=3000)
|
||||
link(BILD_BIN, "Bild in Mediathek")
|
||||
|
||||
node("Beitragsbild setzen", "n8n-nodes-base.httpRequest", 4.3, [6400, 40], {
|
||||
"method": "POST",
|
||||
"url": "={{ $('Konfiguration').first().json.wp_base }}/wp-json/wp/v2/posts/{{ $('Bildprompt bauen').first().json.post_id }}",
|
||||
"authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth",
|
||||
"sendBody": True, "specifyBody": "json",
|
||||
"jsonBody": "={{ JSON.stringify({ featured_media: $json.id }) }}",
|
||||
"sendHeaders": True, "specifyHeaders": "json", "jsonHeaders": '={"Content-Type":"application/json"}',
|
||||
"options": {"timeout": 60000}},
|
||||
credentials=CRED_WP, retryOnFail=True, maxTries=3, waitBetweenTries=3000)
|
||||
link("Bild in Mediathek", "Beitragsbild setzen")
|
||||
|
||||
BILD_OK = code("Bild gemerkt", [6620, 40], """
|
||||
const r = $('Bild als Datei').first().json;
|
||||
const m = $('Bild in Mediathek').first().json;
|
||||
const p = $input.first().json;
|
||||
if (Number(p.featured_media) !== Number(m.id)) {
|
||||
throw new Error('Beitragsbild wurde nicht gesetzt. Erwartet ' + m.id + ', WordPress meldet ' + p.featured_media);
|
||||
}
|
||||
return [{ json: { ...r, bild: 'neu erzeugt', media_id: m.id, bild_url: m.source_url,
|
||||
featured_media: m.id, bild_kb: Math.round(r.bild_bytes / 1024) } }];
|
||||
""")
|
||||
link("Beitragsbild setzen", BILD_OK)
|
||||
link(BILD_OK, "Pause Rate Limit")
|
||||
|
||||
# ---------------------------------------------------------------- Statustabelle
|
||||
SAMMELN = code("Ergebnisse sammeln", [900, 80], r"""
|
||||
const alle = $input.all().map(i => i.json);
|
||||
@@ -694,6 +827,9 @@ if (s.importiert.length) {
|
||||
z.push(` Vorschau: ${r.vorschau_url}`);
|
||||
z.push(` Bearbeiten: ${r.bearbeiten_url}`);
|
||||
if (r.elementor) z.push(` Layout: ${r.elementor}`);
|
||||
if (r.bild === 'neu erzeugt') z.push(` Bild: neu erzeugt (${r.bild_kb} KB), ${r.bild_url}`);
|
||||
else if (r.featured_media) z.push(` Bild: bereits vorhanden, nicht neu erzeugt`);
|
||||
if (r.bild_hinweis) z.push(` Bild: ${r.bild_hinweis}`);
|
||||
if (r.meta_warnung) z.push(` ACHTUNG: ${r.meta_warnung}`);
|
||||
if (r.preis_warnung) z.push(` PREISE: ${r.preis_warnung}`);
|
||||
if (r.stil_hinweise && r.stil_hinweise.length) {
|
||||
|
||||
4
build/workflow-ids.json
Normal file
4
build/workflow-ids.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"brief-vorbereiten": "9Ym8xpJwWw2OaUCv",
|
||||
"pruefen-und-importieren": "OtwhR0yPz3W9Snui"
|
||||
}
|
||||
26
docs/beleg-05-image-1536x864.json
Normal file
26
docs/beleg-05-image-1536x864.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"created": 1790064128,
|
||||
"background": "opaque",
|
||||
"output_format": "webp",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"usage": {
|
||||
"input_tokens": 220,
|
||||
"input_tokens_details": {
|
||||
"image_tokens": 0,
|
||||
"text_tokens": 220
|
||||
},
|
||||
"output_tokens": 1078,
|
||||
"output_tokens_details": {
|
||||
"image_tokens": 1078,
|
||||
"text_tokens": 0
|
||||
},
|
||||
"total_tokens": 1298
|
||||
},
|
||||
"data": [
|
||||
{
|
||||
"b64_json": "UklGRjbOCQBXRUJQVlA4TKV4CQAv/8XXAM1IbhtJkCQoq3f1yBv/Dc6o7Lm1...",
|
||||
"generation_id": "7295a6c6-dcaf-4e78-8ba9-ed4513a89731"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
docs/bildtest/test-1536x864.webp
Normal file
BIN
docs/bildtest/test-1536x864.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 628 KiB |
BIN
docs/bildtest/workflow-4221-v2.webp
Normal file
BIN
docs/bildtest/workflow-4221-v2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 641 KiB |
BIN
docs/bildtest/workflow-4221.webp
Normal file
BIN
docs/bildtest/workflow-4221.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 609 KiB |
@@ -9,7 +9,7 @@
|
||||
-460,
|
||||
100
|
||||
],
|
||||
"id": "9d7b1805-8faf-4e0b-90d0-faedab546436",
|
||||
"id": "b9523f68-6d9f-4591-92c1-315c8d17e036",
|
||||
"name": "Manuell starten"
|
||||
},
|
||||
{
|
||||
@@ -25,9 +25,9 @@
|
||||
-460,
|
||||
280
|
||||
],
|
||||
"id": "ceaa8ccf-b4a1-4a0d-a173-b9ed63d44833",
|
||||
"id": "e145f97c-7c42-4ac0-bbfa-6791cdf1dc75",
|
||||
"name": "Webhook Start",
|
||||
"webhookId": "ddaf87b7-a52e-44ad-8fc9-b0560671eab3"
|
||||
"webhookId": "51409459-2753-4b72-9442-44eb304e3970"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
@@ -35,91 +35,115 @@
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "c37716f4-15ed-4a09-83f1-7841ff2a4efb",
|
||||
"id": "41e1ade4-2852-4dd1-a6ea-2bb3f9303615",
|
||||
"name": "nw_base",
|
||||
"value": "https://app.neuronwriter.com/neuron-api/0.5/writer",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "a30eeffc-30a1-42fa-bb43-4662e503872b",
|
||||
"id": "919bffea-074d-4e88-b70a-811a1eac022c",
|
||||
"name": "gitea_base",
|
||||
"value": "http://gitea:3000",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "db835d6c-31f9-4ac1-95ff-096bd685aa5e",
|
||||
"id": "0b37ba5d-6fca-4366-93f0-91f449cbac1d",
|
||||
"name": "gitea_owner",
|
||||
"value": "lucas.orth",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "d3f9c73d-bcf1-4ed7-8047-f9eb3968f403",
|
||||
"id": "1bb08030-e5c0-43d9-956a-dc7eaa123b1c",
|
||||
"name": "gitea_repo",
|
||||
"value": "Skrift-Auto-Article",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "c6a32b0a-032f-498e-aea8-04587961668b",
|
||||
"id": "f025bd60-6036-4d86-ad10-de6e9797b4aa",
|
||||
"name": "branch",
|
||||
"value": "main",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "c7e60ffd-132b-43b4-b3e3-7fd0f66b6546",
|
||||
"id": "70fe52cd-e118-428f-98d3-b6fe820415b4",
|
||||
"name": "artikel_ordner",
|
||||
"value": "artikel",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "d379f9fc-d1ba-4ac5-8494-1af6068cefca",
|
||||
"id": "dca9c723-2b38-4eb5-8a97-11e5261768af",
|
||||
"name": "brief_ordner",
|
||||
"value": "briefe",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "46d52c78-8a51-4c5b-b893-ed79a53753a8",
|
||||
"id": "d1761018-b988-49c6-a8d2-b2daea919c48",
|
||||
"name": "nachbessern_ordner",
|
||||
"value": "nachbessern",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "ff44870f-d811-402a-afaf-61053ca2bb83",
|
||||
"id": "7ca8cd59-7043-4a0c-8045-ee87d6386c90",
|
||||
"name": "status_pfad",
|
||||
"value": "status-importe.json",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "ea4a7974-642d-49df-b419-7cb2007893d6",
|
||||
"id": "88d49605-c288-4715-aa51-6263c7a173a3",
|
||||
"name": "wp_base",
|
||||
"value": "https://skrift.de",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "354bf17a-52d5-4483-9cd6-68721a9c2a23",
|
||||
"id": "de3caff4-aa67-441f-b26c-16bdfed44eb9",
|
||||
"name": "score_ziel",
|
||||
"value": "={{ $json.body && $json.body.score_ziel ? Number($json.body.score_ziel) : 65 }}",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"id": "388a5e43-5ab7-42f2-b3d2-438f72ff58e6",
|
||||
"id": "8047bfd6-776e-462f-887e-fbee0826d29d",
|
||||
"name": "pause_zwischen_artikeln",
|
||||
"value": 5,
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"id": "9b2fa315-8213-4609-a2e5-be0936e24f20",
|
||||
"id": "6debc7f0-3db7-4f35-9f91-5126abefb520",
|
||||
"name": "elementor_ausgabe",
|
||||
"value": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"id": "ffca6f3b-e391-4ca7-adb8-49017472dc7b",
|
||||
"id": "3fd3df05-82f9-4b9f-9a2b-fbe70429b7d6",
|
||||
"name": "bild_aktiv",
|
||||
"value": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"id": "378253b1-1ddf-4fbb-8d05-852cd3aed978",
|
||||
"name": "bild_modell",
|
||||
"value": "gpt-image-2",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "ef82071d-192f-4a81-a4f1-544a038a295f",
|
||||
"name": "bild_groesse",
|
||||
"value": "1536x864",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "cc33aca1-730e-45a2-9ec7-273755c8c47d",
|
||||
"name": "bild_qualitaet",
|
||||
"value": "medium",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "116daf1c-c81a-4ef6-8c5d-0c0c193c224c",
|
||||
"name": "faq_ueberschrift",
|
||||
"value": "Häufige Fragen",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "2e8ae0e2-c6ea-4495-9fd5-1ad24c2b5dd8",
|
||||
"id": "0cbace80-605d-4dbc-8868-c63a6234fbf4",
|
||||
"name": "benachrichtigung_an",
|
||||
"value": "privat@lucas-orth.de",
|
||||
"type": "string"
|
||||
@@ -134,7 +158,7 @@
|
||||
-240,
|
||||
190
|
||||
],
|
||||
"id": "d6943dd4-a080-471e-8d8d-281d2b49c91d",
|
||||
"id": "964a22b7-73b6-4318-8700-f0079d07a9d0",
|
||||
"name": "Konfiguration"
|
||||
},
|
||||
{
|
||||
@@ -159,7 +183,7 @@
|
||||
-20,
|
||||
190
|
||||
],
|
||||
"id": "21951ce8-26f3-4473-8051-4e232c228e89",
|
||||
"id": "6a9ab914-96ca-4fbe-95c8-625796575b2a",
|
||||
"name": "Artikelordner lesen",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -182,7 +206,7 @@
|
||||
200,
|
||||
190
|
||||
],
|
||||
"id": "79588bca-c88b-4f26-8344-1f1aaabbf7b7",
|
||||
"id": "b9f93c84-cfe5-41a1-a55d-341ef9adbd8e",
|
||||
"name": "Artikeldateien filtern"
|
||||
},
|
||||
{
|
||||
@@ -196,7 +220,7 @@
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "a9e1753d-2159-4f99-aa0e-b9acaaf0b413",
|
||||
"id": "8d02e08e-0638-4437-92e0-6ac6abfffc56",
|
||||
"leftValue": "={{ $json.leer === true }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
@@ -217,7 +241,7 @@
|
||||
420,
|
||||
190
|
||||
],
|
||||
"id": "7f5cd106-1cbe-4fd2-9a15-3d31ceef74c0",
|
||||
"id": "e0885743-c0cd-49d3-a821-164616cad729",
|
||||
"name": "Artikel vorhanden?"
|
||||
},
|
||||
{
|
||||
@@ -228,7 +252,7 @@
|
||||
640,
|
||||
40
|
||||
],
|
||||
"id": "66ea5319-b958-4cde-924a-ff101321bb3e",
|
||||
"id": "42e5ca07-fe2d-4f3d-bc8a-e8c6641a8d54",
|
||||
"name": "Nichts zu tun"
|
||||
},
|
||||
{
|
||||
@@ -244,7 +268,7 @@
|
||||
640,
|
||||
320
|
||||
],
|
||||
"id": "59e68a48-9e3a-499c-91a9-2d32ba8a6420",
|
||||
"id": "969401ee-c28c-4489-b8d9-c024bd9c2b5e",
|
||||
"name": "Artikel nacheinander"
|
||||
},
|
||||
{
|
||||
@@ -268,7 +292,7 @@
|
||||
900,
|
||||
420
|
||||
],
|
||||
"id": "a3787725-913a-4b49-8177-b40a29322c78",
|
||||
"id": "566c2381-7296-4b46-b022-564a78fb6792",
|
||||
"name": "Artikeldatei laden",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -292,7 +316,7 @@
|
||||
900,
|
||||
640
|
||||
],
|
||||
"id": "25cb559a-6047-4766-bebd-f090d36d44a2",
|
||||
"id": "8a543e9c-c7b3-4ee4-a07c-37d13cf83f2f",
|
||||
"name": "Fehler Artikeldatei",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
@@ -318,7 +342,7 @@
|
||||
1120,
|
||||
420
|
||||
],
|
||||
"id": "d3ea9547-61df-4d13-9dd4-6ffde02be40b",
|
||||
"id": "bb339e46-44b5-4213-9160-e8ceda5e7a89",
|
||||
"name": "Brief laden",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -338,7 +362,7 @@
|
||||
1340,
|
||||
420
|
||||
],
|
||||
"id": "01b083a8-acdd-4964-80fc-26770a1dcecb",
|
||||
"id": "c4db72b1-1e0c-4c63-8dd6-18ce5ed9288f",
|
||||
"name": "Artikel pruefen"
|
||||
},
|
||||
{
|
||||
@@ -368,7 +392,7 @@
|
||||
1560,
|
||||
420
|
||||
],
|
||||
"id": "939d7498-7c06-49a7-b96b-8ed0095edf94",
|
||||
"id": "22ffdabc-ac80-4570-bee2-337463b9e11f",
|
||||
"name": "Score ermitteln",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -392,7 +416,7 @@
|
||||
1560,
|
||||
640
|
||||
],
|
||||
"id": "e3135c57-8738-4d82-914c-8813d3916dcc",
|
||||
"id": "06e19a47-f72e-49af-9275-09383308e218",
|
||||
"name": "Fehler Score",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
@@ -407,7 +431,7 @@
|
||||
1780,
|
||||
420
|
||||
],
|
||||
"id": "b1ea4d99-d731-4468-8525-b1af09e0acc3",
|
||||
"id": "29350571-0c58-4cbb-946c-d413c0d3cac3",
|
||||
"name": "Score auswerten"
|
||||
},
|
||||
{
|
||||
@@ -421,7 +445,7 @@
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "851f792a-479c-4d4b-8801-15010f03be39",
|
||||
"id": "f05d0df3-ca20-4543-968b-5c2cb789774f",
|
||||
"leftValue": "={{ $json.bestanden }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
@@ -442,7 +466,7 @@
|
||||
2000,
|
||||
420
|
||||
],
|
||||
"id": "7187c432-a84a-4a61-b653-a864626f9c0b",
|
||||
"id": "8f793efc-bb8b-4994-a02a-9a4726fbcea8",
|
||||
"name": "Score erreicht?"
|
||||
},
|
||||
{
|
||||
@@ -456,7 +480,7 @@
|
||||
2220,
|
||||
640
|
||||
],
|
||||
"id": "202c13fa-f4eb-4f85-a1a9-97f953ac99dc",
|
||||
"id": "2ca96cd1-a927-4fb3-85ae-8012437609df",
|
||||
"name": "Fehlende Begriffe ermitteln"
|
||||
},
|
||||
{
|
||||
@@ -481,7 +505,7 @@
|
||||
2440,
|
||||
640
|
||||
],
|
||||
"id": "8cbf40d1-3067-461f-a394-796fb71981d0",
|
||||
"id": "4e8517b2-8f12-4bc0-b19b-386da85a6d3a",
|
||||
"name": "Nachbesserung vorhanden?",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -501,7 +525,7 @@
|
||||
2660,
|
||||
640
|
||||
],
|
||||
"id": "b20fd046-39d8-48bf-941d-0866963437d0",
|
||||
"id": "3d8631ae-5f48-4a1b-a4c1-ebb27856dbb4",
|
||||
"name": "Nachbesserung vorbereiten"
|
||||
},
|
||||
{
|
||||
@@ -531,7 +555,7 @@
|
||||
2880,
|
||||
640
|
||||
],
|
||||
"id": "0197b51e-4b00-4fd9-acb0-86a5193ed692",
|
||||
"id": "36244e4c-bd55-4777-b0c0-93ab9c17d14c",
|
||||
"name": "Nachbesserung committen",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -555,7 +579,7 @@
|
||||
2880,
|
||||
860
|
||||
],
|
||||
"id": "9c770168-67a5-4ec5-9498-1037533d808d",
|
||||
"id": "dc67d35e-4a83-428e-83be-7c4196161806",
|
||||
"name": "Fehler Nachbesserung",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
@@ -570,7 +594,7 @@
|
||||
3100,
|
||||
640
|
||||
],
|
||||
"id": "0a987ebf-e478-48ce-b721-598e2759019a",
|
||||
"id": "eaf7de10-8b7a-4020-a5e9-5b58af6b95e8",
|
||||
"name": "Nachbesserung gemerkt"
|
||||
},
|
||||
{
|
||||
@@ -600,7 +624,7 @@
|
||||
2220,
|
||||
240
|
||||
],
|
||||
"id": "4ee193df-d21a-4a4b-a78e-ce967ce6fabf",
|
||||
"id": "ed8e731a-4142-46ac-830e-cddcd44a9987",
|
||||
"name": "Revision zu NeuronWriter",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -624,7 +648,7 @@
|
||||
2220,
|
||||
60
|
||||
],
|
||||
"id": "9fa33651-10b2-4068-a5db-0c1705a394a6",
|
||||
"id": "9ed00d79-a091-406f-afa9-e6aca9d773ac",
|
||||
"name": "Fehler Revision",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
@@ -650,7 +674,7 @@
|
||||
2440,
|
||||
240
|
||||
],
|
||||
"id": "bd2f2ec2-0ce6-4491-86cf-342aeecbbeed",
|
||||
"id": "641f8e00-0809-41bb-a43a-2ab3077236cc",
|
||||
"name": "Beitrag vorhanden?",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
@@ -684,7 +708,7 @@
|
||||
2660,
|
||||
240
|
||||
],
|
||||
"id": "caa0d4e8-3bca-4fd1-90e4-824837ca8c01",
|
||||
"id": "34ba9cb0-fab5-4344-bc9c-699239d01c99",
|
||||
"name": "Kategorie suchen",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
@@ -707,7 +731,7 @@
|
||||
2880,
|
||||
240
|
||||
],
|
||||
"id": "cd297bed-663d-47f3-ae1d-7442e7251e69",
|
||||
"id": "e900cca9-39fe-4806-9588-91d1de3ba9e5",
|
||||
"name": "Kategorie pruefen"
|
||||
},
|
||||
{
|
||||
@@ -721,7 +745,7 @@
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "f05870e6-38ac-4e5e-8b77-c75437e2d520",
|
||||
"id": "59dc46d5-6d0d-4796-bf86-95d715ea05d8",
|
||||
"leftValue": "={{ $json.kategorie_fehlt }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
@@ -742,7 +766,7 @@
|
||||
3100,
|
||||
240
|
||||
],
|
||||
"id": "01a425ce-96d8-4a77-b797-946bc628ad2f",
|
||||
"id": "0c0a8bc7-cbac-4e70-a7f6-e94c38ffa837",
|
||||
"name": "Kategorie anlegen?"
|
||||
},
|
||||
{
|
||||
@@ -772,7 +796,7 @@
|
||||
3320,
|
||||
140
|
||||
],
|
||||
"id": "ed15de50-93a9-4413-8729-3aa6c57cac6a",
|
||||
"id": "b64baa11-054d-4830-a56c-20c931ce3655",
|
||||
"name": "Kategorie anlegen",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
@@ -795,7 +819,7 @@
|
||||
3540,
|
||||
240
|
||||
],
|
||||
"id": "1dad3b28-189b-430a-ac32-c1724c816f16",
|
||||
"id": "cfb9aeda-8ebe-4895-a463-6f621d22020e",
|
||||
"name": "Kategorie festlegen"
|
||||
},
|
||||
{
|
||||
@@ -809,7 +833,7 @@
|
||||
3760,
|
||||
240
|
||||
],
|
||||
"id": "b64f3c2d-f4a3-4e61-abd0-4b2b5fa42661",
|
||||
"id": "fa7f4b40-e2fd-4e02-832c-2ff0da8527b3",
|
||||
"name": "WordPress-Body bauen"
|
||||
},
|
||||
{
|
||||
@@ -839,7 +863,7 @@
|
||||
3980,
|
||||
240
|
||||
],
|
||||
"id": "d1d7fd80-caf7-46cf-9ded-9aa3b97b9a15",
|
||||
"id": "c22b7697-ac02-45eb-aa2c-7fe87aeb46ff",
|
||||
"name": "Beitrag anlegen oder aktualisieren",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
@@ -854,7 +878,7 @@
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\nconst v = $('WordPress-Body bauen').first().json;\nconst p = $input.first().json;\n\nif (!p.id) {\n throw new Error('WordPress lieferte keine Beitrags-ID zurueck. Antwort: '\n + JSON.stringify(p).slice(0, 400));\n}\nif (p.status !== 'draft') {\n throw new Error('Beitrag ' + p.id + ' hat Status \"' + p.status\n + '\" statt \"draft\". Der Workflow darf nie veroeffentlichen. Bitte pruefen.');\n}\n\n// Gegenprobe: sind die Meta-Felder wirklich angekommen?\nconst m = p.meta || {};\nconst fehlend = ['kurzantwort', 'cta_ziel', 'stand_datum', 'faq']\n .filter(k => m[k] === undefined);\nconst faq_ok = Array.isArray(m.faq) ? m.faq.length : -1;\n\nconst konf = $('Konfiguration').first().json;\nreturn [{ json: {\n slug: v.slug, ergebnis: 'importiert', score: v.score, score_ziel: v.score_ziel,\n post_id: p.id, aktion: v.vorhanden ? 'aktualisiert' : 'neu angelegt',\n alter_status: v.alter_status, status: p.status,\n kategorie: v.kategorie_name, kategorie_id: v.kategorie_id,\n vorschau_url: `${konf.wp_base}/?p=${p.id}&preview=true`,\n bearbeiten_url: `${konf.wp_base}/wp-admin/post.php?post=${p.id}&action=edit`,\n meta_warnung: fehlend.length\n ? 'Diese Meta-Felder kamen nicht zurueck: ' + fehlend.join(', ')\n + '. Mu-Plugin skrift-ratgeber-felder.php installiert?'\n : null,\n faq_eintraege: faq_ok,\n elementor: (p.meta || {})._elementor_edit_mode === 'builder'\n ? (() => { try { return JSON.parse((p.meta || {})._elementor_data || '[]').length + ' Container'; }\n catch (e) { return 'ungueltig'; } })()\n : 'klassischer Inhalt',\n seo_titel: (p.meta || {})._seopress_titles_title || null,\n preis_warnung: v.preis_warnung || null,\n stil_hinweise: v.stil_hinweise || [],\n preis_shortcodes: v.preis_shortcodes || 0,\n}}];\n"
|
||||
"jsCode": "\nconst v = $('WordPress-Body bauen').first().json;\nconst p = $input.first().json;\n\nif (!p.id) {\n throw new Error('WordPress lieferte keine Beitrags-ID zurueck. Antwort: '\n + JSON.stringify(p).slice(0, 400));\n}\nif (p.status !== 'draft') {\n throw new Error('Beitrag ' + p.id + ' hat Status \"' + p.status\n + '\" statt \"draft\". Der Workflow darf nie veroeffentlichen. Bitte pruefen.');\n}\n\n// Gegenprobe: sind die Meta-Felder wirklich angekommen?\nconst m = p.meta || {};\nconst fehlend = ['kurzantwort', 'cta_ziel', 'stand_datum', 'faq']\n .filter(k => m[k] === undefined);\nconst faq_ok = Array.isArray(m.faq) ? m.faq.length : -1;\n\nconst konf = $('Konfiguration').first().json;\nreturn [{ json: {\n slug: v.slug, ergebnis: 'importiert', score: v.score, score_ziel: v.score_ziel,\n post_id: p.id, featured_media: p.featured_media || 0, aktion: v.vorhanden ? 'aktualisiert' : 'neu angelegt',\n alter_status: v.alter_status, status: p.status,\n kategorie: v.kategorie_name, kategorie_id: v.kategorie_id,\n vorschau_url: `${konf.wp_base}/?p=${p.id}&preview=true`,\n bearbeiten_url: `${konf.wp_base}/wp-admin/post.php?post=${p.id}&action=edit`,\n meta_warnung: fehlend.length\n ? 'Diese Meta-Felder kamen nicht zurueck: ' + fehlend.join(', ')\n + '. Mu-Plugin skrift-ratgeber-felder.php installiert?'\n : null,\n faq_eintraege: faq_ok,\n elementor: (p.meta || {})._elementor_edit_mode === 'builder'\n ? (() => { try { return JSON.parse((p.meta || {})._elementor_data || '[]').length + ' Container'; }\n catch (e) { return 'ungueltig'; } })()\n : 'klassischer Inhalt',\n seo_titel: (p.meta || {})._seopress_titles_title || null,\n preis_warnung: v.preis_warnung || null,\n stil_hinweise: v.stil_hinweise || [],\n preis_shortcodes: v.preis_shortcodes || 0,\n}}];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
@@ -862,7 +886,7 @@
|
||||
4200,
|
||||
240
|
||||
],
|
||||
"id": "a16f780a-5f7e-4581-b0f5-7f55464e87d1",
|
||||
"id": "9d81b408-d848-480d-99d7-cf09bf728877",
|
||||
"name": "Ergebnis pruefen"
|
||||
},
|
||||
{
|
||||
@@ -893,7 +917,7 @@
|
||||
4420,
|
||||
240
|
||||
],
|
||||
"id": "f1b48e11-b8c6-4842-913c-5a8a43b042d5",
|
||||
"id": "f4ad279d-9ee5-4d0a-9e82-151450889d92",
|
||||
"name": "Cache leeren",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
@@ -913,7 +937,7 @@
|
||||
4640,
|
||||
240
|
||||
],
|
||||
"id": "6708b72c-7577-4bb5-b824-652648fff48c",
|
||||
"id": "18f0e4ac-8ea3-450f-8d49-df200d7ddaaf",
|
||||
"name": "Importergebnis merken"
|
||||
},
|
||||
{
|
||||
@@ -927,9 +951,288 @@
|
||||
4860,
|
||||
420
|
||||
],
|
||||
"id": "2297ffc3-9c1a-48a2-ba7a-20f394af02f0",
|
||||
"id": "9613876f-73d4-4baa-99ad-31d8a2714e4c",
|
||||
"name": "Pause Rate Limit",
|
||||
"webhookId": "cf34062f-fc9c-49de-b651-9a8d020b9d57"
|
||||
"webhookId": "d8b56a3f-dffc-4f1e-94a6-a3864185fa09"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "loose",
|
||||
"version": 2
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "433d059a-e005-4644-9f14-64cfe735e4b6",
|
||||
"leftValue": "={{ $('Konfiguration').first().json.bild_aktiv === true && !Number($json.featured_media) }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"looseTypeValidation": true,
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
4860,
|
||||
240
|
||||
],
|
||||
"id": "61319cb6-8092-4daa-a837-fb7008994b87",
|
||||
"name": "Beitragsbild fehlt?"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "GET",
|
||||
"url": "={{ $('Konfiguration').first().json.gitea_base }}/api/v1/repos/{{ $('Konfiguration').first().json.gitea_owner }}/{{ $('Konfiguration').first().json.gitea_repo }}/contents/artikel-index.json?ref={{ $('Konfiguration').first().json.branch }}",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"neverError": true,
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 60000
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
5080,
|
||||
120
|
||||
],
|
||||
"id": "6c2b9f0c-e425-4f79-a0c8-de5b56da7ebf",
|
||||
"name": "Bilddaten laden",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
"id": "VOD4JM5zwpSC8wAr",
|
||||
"name": "Gitea Skrift Auto Article"
|
||||
}
|
||||
},
|
||||
"retryOnFail": true,
|
||||
"maxTries": 3,
|
||||
"waitBetweenTries": 3000
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\n// Prompt nach ratgeber/bildstil.md, Farbe und Motiv aus artikel-index.json.\nconst r = $('Importergebnis merken').first().json;\nconst antwort = $input.first().json;\nconst K = (x) => (x && x.body !== undefined) ? x.body : ((x || {}).data);\nconst konf = $('Konfiguration').first().json;\n\nlet zeile = null;\nconst kb = K(antwort);\nif (antwort.statusCode === 200 && kb && kb.content) {\n try {\n const tab = JSON.parse(Buffer.from(kb.content, 'base64').toString('utf8'));\n zeile = (Array.isArray(tab) ? tab : []).find(z => z.slug === r.slug) || null;\n } catch (e) { zeile = null; }\n}\nif (!zeile || !zeile.bild_farbe || !zeile.bildmotiv) {\n return [{ json: { ...r, bild_prompt: null,\n bild_hinweis: 'Kein bild_farbe oder bildmotiv in artikel-index.json, Bild uebersprungen.' } }];\n}\n\nconst FARBNAME = { '#7B96C2': 'muted light ink blue', '#B6997F': 'muted sepia brown',\n '#8C9A82': 'muted sage green', '#C47B5E': 'muted terracotta red' };\nconst farbe = String(zeile.bild_farbe).toUpperCase();\nconst name = FARBNAME[farbe] ? ` (${FARBNAME[farbe]}, not more saturated)` : '';\nconst leer = /price tag/i.test(zeile.bildmotiv) ? ', the price tag is completely empty' : '';\n\nconst prompt = [\n 'Hand-drawn doodle spot illustration, flat editorial icon style.',\n `Solid flat background color ${farbe}${name}, completely uniform, no texture, no gradient, no shadow, no vignette.`,\n 'In the center one simple object, drawn with thick uneven black marker outlines (#1A1A1A), slightly wobbly hand-drawn lines like a felt-tip pen, rounded line ends.',\n 'Clean closed outlines, no stray marks, no hatching and no small dashes inside the shapes.',\n 'Object fills are flat off-white cream (#F9F7F5), no shading, no highlights.',\n `Motif: ${zeile.bildmotiv}${leer}. Shown straight from the front, not tilted.`,\n 'Minimal and iconic, lots of empty space, the object takes about 35 percent of the image height.',\n 'No text, no letters, no numbers, no currency symbols, no logo, no border, no frame, no rounded corners, no people.',\n].join(' ');\n\nreturn [{ json: { ...r, bild_prompt: prompt, bild_titel: zeile.titel || r.slug,\n openai_body: JSON.stringify({ model: konf.bild_modell, prompt, size: konf.bild_groesse,\n n: 1, output_format: 'webp', quality: konf.bild_qualitaet }) } }];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
5300,
|
||||
120
|
||||
],
|
||||
"id": "f602842b-c4ed-4d15-8e85-72ce9d329fa3",
|
||||
"name": "Bildprompt bauen"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "loose",
|
||||
"version": 2
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "a9afefa8-8157-43f5-91b1-f7446c5364bd",
|
||||
"leftValue": "={{ !!$json.bild_prompt }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"looseTypeValidation": true,
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
5520,
|
||||
120
|
||||
],
|
||||
"id": "14894cfa-8e68-4edb-9d17-f2671780aa74",
|
||||
"name": "Bildprompt vorhanden?"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://api.openai.com/v1/images/generations",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"neverError": false
|
||||
}
|
||||
},
|
||||
"timeout": 180000
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.openai_body }}",
|
||||
"sendHeaders": true,
|
||||
"specifyHeaders": "json",
|
||||
"jsonHeaders": "={\"Content-Type\":\"application/json\"}"
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
5740,
|
||||
40
|
||||
],
|
||||
"id": "31ab60fc-6031-439a-8402-74dd6d0d9437",
|
||||
"name": "Bild erzeugen",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
"id": "03NmFB2C9IFRXIu8",
|
||||
"name": "OpenAI Bilder"
|
||||
}
|
||||
},
|
||||
"onError": "continueErrorOutput",
|
||||
"retryOnFail": true,
|
||||
"maxTries": 3,
|
||||
"waitBetweenTries": 3000
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\nconst r = $('Bildprompt bauen').first().json;\nconst e = $input.first().json;\nreturn [{ json: { ...r, openai_body: undefined,\n bild_hinweis: 'Bild nicht erzeugt, Artikel ist trotzdem importiert. Haeufige Ursachen: '\n + 'Guthaben leer, Organisation fuer Bildmodelle nicht verifiziert, Prompt abgelehnt. Antwort: '\n + JSON.stringify(e).slice(0, 300) } }];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
5740,
|
||||
260
|
||||
],
|
||||
"id": "6efa2c23-95e2-4a94-873b-b509c10ab395",
|
||||
"name": "Fehler Bild",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\nconst r = $('Bildprompt bauen').first().json;\nconst a = $input.first().json;\nconst b64 = a && a.data && a.data[0] && a.data[0].b64_json;\nif (!b64) throw new Error('OpenAI lieferte kein data[0].b64_json. Antwort: ' + JSON.stringify(a).slice(0, 300));\nconst puffer = Buffer.from(b64, 'base64');\nconst datei = await this.helpers.prepareBinaryData(puffer, `${r.slug}.webp`, 'image/webp');\nconst { openai_body, ...rest } = r;\nreturn [{ json: { ...rest, bild_bytes: puffer.length }, binary: { bild: datei } }];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
5960,
|
||||
40
|
||||
],
|
||||
"id": "491b23b7-4679-429d-9745-47292b0154ca",
|
||||
"name": "Bild als Datei"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "={{ $('Konfiguration').first().json.wp_base }}/wp-json/wp/v2/media?alt_text={{ encodeURIComponent('Illustration zum Artikel: ' + $json.bild_titel) }}&title={{ encodeURIComponent($json.bild_titel) }}",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Disposition",
|
||||
"value": "=attachment; filename=\"{{ $json.slug }}.webp\""
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "image/webp"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"contentType": "binaryData",
|
||||
"inputDataFieldName": "bild",
|
||||
"options": {
|
||||
"timeout": 120000
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
6180,
|
||||
40
|
||||
],
|
||||
"id": "b5e1265a-6b87-4c3f-840c-6cca67628550",
|
||||
"name": "Bild in Mediathek",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "WIN05TZgM0K5VOGy",
|
||||
"name": "WP skrift.de Redakteur"
|
||||
}
|
||||
},
|
||||
"retryOnFail": true,
|
||||
"maxTries": 3,
|
||||
"waitBetweenTries": 3000
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "={{ $('Konfiguration').first().json.wp_base }}/wp-json/wp/v2/posts/{{ $('Bildprompt bauen').first().json.post_id }}",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpBasicAuth",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ JSON.stringify({ featured_media: $json.id }) }}",
|
||||
"sendHeaders": true,
|
||||
"specifyHeaders": "json",
|
||||
"jsonHeaders": "={\"Content-Type\":\"application/json\"}",
|
||||
"options": {
|
||||
"timeout": 60000
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
6400,
|
||||
40
|
||||
],
|
||||
"id": "21f00fcc-1449-4cb7-96b2-6cf35a4d8056",
|
||||
"name": "Beitragsbild setzen",
|
||||
"credentials": {
|
||||
"httpBasicAuth": {
|
||||
"id": "WIN05TZgM0K5VOGy",
|
||||
"name": "WP skrift.de Redakteur"
|
||||
}
|
||||
},
|
||||
"retryOnFail": true,
|
||||
"maxTries": 3,
|
||||
"waitBetweenTries": 3000
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\nconst r = $('Bild als Datei').first().json;\nconst m = $('Bild in Mediathek').first().json;\nconst p = $input.first().json;\nif (Number(p.featured_media) !== Number(m.id)) {\n throw new Error('Beitragsbild wurde nicht gesetzt. Erwartet ' + m.id + ', WordPress meldet ' + p.featured_media);\n}\nreturn [{ json: { ...r, bild: 'neu erzeugt', media_id: m.id, bild_url: m.source_url,\n featured_media: m.id, bild_kb: Math.round(r.bild_bytes / 1024) } }];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
6620,
|
||||
40
|
||||
],
|
||||
"id": "78f4059e-6003-43b0-80dc-fad15546eff3",
|
||||
"name": "Bild gemerkt"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
@@ -942,7 +1245,7 @@
|
||||
900,
|
||||
80
|
||||
],
|
||||
"id": "056c1cf1-f7ba-48dc-a1c2-3d22d70e4550",
|
||||
"id": "7241567b-ebff-4ddf-a4e3-f40ef3787b07",
|
||||
"name": "Ergebnisse sammeln"
|
||||
},
|
||||
{
|
||||
@@ -967,7 +1270,7 @@
|
||||
1120,
|
||||
80
|
||||
],
|
||||
"id": "88815af5-2481-4518-adf6-d50ec1cb28c8",
|
||||
"id": "1b6c1a04-caf9-4bb8-ace9-b050fe4710bb",
|
||||
"name": "Statustabelle lesen",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -987,7 +1290,7 @@
|
||||
1340,
|
||||
80
|
||||
],
|
||||
"id": "c094f8dd-9756-47b6-876b-057507091af2",
|
||||
"id": "5aecb5c3-e0d3-45df-b33b-37c1d13c8c08",
|
||||
"name": "Statustabelle fortschreiben"
|
||||
},
|
||||
{
|
||||
@@ -1001,7 +1304,7 @@
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "51ddce38-e3ef-46d4-8922-b51f79ff011a",
|
||||
"id": "82bf79b1-edca-437a-88cd-913d7f3fd9c4",
|
||||
"leftValue": "={{ $json.ueberspringen }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
@@ -1022,7 +1325,7 @@
|
||||
1560,
|
||||
80
|
||||
],
|
||||
"id": "480901ea-3057-402a-8828-c449d4127118",
|
||||
"id": "049968c9-10ac-4616-b768-832074799f58",
|
||||
"name": "Gab es Importe?"
|
||||
},
|
||||
{
|
||||
@@ -1052,7 +1355,7 @@
|
||||
1780,
|
||||
160
|
||||
],
|
||||
"id": "461196bc-73d5-49a9-be96-9da3866479dc",
|
||||
"id": "e1193d3f-fed0-4f31-a90c-c333a5a2bdd5",
|
||||
"name": "Statustabelle schreiben",
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
@@ -1076,14 +1379,14 @@
|
||||
1780,
|
||||
340
|
||||
],
|
||||
"id": "a754dbe7-60b0-43c2-80bd-ff88df4eac50",
|
||||
"id": "6df2408f-6d6c-4a04-8641-3a4a738268c2",
|
||||
"name": "Fehler Statustabelle",
|
||||
"onError": "continueRegularOutput"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "runOnceForAllItems",
|
||||
"jsCode": "\nconst s = $('Ergebnisse sammeln').first().json;\nconst z = [];\nz.push(`Importiert: ${s.anzahl_importiert} | Nachbessern: ${s.anzahl_nachbessern} | Fehler: ${s.anzahl_fehler}`);\nz.push('');\n\nif (s.importiert.length) {\n z.push('Als Entwurf in WordPress:');\n s.importiert.forEach(r => {\n z.push(` ${r.slug} (Score ${r.score}, ${r.aktion})`);\n z.push(` Vorschau: ${r.vorschau_url}`);\n z.push(` Bearbeiten: ${r.bearbeiten_url}`);\n if (r.elementor) z.push(` Layout: ${r.elementor}`);\n if (r.meta_warnung) z.push(` ACHTUNG: ${r.meta_warnung}`);\n if (r.preis_warnung) z.push(` PREISE: ${r.preis_warnung}`);\n if (r.stil_hinweise && r.stil_hinweise.length) {\n z.push(` STIL: ${r.stil_hinweise.length} Hinweis(e)`);\n r.stil_hinweise.slice(0, 6).forEach(h => z.push(` - ${h.art}: ${h.stelle}`));\n if (r.stil_hinweise.length > 6) z.push(` ... weitere im Nachbesserungsbericht bzw. in der Execution`);\n }\n if (r.cache_hinweis) z.push(` Hinweis: ${r.cache_hinweis}`);\n });\n z.push('');\n}\nif (s.nachbessern.length) {\n z.push('Score zu niedrig, Nachbesserung liegt im Repo:');\n s.nachbessern.forEach(r => {\n z.push(` ${r.slug}: Score ${r.score} von ${r.score_ziel}`);\n z.push(` ${r.anzahl_pflicht} Pflichtbegriffe fehlen, ${r.anzahl_erweitert} Zusatzbegriffe`);\n if (r.wortzahl && r.wortzahl.differenz !== null) {\n z.push(` Wortzahl ${r.wortzahl.ist} von ${r.wortzahl.ziel} (${r.wortzahl.differenz > 0 ? '+' : ''}${r.wortzahl.differenz})`);\n }\n z.push(` Datei: ${r.pfad}`);\n if (r.preis_warnung) z.push(` PREISE: ${r.preis_warnung}`);\n if (r.stil_hinweise && r.stil_hinweise.length) {\n z.push(` STIL: ${r.stil_hinweise.length} Hinweis(e)`);\n r.stil_hinweise.slice(0, 6).forEach(h => z.push(` - ${h.art}: ${h.stelle}`));\n if (r.stil_hinweise.length > 6) z.push(` ... weitere im Nachbesserungsbericht bzw. in der Execution`);\n }\n });\n z.push('');\n}\nif (s.fehler.length) {\n z.push('Fehler:');\n s.fehler.forEach(r => z.push(` ${r.slug || '?'} [${r.stufe}]: ${r.meldung}`));\n z.push('');\n}\nz.push('Kein Beitrag wurde veroeffentlicht. Alle Importe stehen auf Entwurf.');\n\nreturn [{ json: {\n betreff: `Skrift Ratgeber: ${s.anzahl_importiert} Entwurf/Entwuerfe`\n + (s.anzahl_nachbessern ? `, ${s.anzahl_nachbessern} zum Nachbessern` : '')\n + (s.anzahl_fehler ? `, ${s.anzahl_fehler} Fehler` : ''),\n text: z.join('\\n') }}];\n"
|
||||
"jsCode": "\nconst s = $('Ergebnisse sammeln').first().json;\nconst z = [];\nz.push(`Importiert: ${s.anzahl_importiert} | Nachbessern: ${s.anzahl_nachbessern} | Fehler: ${s.anzahl_fehler}`);\nz.push('');\n\nif (s.importiert.length) {\n z.push('Als Entwurf in WordPress:');\n s.importiert.forEach(r => {\n z.push(` ${r.slug} (Score ${r.score}, ${r.aktion})`);\n z.push(` Vorschau: ${r.vorschau_url}`);\n z.push(` Bearbeiten: ${r.bearbeiten_url}`);\n if (r.elementor) z.push(` Layout: ${r.elementor}`);\n if (r.bild === 'neu erzeugt') z.push(` Bild: neu erzeugt (${r.bild_kb} KB), ${r.bild_url}`);\n else if (r.featured_media) z.push(` Bild: bereits vorhanden, nicht neu erzeugt`);\n if (r.bild_hinweis) z.push(` Bild: ${r.bild_hinweis}`);\n if (r.meta_warnung) z.push(` ACHTUNG: ${r.meta_warnung}`);\n if (r.preis_warnung) z.push(` PREISE: ${r.preis_warnung}`);\n if (r.stil_hinweise && r.stil_hinweise.length) {\n z.push(` STIL: ${r.stil_hinweise.length} Hinweis(e)`);\n r.stil_hinweise.slice(0, 6).forEach(h => z.push(` - ${h.art}: ${h.stelle}`));\n if (r.stil_hinweise.length > 6) z.push(` ... weitere im Nachbesserungsbericht bzw. in der Execution`);\n }\n if (r.cache_hinweis) z.push(` Hinweis: ${r.cache_hinweis}`);\n });\n z.push('');\n}\nif (s.nachbessern.length) {\n z.push('Score zu niedrig, Nachbesserung liegt im Repo:');\n s.nachbessern.forEach(r => {\n z.push(` ${r.slug}: Score ${r.score} von ${r.score_ziel}`);\n z.push(` ${r.anzahl_pflicht} Pflichtbegriffe fehlen, ${r.anzahl_erweitert} Zusatzbegriffe`);\n if (r.wortzahl && r.wortzahl.differenz !== null) {\n z.push(` Wortzahl ${r.wortzahl.ist} von ${r.wortzahl.ziel} (${r.wortzahl.differenz > 0 ? '+' : ''}${r.wortzahl.differenz})`);\n }\n z.push(` Datei: ${r.pfad}`);\n if (r.preis_warnung) z.push(` PREISE: ${r.preis_warnung}`);\n if (r.stil_hinweise && r.stil_hinweise.length) {\n z.push(` STIL: ${r.stil_hinweise.length} Hinweis(e)`);\n r.stil_hinweise.slice(0, 6).forEach(h => z.push(` - ${h.art}: ${h.stelle}`));\n if (r.stil_hinweise.length > 6) z.push(` ... weitere im Nachbesserungsbericht bzw. in der Execution`);\n }\n });\n z.push('');\n}\nif (s.fehler.length) {\n z.push('Fehler:');\n s.fehler.forEach(r => z.push(` ${r.slug || '?'} [${r.stufe}]: ${r.meldung}`));\n z.push('');\n}\nz.push('Kein Beitrag wurde veroeffentlicht. Alle Importe stehen auf Entwurf.');\n\nreturn [{ json: {\n betreff: `Skrift Ratgeber: ${s.anzahl_importiert} Entwurf/Entwuerfe`\n + (s.anzahl_nachbessern ? `, ${s.anzahl_nachbessern} zum Nachbessern` : '')\n + (s.anzahl_fehler ? `, ${s.anzahl_fehler} Fehler` : ''),\n text: z.join('\\n') }}];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
@@ -1091,7 +1394,7 @@
|
||||
2000,
|
||||
80
|
||||
],
|
||||
"id": "86c65a05-ec2b-49fd-9134-0538d0be1065",
|
||||
"id": "3384fccd-d896-4c44-9c89-f91946e5d986",
|
||||
"name": "Meldung formulieren"
|
||||
},
|
||||
{
|
||||
@@ -1109,7 +1412,7 @@
|
||||
2220,
|
||||
80
|
||||
],
|
||||
"id": "0a421a3c-7f3a-4cc0-b3ca-edd79e6a4584",
|
||||
"id": "d2da0c0a-1998-405c-b585-7c8d7bbc834c",
|
||||
"name": "Benachrichtigung",
|
||||
"disabled": true,
|
||||
"notes": "SMTP-Credential zuweisen, Absender eintragen, dann aktivieren."
|
||||
@@ -1491,17 +1794,6 @@
|
||||
]
|
||||
]
|
||||
},
|
||||
"Importergebnis merken": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Pause Rate Limit",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Nachbesserung gemerkt": {
|
||||
"main": [
|
||||
[
|
||||
@@ -1557,6 +1849,148 @@
|
||||
]
|
||||
]
|
||||
},
|
||||
"Importergebnis merken": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Beitragsbild fehlt?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Beitragsbild fehlt?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bilddaten laden",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Pause Rate Limit",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bilddaten laden": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bildprompt bauen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bildprompt bauen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bildprompt vorhanden?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bildprompt vorhanden?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bild erzeugen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Pause Rate Limit",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bild erzeugen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bild als Datei",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Fehler Bild",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Fehler Bild": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Pause Rate Limit",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bild als Datei": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bild in Mediathek",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bild in Mediathek": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Beitragsbild setzen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Beitragsbild setzen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Bild gemerkt",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Bild gemerkt": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Pause Rate Limit",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Ergebnisse sammeln": {
|
||||
"main": [
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user