Kapitel 10/Strem Reminder Premium.json hinzugefügt
This commit is contained in:
688
Kapitel 10/Strem Reminder Premium.json
Normal file
688
Kapitel 10/Strem Reminder Premium.json
Normal file
@@ -0,0 +1,688 @@
|
||||
{
|
||||
"name": "My workflow",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"field": "minutes",
|
||||
"minutesInterval": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
640,
|
||||
256
|
||||
],
|
||||
"id": "2d3ac9d8-0d79-40dd-8213-e14493a1e8b0",
|
||||
"name": "Schedule Trigger"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://id.twitch.tv/oauth2/token",
|
||||
"sendBody": true,
|
||||
"contentType": "form-urlencoded",
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "client_id",
|
||||
"value": "qmy3gi7t40180kqmglyqqd2ayuokud"
|
||||
},
|
||||
{
|
||||
"name": "client_secret",
|
||||
"value": "rj4x8x1uyfadl67qeqr52ef4jfpzmv"
|
||||
},
|
||||
{
|
||||
"name": "grant_type",
|
||||
"value": "client_credentials"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
1216,
|
||||
160
|
||||
],
|
||||
"id": "dabbbc0c-b6f2-41b4-98f1-69f822b654b7",
|
||||
"name": "Access Token"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "=https://api.twitch.tv/helix/schedule",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "oAuth2Api",
|
||||
"sendQuery": true,
|
||||
"queryParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "broadcaster_id",
|
||||
"value": "468013650"
|
||||
},
|
||||
{
|
||||
"name": "start_time",
|
||||
"value": "={{ $now.toUTC().startOf('day').toISO() }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Client-ID",
|
||||
"value": "qmy3gi7t40180kqmglyqqd2ayuokud"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"responseFormat": "text",
|
||||
"outputPropertyName": "body"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
1808,
|
||||
256
|
||||
],
|
||||
"id": "235dd7fb-12f3-4afb-8eba-dbd81ded658e",
|
||||
"name": "Termine laden",
|
||||
"credentials": {
|
||||
"httpBearerAuth": {
|
||||
"id": "nIGvz1OpeNp0rRNd",
|
||||
"name": "Bearer Auth account"
|
||||
},
|
||||
"oAuth2Api": {
|
||||
"id": "yno3OtiN2TqTOGUP",
|
||||
"name": "Twitch"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Speichert neuen Token + Ablaufzeit in Workflow-Static-Data\nconst sd = $getWorkflowStaticData('global');\n\nconst access = $json.access_token;\nconst ttlSec = Number($json.expires_in || 0);\n\n// Puffer ist hier nicht nötig, weil wir täglich prüfen und bei <24h erneuern\nconst expISO = new Date(Date.now() + ttlSec*1000).toISOString();\n\nsd.twitch_token = access;\nsd.twitch_expires_at = expISO;\n\nconst msLeft = (new Date(expISO).getTime() - Date.now());\nconst hoursLeft = msLeft / (1000*60*60);\n\nreturn [{\n json: {\n token: access,\n expires_at: expISO,\n hoursLeft: Number(hoursLeft.toFixed(2))\n }\n}];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1392,
|
||||
160
|
||||
],
|
||||
"id": "5d926795-c3be-4fe9-97e3-61374c47728e",
|
||||
"name": "Token speichern"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "81523d9e-67f7-48b7-8a3a-2d8329f88e9c",
|
||||
"name": "token",
|
||||
"value": "={{$json.token}}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "fac52dff-193d-49c0-af6a-cb6b51fa4fc7",
|
||||
"name": "expires_at",
|
||||
"value": "={{$json.expires_at}}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "95285159-b09f-4c02-8790-355661d71a38",
|
||||
"name": "hoursLeft",
|
||||
"value": "={{$json.hoursLeft}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
1296,
|
||||
336
|
||||
],
|
||||
"id": "c9c6995c-e5f6-4d28-9f92-8f866deb771e",
|
||||
"name": "Token aus Cache"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Liest gespeicherten Token aus Workflow-Static-Data und berechnet Restlaufzeit\nconst sd = $getWorkflowStaticData('global');\nconst token = sd.twitch_token || '';\nconst expISO = sd.twitch_expires_at || '';\nconst expMs = expISO ? new Date(expISO).getTime() : 0;\n\nconst now = Date.now();\nconst msLeft = expMs ? (expMs - now) : 0;\nconst hoursLeft = msLeft > 0 ? (msLeft / (1000*60*60)) : 0;\n\n// true, wenn es keinen Token gibt ODER weniger als 24h übrig sind\nconst needsRefresh = !token || !expMs || hoursLeft < 24;\n\nreturn [{\n json: {\n needsRefresh,\n token,\n expires_at: expISO,\n hoursLeft: Number(hoursLeft.toFixed(2))\n }\n}];\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
832,
|
||||
256
|
||||
],
|
||||
"id": "15a8c0da-fef0-4219-be31-d5ae047ce242",
|
||||
"name": "Access Token prüfen"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 2
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "b542f5d2-789c-4a00-b8eb-3923727306f4",
|
||||
"leftValue": "={{$json.needsRefresh}}",
|
||||
"rightValue": "true",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "or"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
1008,
|
||||
256
|
||||
],
|
||||
"id": "ce16840f-c37d-4b0a-9f3d-c887c7acfb52",
|
||||
"name": "Access Token erneunern"
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1600,
|
||||
256
|
||||
],
|
||||
"id": "880bcf94-2c74-4f49-9a52-e7d86008021e",
|
||||
"name": "Token bereitstellen"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "/**\n * INPUT: items[0].json ODER items[0].json.body (String) vom HTTP Request /helix/schedule\n * OUTPUT: pro Segment ein Item in deinem Schema:\n * { uid, cancelled, title, description, startIso, endIso, tz, hash }\n */\n\nconst input = items[0]?.json ?? {};\nlet payload;\n\nif (typeof input.body === 'string') {\n // HTTP-Node hat \"Response Format: Text\" -> JSON-String in body\n try { payload = JSON.parse(input.body); }\n catch (e) { throw new Error('HTTP body ist kein gültiges JSON'); }\n} else if (input.data) {\n // HTTP-Node hat \"Response Format: JSON\"\n payload = input;\n} else if (typeof input === 'string') {\n payload = JSON.parse(input);\n} else {\n throw new Error('Unerwartete Eingabeform. Erwartet JSON oder body-String.');\n}\n\nconst segments = Array.isArray(payload.data?.segments) ? payload.data.segments : [];\n\n// Hash wie in deinem ICS-Code\nfunction hashHex(s) {\n let h = 5381;\n for (let i = 0; i < s.length; i++) h = ((h << 5) + h) ^ s.charCodeAt(i);\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction buildTitle() { return 'Streamtime'; }\n\nfunction buildDesc(seg) {\n const lines = [];\n if (seg.title) lines.push(`Originaltitel: ${seg.title}`);\n if (seg.category?.name) lines.push(`Kategorie/Game: ${seg.category.name}`);\n return lines.join('\\n');\n}\n\nconst tz = 'Europe/Berlin';\n\nconst out = segments.map(seg => {\n const startIso = seg.start_time; // ISO-UTC laut Twitch\n const endIso = seg.end_time;\n const title = buildTitle();\n const description = buildDesc(seg);\n const hash = hashHex(`${title}|${startIso}|${endIso}|${description}`);\n const kategorie = seg.category?.name;\n return {\n json: {\n uid: seg.id,\n cancelled: Boolean(seg.canceled_until),\n title, description,\n startIso, endIso, tz,\n hash, kategorie \n }\n };\n});\n\nreturn out;\n"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1984,
|
||||
256
|
||||
],
|
||||
"id": "96fe4d28-a423-4bb2-863c-14e9111c94c7",
|
||||
"name": "Parse ICS",
|
||||
"alwaysOutputData": false
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "/**\n * INPUT: Array von Items aus \"Parse ICS\"\n * OUTPUT: nur das nächste bevorstehende Event\n */\n\nconst now = Date.now();\n\nconst upcoming = items\n .map(i => i.json)\n .filter(e => !e.cancelled && new Date(e.startIso).getTime() > now)\n .sort((a, b) => new Date(a.startIso) - new Date(b.startIso));\n\nif (upcoming.length === 0) {\n return [{ json: { message: 'Kein bevorstehender Stream gefunden' } }];\n}\n\nconst next = upcoming[0];\n\nreturn [{\n json: {\n uid: next.uid,\n title: next.title,\n kategroie: next.kategorie,\n description: next.description,\n startIso: next.startIso,\n endIso: next.endIso,\n tz: next.tz,\n hash: next.hash\n }\n}];"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2192,
|
||||
256
|
||||
],
|
||||
"id": "b1aaf439-5c1f-495f-9d7e-a4d425588b0a",
|
||||
"name": "Nächstes Event finden"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "/**\n * Prüft:\n * 1. Startet der Stream in ≤ 30 Minuten?\n * 2. Wurde bereits ein Post erstellt?\n *\n * Zeitumwandlung: Twitch liefert UTC (\"2025-10-15T16:00:00Z\").\n * Wir rechnen in lokale Zeit (Europe/Berlin), um MEZ/MESZ korrekt zu berücksichtigen.\n */\n\nconst event = items[0]?.json ?? {};\nif (!event.startIso) {\n\treturn [{\n\t\tjson: {\n\t\t\tpostAllowed: false,\n\t\t\treason: 'Kein Termin gefunden'\n\t\t}\n\t}];\n}\n\n// Aktuelle Zeit + Startzeit in lokale Zeitzone überführen\nconst tz = 'Europe/Berlin';\nconst now = new Date(); // lokale Zeit des n8n-Servers\nconst startUtc = new Date(event.startIso);\n\n// Startzeit in lokales Format (inkl. Sommer-/Winterzeit)\nconst startLocal = new Date(startUtc.toLocaleString('en-US', { timeZone: tz }));\n\n// Differenz in Minuten\nconst diffMin = (startLocal - now) / 60000;\nconst within30 = diffMin > 0 && diffMin <= 30;\n\n// Zugriff auf global gespeicherte IDs\nconst sd = $getWorkflowStaticData('global');\nsd.postedIds = sd.postedIds || [];\n\nconst alreadyPosted = sd.postedIds.includes(event.uid);\n\n// Wenn innerhalb von 30 Minuten und noch kein Post → erlauben\nif (within30 && !alreadyPosted) {\n\tsd.postedIds.push(event.uid);\n\treturn [{\n\t\tjson: {\n\t\t\t...event,\n\t\t\tpostAllowed: true,\n\t\t\treason: 'Stream startet bald, noch kein Post vorhanden',\n\t\t\tlocalStart: startLocal.toISOString(),\n\t\t\tdiffMinutes: Math.round(diffMin)\n\t\t}\n\t}];\n}\n\n// Keine Aktion notwendig\nreturn [{\n\tjson: {\n\t\t...event,\n\t\tpostAllowed: false,\n\t\treason: alreadyPosted\n\t\t\t? 'Für diesen Stream wurde bereits gepostet'\n\t\t\t: 'Stream liegt außerhalb des 30-Minuten-Fensters',\n\t\tlocalStart: startLocal.toISOString(),\n\t\tdiffMinutes: Math.round(diffMin)\n\t}\n}];"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2400,
|
||||
256
|
||||
],
|
||||
"id": "e86d62a4-9103-44a2-abe6-eef933c05d33",
|
||||
"name": "Stream prüfen"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 2
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "3578de2a-a878-419d-9e1d-bf734a9f8096",
|
||||
"leftValue": "={{ $json.postAllowed }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
"type": "boolean",
|
||||
"operation": "true",
|
||||
"singleValue": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
2608,
|
||||
256
|
||||
],
|
||||
"id": "81577108-fdab-4b7f-bf6a-2c4a75be1d3b",
|
||||
"name": "If"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "download",
|
||||
"path": "/n8n/posts.txt"
|
||||
},
|
||||
"type": "n8n-nodes-base.nextCloud",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
3296,
|
||||
96
|
||||
],
|
||||
"id": "b3694213-54fb-4987-98b3-156b7d49119d",
|
||||
"name": "Download a file",
|
||||
"credentials": {
|
||||
"nextCloudApi": {
|
||||
"id": "j4cdlVf8Sw2OpA0m",
|
||||
"name": "NextCloud account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "/**\n * Liest posts.txt direkt aus dem Binary-Feld \"data\" (vom Nextcloud-Node)\n * und wählt zufällig eine Zeile aus.\n * Wenn keine Datei oder kein Inhalt vorhanden ist, wird ein Fallback-Text aus einer Liste genutzt.\n * Zusätzlich wird der Startzeitpunkt des Streams in lokaler Zeit (MEZ/MESZ) angehängt.\n */\n\nlet content = '';\ntry {\n const buffer = items[0].binary?.data?.data;\n if (buffer) {\n content = Buffer.from(buffer, 'base64').toString('utf8');\n }\n} catch (err) {\n content = '';\n}\n\n// Inhalt in Zeilen aufteilen\nconst lines = content.split('\\n').map(l => l.trim()).filter(Boolean);\n\n// Fallback-Texte\nconst fallbackPosts = [\n 'Der Stream startet gleich – holt euch Snacks und seid dabei! 🎮',\n 'Bald geht’s los – heute wird wieder gezockt! 🔥',\n 'Noch kurz durchatmen – gleich geht’s live auf Sendung! 🚀',\n 'In wenigen Minuten live – Kaffee bereit? ☕',\n 'Los geht’s – der Chat wartet schon auf euch! 💬',\n 'Heute gibt’s wieder gute Laune und Gaming pur! 💜'\n];\n\n// Textauswahl\nlet postText;\nif (lines.length > 0) {\n const randomIndex = Math.floor(Math.random() * lines.length);\n postText = lines[randomIndex];\n} else {\n const randomIndex = Math.floor(Math.random() * fallbackPosts.length);\n postText = fallbackPosts[randomIndex];\n}\n\n// Startzeitpunkt des Streams aus vorherigem Node lesen (startIso)\nlet startIso = items[0].json?.startIso || null;\nlet startLocal = '';\n\nif (startIso) {\n try {\n const date = new Date(startIso);\n const formatter = new Intl.DateTimeFormat('de-DE', {\n weekday: 'short',\n hour: '2-digit',\n minute: '2-digit',\n timeZone: 'Europe/Berlin',\n hour12: false\n });\n startLocal = formatter.format(date);\n } catch (err) {\n startLocal = '';\n }\n}\n\nif (startLocal) {\n postText = `${postText} 🎬 Start: ${startLocal}`;\n}\n\n// Weitergabe an nächste Nodes\nreturn [{\n json: {\n ...items[0].json,\n postText\n }\n}];"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
3440,
|
||||
96
|
||||
],
|
||||
"id": "10583c07-00f8-4b74-9397-a0fb8804ddb4",
|
||||
"name": "Posttext auswählen"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"text": "={{ $json.postText }}",
|
||||
"additionalFields": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.twitter",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
3824,
|
||||
240
|
||||
],
|
||||
"id": "14f6ea83-a1fc-4d9c-a8e4-49fea946ab8b",
|
||||
"name": "X – Post veröffentlichen",
|
||||
"credentials": {
|
||||
"twitterOAuth2Api": {
|
||||
"id": "FBWhPuyEfuMJFdKU",
|
||||
"name": "X account"
|
||||
}
|
||||
},
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return items.map(item => {\n if (item.binary && item.binary.data) {\n delete item.binary.data; // Entfernt die heruntergeladene Datei aus dem Speicher\n }\n return item;\n});"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
4000,
|
||||
240
|
||||
],
|
||||
"id": "8dd18b30-a935-4bd3-8d6c-8abd11890de4",
|
||||
"name": "Code"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"model": "openai/gpt-5",
|
||||
"message": "=Erstelle einen Social-Media-Post auf Deutsch für folgendes Event.\nStil: freundlich, prägnant. Maximal 5 Hashtags mit größter Wirkung nach Analyse\n\nTitel: {{$json[\"title\"]}}\nDatum: {{ $json.startIso }} -> Umwandeln in Datum und Uhrzeit in Lokale Deutsche Zeit. Du brauchst nur die Uhrzeit nennen.\nKategorie: {{ $json.kategroie }}\nGib nur den fertigen Posttext zurück.",
|
||||
"additionalFields": {}
|
||||
},
|
||||
"type": "n8n-nodes-openrouter.openRouter",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
2832,
|
||||
240
|
||||
],
|
||||
"id": "11a0ef0f-3ae9-4e32-b4fd-798bab071824",
|
||||
"name": "OpenRouter",
|
||||
"credentials": {
|
||||
"openRouterApi": {
|
||||
"id": "R0cVyDA0VSYbr7mU",
|
||||
"name": "OpenRouter account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 2
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "e0770cc0-48c8-4125-901c-ebecefd1c63d",
|
||||
"leftValue": "={{ $json.response }}",
|
||||
"rightValue": "=",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "empty",
|
||||
"singleValue": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "or"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
3024,
|
||||
240
|
||||
],
|
||||
"id": "9185cd5b-9d60-4420-b706-e3870296b5d5",
|
||||
"name": "If1"
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"type": "n8n-nodes-base.merge",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
3632,
|
||||
240
|
||||
],
|
||||
"id": "6adb701c-008b-484b-a298-f6abdb686e14",
|
||||
"name": "Merge"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "b65c163c-63fc-4c0e-a95b-6d70f5f11086",
|
||||
"name": "postText",
|
||||
"value": "={{ $json.response }}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
3360,
|
||||
256
|
||||
],
|
||||
"id": "105f9693-777b-4694-b4d0-84584b22fea3",
|
||||
"name": "Edit Fields"
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Access Token prüfen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Access Token": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Token speichern",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Termine laden": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse ICS",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Token speichern": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Token bereitstellen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Token aus Cache": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Token bereitstellen",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Access Token prüfen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Access Token erneunern",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Access Token erneunern": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Access Token",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Token aus Cache",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Token bereitstellen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Termine laden",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse ICS": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Nächstes Event finden",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Nächstes Event finden": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Stream prüfen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Stream prüfen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"If": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "OpenRouter",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Download a file": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Posttext auswählen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Posttext auswählen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"X – Post veröffentlichen": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"OpenRouter": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"If1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Download a file",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Merge",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Merge": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "X – Post veröffentlichen",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"timezone": "Europe/Berlin",
|
||||
"callerPolicy": "workflowsFromSameOwner"
|
||||
},
|
||||
"versionId": "fb5ad769-df0b-4258-8d3e-80b8b9899ef2",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "4edc03810a5a67ca6728ea68a9aec5a82547f97ec5ae65df9f22d521c302e706"
|
||||
},
|
||||
"id": "ITXQNyneGAVBMnoa",
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user