The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Tagging_2",
"nodes": [
{
"parameters": {
"content": "## Datenbank anfragen",
"height": 360,
"width": 440
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-544,
768
],
"id": "a4717fd3-f28d-4bdc-a3a4-7ff38fc1220e",
"name": "Sticky Note"
},
{
"parameters": {
"jsCode": "/*\n=========================================================\nSINGLE ITEM PICKER & CLEANER\n- Sucht den ersten Eintrag, der noch nicht 'processed'='ok' ist\n- Reinigt alle Felder dieses Eintrags\n- Bereitet den Kontext-String f\u00fcr das LLM vor\n=========================================================\n*/\n\n// KONFIGURATION\nconst statusFieldName = 'processed'; // Deine Kontrollspalte\nconst targetStatus = 'ok'; // Der Wert, den erledigte Zeilen haben\n\n// Felder, die wir NICHT im Prompt wollen (technisches Zeug)\nconst excludedFromPrompt = [\n \"processed\", \n \"SO URL\", \n \"API URL\", \n \"Image URL\", \n \"Bildlink\", \n \"ID\",\n \"row_scan\",\n \"_id\",\n statusFieldName // Die Kontrollspalte selbst auch nicht\n];\n\n// 1. Input holen\nconst items = $input.all();\nlet targetItem = null;\n\n// 2. SEARCH LOOP: Finde das erste \"offene\" Item\nfor (const item of items) {\n const currentStatus = item.json[statusFieldName];\n \n // Bedingung: Wenn Status leer ist ODER ungleich 'ok'\n if (!currentStatus || currentStatus !== targetStatus) {\n targetItem = item;\n break; // WICHTIG: Sofort stoppen, wir wollen nur einen!\n }\n}\n\n// Wenn alle schon erledigt sind (\"ok\"), geben wir nichts zur\u00fcck -> Workflow stoppt hier meist\nif (!targetItem) {\n return [];\n}\n\n// -------------------------------------------------------\n// AB HIER: Reinigung nur f\u00fcr das gefundene targetItem\n// -------------------------------------------------------\n\n// Hilfsfunktion: Text reinigen\nfunction cleanText(text) {\n if (text === null || text === undefined) return \"Keine Angabe\";\n let cleaned = String(text);\n cleaned = cleaned.replace(/[\\u200B\\u00A0]/g, ' '); // Zero Width Spaces weg\n return cleaned.trim();\n}\n\nconst originalJson = targetItem.json;\nconst cleanJson = {};\nlet contextLines = [];\n\n// Dynamisch \u00fcber ALLE Spalten iterieren\nfor (const key of Object.keys(originalJson)) {\n const rawValue = originalJson[key];\n \n // Wert reinigen\n const cleanValue = cleanText(rawValue);\n \n // In das saubere JSON-Objekt speichern\n cleanJson[key] = cleanValue;\n\n // Entscheiden, ob es in den Kontext-String kommt\n if (cleanValue !== \"Keine Angabe\" && cleanValue !== \"\" && !excludedFromPrompt.includes(key)) {\n contextLines.push(`${key}: ${cleanValue}`);\n }\n}\n\n// Den Context-String zusammenbauen\nconst contextString = contextLines.join('\\n');\n\n// Daten in das Item schreiben\ntargetItem.json.metadata_clean = cleanJson; \ntargetItem.json.context_data_string = contextString; \n\n// WICHTIG: Wir geben ein Array zur\u00fcck, das NUR dieses eine Item enth\u00e4lt\nreturn [targetItem];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-272,
928
],
"id": "a8132357-340c-4c12-8da0-f860f0d538cd",
"name": "Code6"
},
{
"parameters": {
"operation": "list",
"tableName": "metadata",
"viewName": "ok",
"options": {
"simple": false
}
},
"type": "n8n-nodes-base.seaTable",
"typeVersion": 2,
"position": [
-464,
928
],
"id": "77667500-4fc3-44d3-be84-9081525deb0a",
"name": "Get many rows",
"credentials": {
"seaTableApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-720,
928
],
"id": "6397e814-120b-4eca-aab0-a34d257f5666",
"name": "Schedule Trigger"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "5TaVWQNKBGBnRxPV",
"mode": "list"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"Bildlink": "={{ $json.Bildlink }}",
"metadata_clean": "={{ $('Code6').item.json.metadata_clean }}",
"context_data_string": "={{ $('Code6').item.json.context_data_string }}",
"metadata_clean__id": "={{ $('Code6').item.json.metadata_clean._id }}"
},
"matchingColumns": [
"Bildlink",
"metadata_clean",
"context_data_string",
"metadata_clean__id"
],
"schema": [
{
"id": "Bildlink",
"displayName": "Bildlink",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "metadata_clean",
"displayName": "metadata_clean",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "context_data_string",
"displayName": "context_data_string",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "metadata_clean__id",
"displayName": "metadata_clean__id",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
0,
928
],
"name": "Call Tagging_Sub2",
"id": "0d4c450a-6cdf-4ce5-bc9b-41ffb138a673"
},
{
"parameters": {
"amount": 2
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
0,
1152
],
"id": "5f3aaede-6d53-4da4-8f4c-66ecfd63d1f2",
"name": "Wait"
}
],
"connections": {
"Code6": {
"main": [
[
{
"node": "Call Tagging_Sub2",
"type": "main",
"index": 0
}
]
]
},
"Get many rows": {
"main": [
[
{
"node": "Code6",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get many rows",
"type": "main",
"index": 0
}
]
]
},
"Call Tagging_Sub2": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Get many rows",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "902aea4b-0a01-43d3-a85e-0746d58af5b4",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "9Mi6pHBkQW8K4lYM",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
seaTableApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Tagging_2. Uses seaTable. Scheduled trigger; 6 nodes.
Source: https://github.com/sebastianruffberlin/AI-Museum-Tagging/blob/8338053d8ebe7c5b335249bd73cb4cf8f05881c4/workflows/Tagging_2.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This template is an interactive playground designed to help you master the most useful keyboard shortcuts in n8n and supercharge your building speed. Forget boring lists—this workflow gives you hands-
Perfect for content publishing with organic scheduling patterns, social media automation, API systems that need to avoid rate limiting, or any automation requiring randomised timing control across mul
Complete backup solution that saves both workflows and credentials to local/server disk with optional FTP upload for off-site redundancy.
This workflow enables you to listen to your recent favorites in very hight quality offline without sacrificing all of your storage.
WF-Main - XHS 主控制器. Uses scheduleTrigger, httpRequest, executeWorkflow, noOp. Scheduled trigger; 21 nodes.