Files
n8n-workflows/Contact-cards.json
T
adminjeroen f0ac7ae4af Upload files to "/"
Maakt een html file aan een upload die naar een map die vervolgens een visitekaartje toont.
2026-08-05 09:07:33 +02:00

136 lines
21 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"name": "Contact-cards",
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-352,
-368
],
"id": "f1141f30-1190-4aa5-beba-c5cd71b5d2da",
"name": "When clicking Execute workflow"
},
{
"parameters": {
"jsCode": "// n8n Code node (run once per item)\n// Input (minimaal):\n// name, title, company, email, website, street, postcode, city\n// telefoons (ruw): workTel (of phone), companyTel, mobile (optioneel)\n// social (optioneel): facebookUrl, linkedinUrl\n// slug (optioneel)\n\nfunction initials(name) {\n const p = String(name || \"\").trim().split(/\\s+/).filter(Boolean);\n if (!p.length) return \"\";\n if (p.length === 1) return p[0].slice(0, 2).toUpperCase();\n return (p[0][0] + p[p.length - 1][0]).toUpperCase();\n}\n\nfunction slugify(s) {\n return String(s || \"\")\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nfunction escHtml(v) {\n return String(v ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nfunction digits(s) {\n return String(s || \"\").replace(/\\D+/g, \"\");\n}\n\nfunction toE164NL(raw) {\n const d = digits(raw);\n if (!d) return \"\";\n if (String(raw || \"\").trim().startsWith(\"+\")) return String(raw).trim();\n if (d.startsWith(\"0\")) return \"+31\" + d.slice(1);\n if (d.startsWith(\"31\")) return \"+\" + d;\n return \"+\" + d;\n}\n\nfunction formatNLDisplay(raw) {\n const d = digits(raw);\n if (!d) return \"\";\n if (d.length === 10 && d.startsWith(\"088\")) return `${d.slice(0, 3)} ${d.slice(3, 6)} ${d.slice(6)}`;\n if (d.length === 10 && d.startsWith(\"06\")) return `${d.slice(0, 2)} ${d.slice(2)}`;\n return String(raw || \"\");\n}\n\nconst d0 = items[0].json;\n\nconst company = d0.company || \"De Wit Transport\";\nconst name = d0.name || \"\";\nconst title = d0.title || \"\";\nconst email = d0.email || \"\";\nconst website = d0.website || \"\";\n\nconst workTelRaw = d0.workTel ?? d0.phone ?? \"\";\nconst mobileRaw = d0.mobile ?? \"\";\nconst companyTelRaw = d0.companyTel ?? \"\";\n\nconst slug = d0.slug ? slugify(d0.slug) : slugify(name);\nconst cardUrl = d0.cardUrl || `https://cards.tmsconnector.nl/${slug}`;\n\nconst mapsQuery = `${d0.street || \"\"} ${d0.postcode || \"\"} ${d0.city || \"\"}`.trim();\nconst mapsUrl = d0.mapsUrl || `https://www.google.com/maps?q=${encodeURIComponent(mapsQuery)}`;\n\nconst workTelE164 = d0.workTelE164 || toE164NL(workTelRaw);\nconst workTelDisplay = d0.workTelDisplay || formatNLDisplay(workTelRaw) || workTelRaw;\n\nconst mobileE164 = d0.mobileE164 || (mobileRaw ? toE164NL(mobileRaw) : \"\");\nconst mobileDisplay = d0.mobileDisplay || (mobileRaw ? formatNLDisplay(mobileRaw) : \"\");\n\nconst companyTelE164 = d0.companyTelE164 || (companyTelRaw ? toE164NL(companyTelRaw) : \"\");\nconst companyTelDisplay = d0.companyTelDisplay || (companyTelRaw ? formatNLDisplay(companyTelRaw) : \"\");\n\nconst facebookUrl = d0.facebookUrl ?? \"https://www.facebook.com/profile.php?id=100063917050863\";\nconst linkedinUrl = d0.linkedinUrl ?? \"https://www.linkedin.com/company/de-wit-transport/\";\n\n// ==== Umami config ====\nconst UMAMI_SCRIPT = \"https://analytics.tmsconnector.nl/script.js\";\nconst UMAMI_WEBSITE_ID = \"27321573-6471-41b3-9e0d-0e2c57615d14\";\nconst UMAMI_DOMAINS = \"cards.tmsconnector.nl,card.dewittransport.nl\";\n\n// ==== CSS versie ====\nconst CSS_VERSION = \"20260310-1\";\n\nconst html = `<!doctype html>\n<html lang=\"nl\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n <title>Visitekaartje | ${escHtml(name)}</title>\n\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=Raleway:wght@500;700;800&display=swap\" rel=\"stylesheet\">\n\n <link rel=\"icon\" href=\"/assets/favicon.svg\" type=\"image/svg+xml\">\n <link rel=\"icon\" href=\"/assets/favicon.png\" type=\"image/png\">\n <link rel=\"apple-touch-icon\" href=\"/assets/favicon.png\">\n <meta name=\"theme-color\" content=\"#15A1EE\">\n\n <link rel=\"stylesheet\" href=\"/assets/dewit-card.css?v=${CSS_VERSION}\" />\n\n <script\n defer\n src=\"${UMAMI_SCRIPT}\"\n data-website-id=\"${UMAMI_WEBSITE_ID}\"\n data-domains=\"${UMAMI_DOMAINS}\">\n </script>\n</head>\n<body>\n <main class=\"page\">\n <section class=\"card\" aria-label=\"Visitekaartje\">\n <header class=\"topbar\">\n <div class=\"logo\">\n <img src=\"/assets/dewit-logo.svg\" alt=\"${escHtml(company)}\"\n onerror=\"this.style.display='none'; this.nextElementSibling.style.display='block';\" />\n <div class=\"fallback\" style=\"display:none;\">${escHtml(company)}</div>\n </div>\n </header>\n\n <div class=\"linkbar\" aria-label=\"Links\">\n <a id=\"webLink\"\n href=\"${escHtml(website)}\"\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label=\"Website\"\n data-umami-event=\"click_website\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm7.7 9h-3.2a15 15 0 0 0-1.1-5 8 8 0 0 1 4.3 5ZM12 4c1 1.3 1.8 3.7 2.1 7H9.9C10.2 7.7 11 5.3 12 4Zm-3.4 2a15 15 0 0 0-1.1 5H4.3a8 8 0 0 1 4.3-5ZM4.3 13h3.2a15 15 0 0 0 1.1 5 8 8 0 0 1-4.3-5Zm7.7 7c-1-1.3-1.8-3.7-2.1-7h4.2c-.3 3.3-1.1 5.7-2.1 7Zm3.4-2a15 15 0 0 0 1.1-5h3.2a8 8 0 0 1-4.3 5Z\"/></svg>\n </a>\n\n <a id=\"fbLink\"\n href=\"${escHtml(facebookUrl)}\"\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label=\"Facebook\"\n data-umami-event=\"click_facebook\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M13.5 22v-8h2.7l.4-3h-3.1V9.1c0-.9.2-1.5 1.6-1.5H16.7V5c-.3 0-1.3-.1-2.4-.1-2.4 0-4.1 1.5-4.1 4.2V11H7.5v3h2.7v8h3.3z\"/></svg>\n </a>\n\n <a id=\"liLink\"\n href=\"${escHtml(linkedinUrl)}\"\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label=\"LinkedIn\"\n data-umami-event=\"click_linkedin\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M6.5 9H3.9v12h2.6V9zM5.2 3.8C4.3 3.8 3.6 4.5 3.6 5.4S4.3 7 5.2 7s1.6-.7 1.6-1.6-.7-1.6-1.6-1.6zM20.6 21v-6.8c0-3.6-1.9-5.2-4.4-5.2-2 0-2.9 1.1-3.4 1.9V9H10.2c0 1.2 0 12 0 12h2.6v-6.7c0-.4 0-.8.1-1.1.3-.8 1-1.7 2.2-1.7 1.6 0 2.2 1.2 2.2 2.9V21h3.3z\"/></svg>\n </a>\n </div>\n\n <div class=\"content\">\n <div class=\"header\">\n <div class=\"identity\">\n <h1>${escHtml(name)}</h1>\n ${title ? `<p>${escHtml(title)}</p>` : \"\"}\n </div>\n <div class=\"avatar\" aria-hidden=\"true\">${escHtml(initials(name))}</div>\n </div>\n\n <div class=\"sections\">\n <div class=\"section\">\n <h2>Contactgegevens</h2>\n <ul class=\"list\">\n <li class=\"item\">\n <svg class=\"icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1H2z\"/></svg>\n <div class=\"value\">\n <a href=\"mailto:${escHtml(email)}\" data-umami-event=\"click_email\">${escHtml(email)}</a>\n <div class=\"small\">E-mail</div>\n </div>\n </li>\n\n <li class=\"item\" id=\"mobileRow\">\n <svg class=\"icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M11 1H5C4.4 1 4 1.4 4 2v12c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zm0 12H5V3h6v10z\"/></svg>\n <div class=\"value\">\n <a href=\"tel:${escHtml(mobileE164)}\" data-umami-event=\"click_mobile\">${escHtml(mobileDisplay)}</a>\n <div class=\"small\">Mobiel</div>\n </div>\n </li>\n\n <li class=\"item\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.7-.4 1.1-.3 1.2.4 2.4.6 3.7.6.6 0 1.2.5 1.2 1.2V20c0 .7-.5 1.2-1.2 1.2C10.7 21.2 2.8 13.3 2.8 3.2 2.8 2.5 3.3 2 4 2h3.4c.7 0 1.2.5 1.2 1.2 0 1.3.2 2.5.6 3.7.1.4 0 .8-.3 1.1L6.6 10.8z\"/></svg>\n <div class=\"value\">\n <a href=\"tel:${escHtml(workTelE164)}\" data-umami-event=\"click_workphone\">${escHtml(workTelDisplay)}</a>\n <div class=\"small\">Direct</div>\n </div>\n </li>\n </ul>\n </div>\n\n <div class=\"section\">\n <h2>Adres</h2>\n <ul class=\"list\">\n <li class=\"item\">\n <svg class=\"icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M8 0a5.5 5.5 0 0 0-5.5 5.5c0 4.2 5.5 10.5 5.5 10.5S13.5 9.7 13.5 5.5A5.5 5.5 0 0 0 8 0zm0 7.5A2 2 0 1 1 8 3.5a2 2 0 0 1 0 4z\"/></svg>\n <div class=\"value\">\n <div>${escHtml(d0.street || \"\")}</div>\n <div class=\"small\">${escHtml(d0.postcode || \"\")} ${escHtml(d0.city || \"\")}</div>\n <div class=\"small\">\n <a href=\"${escHtml(mapsUrl)}\" target=\"_blank\" rel=\"noreferrer\" data-umami-event=\"click_route\">Routebeschrijving</a>\n </div>\n </div>\n </li>\n\n <li class=\"item\" id=\"companyPhoneRow\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.7-.4 1.1-.3 1.2.4 2.4.6 3.7.6.6 0 1.2.5 1.2 1.2V20c0 .7-.5 1.2-1.2 1.2C10.7 21.2 2.8 13.3 2.8 3.2 2.8 2.5 3.3 2 4 2h3.4c.7 0 1.2.5 1.2 1.2 0 1.3.2 2.5.6 3.7.1.4 0 .8-.3 1.1L6.6 10.8z\"/></svg>\n <div class=\"value\">\n <a href=\"tel:${escHtml(companyTelE164)}\" data-umami-event=\"click_companyphone\">${escHtml(companyTelDisplay)}</a>\n <div class=\"small\">Hoofdnummer</div>\n </div>\n </li>\n </ul>\n </div>\n </div>\n </div>\n\n <div class=\"actionbar\">\n <button class=\"btn primary\" type=\"button\" id=\"btnSave\">Voeg toe aan contacten</button>\n <button class=\"btn\" type=\"button\" id=\"btnShare\">Delen</button>\n </div>\n </section>\n </main>\n\n <div class=\"modal-backdrop\" id=\"shareBackdrop\" aria-hidden=\"true\">\n <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Delen\">\n <div class=\"modal-header\">\n <div class=\"modal-title\">Deel dit kaartje</div>\n <button class=\"modal-close\" type=\"button\" id=\"btnClose\">×</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"qrbox\">\n <canvas id=\"qrcode\" aria-label=\"QR-code\"></canvas>\n <div class=\"shareurl\" id=\"shareUrl\"></div>\n <div class=\"modal-actions\">\n <button class=\"btn\" type=\"button\" id=\"btnCopy\">Kopieer link</button>\n <button class=\"btn primary\" type=\"button\" id=\"btnNativeShare\">Delen…</button>\n </div>\n <div class=\"small\" id=\"qrHint\" style=\"text-align:center;margin-top:6px;\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <script src=\"/assets/qrcode.min.js\"></script>\n <script>\n (function(){\n const url = ${JSON.stringify(cardUrl)};\n\n const __slug = (function () {\n const seg = String(location.pathname || \"\").split(\"/\").filter(Boolean);\n return seg[0] || ${JSON.stringify(slug)};\n })();\n\n function umamiTrack(name, data){\n try {\n if (window.umami && typeof window.umami.track === \"function\") {\n window.umami.track(name, Object.assign({ slug: __slug }, data || {}));\n }\n } catch(e) {}\n }\n\n const src = new URLSearchParams(location.search).get(\"src\");\n if (src) umamiTrack(\"open_card\", { src });\n\n function isEmpty(v){\n return !v || String(v).trim() === \"\";\n }\n\n if (isEmpty(${JSON.stringify(mobileE164)}) || isEmpty(${JSON.stringify(mobileDisplay)})) {\n const r = document.getElementById(\"mobileRow\");\n if (r) r.style.display = \"none\";\n }\n\n if (isEmpty(${JSON.stringify(companyTelE164)}) || isEmpty(${JSON.stringify(companyTelDisplay)})) {\n const r = document.getElementById(\"companyPhoneRow\");\n if (r) r.style.display = \"none\";\n }\n\n if (isEmpty(${JSON.stringify(website)})) {\n const el = document.getElementById(\"webLink\");\n if (el) el.style.display = \"none\";\n }\n\n if (isEmpty(${JSON.stringify(facebookUrl)})) {\n const el = document.getElementById(\"fbLink\");\n if (el) el.style.display = \"none\";\n }\n\n if (isEmpty(${JSON.stringify(linkedinUrl)})) {\n const el = document.getElementById(\"liLink\");\n if (el) el.style.display = \"none\";\n }\n\n function vcardEscape(s){\n return String(s ?? \"\")\n .replace(/\\\\\\\\/g,\"\\\\\\\\\\\\\\\\\")\n .replace(/\\\\n/g,\"\\\\\\\\n\")\n .replace(/;/g,\"\\\\\\\\;\")\n .replace(/,/g,\"\\\\\\\\,\");\n }\n\n const name = ${JSON.stringify(name)};\n const title = ${JSON.stringify(title)};\n const company = ${JSON.stringify(company)};\n const email = ${JSON.stringify(email)};\n const website = ${JSON.stringify(website)};\n\n const workTel = ${JSON.stringify(workTelE164)};\n const mobileTel = ${JSON.stringify(mobileE164)};\n const mainTel = ${JSON.stringify(companyTelE164)};\n\n const street = ${JSON.stringify(d0.street || \"\")};\n const postcode = ${JSON.stringify(d0.postcode || \"\")};\n const city = ${JSON.stringify(d0.city || \"\")};\n\n const parts = String(name || \"\").trim().split(/\\\\s+/);\n const first = parts.shift() || \"\";\n const last = parts.join(\" \") || \"\";\n\n const vcf = [\n \"BEGIN:VCARD\",\n \"VERSION:3.0\",\n \\`N:\\${vcardEscape(last)};\\${vcardEscape(first)};;;\\`,\n \\`FN:\\${vcardEscape(name)}\\`,\n \\`ORG:\\${vcardEscape(company)}\\`,\n \\`TITLE:\\${vcardEscape(title)}\\`,\n (workTel ? \\`TEL;TYPE=WORK,VOICE:\\${vcardEscape(workTel)}\\` : \"\"),\n (mainTel ? \\`TEL;TYPE=WORK,MAIN:\\${vcardEscape(mainTel)}\\` : \"\"),\n (mobileTel ? \\`TEL;TYPE=CELL,VOICE:\\${vcardEscape(mobileTel)}\\` : \"\"),\n (email ? \\`EMAIL;TYPE=INTERNET,WORK:\\${vcardEscape(email)}\\` : \"\"),\n (street || postcode || city ? \\`ADR;TYPE=WORK:;;\\${vcardEscape(street)};\\${vcardEscape(city)};;\\${vcardEscape(postcode)};Netherlands\\` : \"\"),\n (website ? \\`URL:\\${vcardEscape(website)}\\` : \"\"),\n \"END:VCARD\"\n ].filter(Boolean).join(\"\\\\n\");\n\n document.getElementById(\"btnSave\").addEventListener(\"click\", function(){\n umamiTrack(\"save_contact\");\n\n const blob = new Blob([vcf], { type:\"text/vcard;charset=utf-8\" });\n const a = document.createElement(\"a\");\n a.href = URL.createObjectURL(blob);\n a.download = (name || \"contact\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g,\"-\")\n .replace(/^-|-$/g,\"\") + \".vcf\";\n\n document.body.appendChild(a);\n a.click();\n a.remove();\n });\n\n const backdrop = document.getElementById(\"shareBackdrop\");\n const shareUrlEl = document.getElementById(\"shareUrl\");\n const qrHint = document.getElementById(\"qrHint\");\n\n function openShare(){\n umamiTrack(\"open_share\");\n\n shareUrlEl.textContent = url;\n backdrop.classList.add(\"open\");\n backdrop.setAttribute(\"aria-hidden\",\"false\");\n\n const qrCanvas = document.getElementById(\"qrcode\");\n qrHint.textContent = \"\";\n\n if (window.QRCode && QRCode.toCanvas) {\n QRCode.toCanvas(qrCanvas, url, { width: 180, margin: 1 }, function(err) {\n if (err) qrHint.textContent = \"QR kon niet worden gemaakt.\";\n });\n } else {\n qrHint.textContent = \"QR library ontbreekt op /assets/qrcode.min.js\";\n }\n }\n\n function closeShare(){\n backdrop.classList.remove(\"open\");\n backdrop.setAttribute(\"aria-hidden\",\"true\");\n }\n\n document.getElementById(\"btnShare\").addEventListener(\"click\", openShare);\n document.getElementById(\"btnClose\").addEventListener(\"click\", closeShare);\n\n backdrop.addEventListener(\"click\", function(e){\n if (e.target === backdrop) closeShare();\n });\n\n document.getElementById(\"btnCopy\").addEventListener(\"click\", async function(){\n umamiTrack(\"copy_link\");\n try {\n await navigator.clipboard.writeText(url);\n alert(\"Link gekopieerd\");\n } catch(e) {\n alert(url);\n }\n });\n\n document.getElementById(\"btnNativeShare\").addEventListener(\"click\", async function(){\n umamiTrack(\"native_share\");\n if (navigator.share) {\n try {\n await navigator.share({ title: name, text: title, url });\n } catch(e) {}\n } else {\n alert(\"Delen is niet beschikbaar. Gebruik 'Kopieer link'.\");\n }\n });\n })();\n </script>\n</body>\n</html>`;\n\nconst dataBuffer = Buffer.from(html, \"utf8\");\n\nreturn [{\n json: {\n slug,\n path: `${slug}/index.html`,\n cardUrl\n },\n binary: {\n data: await this.helpers.prepareBinaryData(dataBuffer, \"index.html\", \"text/html\")\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
112,
-368
],
"id": "805af8c4-8dd1-409d-9e6d-2ec048e5f91c",
"name": "Code in JavaScript"
},
{
"parameters": {
"mode": "raw",
"jsonOutput": "{\n \"name\": \"Eric de Wit\",\n \"title\": \"Commercieel directeur\",\n \"company\": \"De Wit Transport\",\n \"email\": \"e.dewit@dewittransport.nl\",\n \"website\": \"https://www.dewittransport.nl\",\n\n \"workTel\": \"088665392\",\n \"companyTel\": \"0886653300\",\n \"mobile\": \"0651316371\",\n\n \"street\": \"Haarlemmerstraatweg 52\",\n \"postcode\": \"2343 LB\",\n \"city\": \"Oegstgeest\",\n\n \"facebookUrl\": \"https://www.facebook.com/profile.php?id=100063917050863\",\n \"linkedinUrl\": \"https://www.linkedin.com/company/de-wit-transport/\"\n}\n",
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-96,
-368
],
"id": "eec908ce-ab3c-43b0-af18-7e0559ecb9e1",
"name": "Edit Fields"
},
{
"parameters": {
"protocol": "sftp",
"operation": "upload",
"path": "=/cards/{{ $json.path }}",
"options": {}
},
"type": "n8n-nodes-base.ftp",
"typeVersion": 1,
"position": [
336,
-368
],
"id": "aa3ddd75-e9dc-4aed-8d98-9f05a4867d67",
"name": "FTP",
"credentials": {
"sftp": {
"id": "uKyzg5cSXQqXOuHI",
"name": "SFTP n8n"
}
}
},
{
"parameters": {
"protocol": "sftp",
"operation": "list",
"path": "/cards/",
"options": {}
},
"type": "n8n-nodes-base.ftp",
"typeVersion": 1,
"position": [
144,
-656
],
"id": "7fd74991-605e-4854-a0e3-0b4fb686f638",
"name": "FTP1",
"credentials": {
"sftp": {
"id": "uKyzg5cSXQqXOuHI",
"name": "SFTP n8n"
}
}
}
],
"pinData": {},
"connections": {
"When clicking Execute workflow": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "FTP",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"availableInMCP": false
},
"versionId": "bd68247e-cb5a-49bd-aa67-15d2b868821b",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "22b0779b2e76c14be6b62c9c2bf1df5938c4e0bee54f033e17614db1892a6369"
},
"id": "HX3DFRGFN9ZG7adu0wfsT",
"tags": []
}