{ "name": "SMB · Onboarding", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "onboard", "responseMode": "onReceived", "options": { "allowedOrigins": "*" } }, "id": "d1a08bba-5cc5-48fa-8063-bda2d58cab15", "name": "Onboard webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [ 240, 300 ], "webhookId": "96c28466-ee4b-4aa5-8f06-52d098b497a7" }, { "parameters": { "jsCode": "const w=$('Onboard webhook').first().json; const body=w.body||w;\nconst s=v=>{v=(v==null?'':String(v));return /^[=+\\-@\\t\\r]/.test(v)?\"'\"+v:v;};\nconst now=new Date();\nfunction pd(v){if(!v)return null;const m=String(v).match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if(m)return new Date(Date.UTC(+m[1],+m[2]-1,+m[3]));const d=new Date(v);return isNaN(d)?null:d;}\nfunction slugify(v){return String(v||'').toLowerCase().normalize('NFKD').replace(/[\\u0300-\\u036f]/g,'')\n .replace(/[^a-z0-9]+/g,'-').replace(/^-+|-+$/g,'')||'client';}\nconst cycle=String(body.billing_cycle||'monthly').toLowerCase();\nconst start=pd(body.start_date)||new Date(Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate()));\nconst startStr=start.toISOString().slice(0,10);\nconst tier=String(body.tier||'A').toUpperCase().includes('B')?'B':'A';\nconst services=String(body.services||'site, booking, leads');\nconst slug=slugify(body.business_name)+'-'+Math.random().toString(36).slice(2,6);\nconst client={business_name:s(body.business_name),owner_name:s(body.owner_name),\n email:s(body.email),phone:s(body.phone),niche:s(body.niche),tier,status:'onboarding',\n domain:s(body.domain),stack_notes:s(body.stack_notes),vault_ref:s(body.vault_ref),\n services:s(services),billing_cycle:cycle,monthly_fee_eur:(body.monthly_fee_eur||''),\n start_date:startStr,notes:s(body.notes),slug};\nconst checklist=services.split(',').map(x=>x.trim()).filter(Boolean).map(x=>x+'\\u2610').join(' ');\nconst gl=new Date(start);gl.setUTCDate(gl.getUTCDate()+14);const goLive=gl.toISOString().slice(0,10);\nconst project={project_id:'P-'+Date.now(),deliverable:'Onboarding & Setup',tier,checklist,\n go_live_date:goLive,status:'todo'};\nreturn [{json:{client,project,tier,services,cycle,monthly_fee_eur:(body.monthly_fee_eur||''),\n business_name:client.business_name}}];" }, "id": "fe9a0f5d-c6f8-4328-a98e-edc022582ec3", "name": "Compute", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 460, 300 ] }, { "parameters": { "method": "POST", "url": "http://smb-crm:8080/api/clients", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify($json.client) }}", "options": {} }, "id": "22222222-3333-4444-5555-666666666666", "name": "Save client", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 680, 300 ], "retryOnFail": true, "maxTries": 4, "waitBetweenTries": 3000 }, { "parameters": { "jsCode": "const c=$('Compute').first().json;\nconst cid=$('Save client').first().json.added;\nconst p=Object.assign({}, c.project, {client_id:cid});\nreturn [{json:p}];" }, "id": "33333333-4444-5555-6666-777777777777", "name": "Build project", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 900, 300 ] }, { "parameters": { "method": "POST", "url": "http://smb-crm:8080/api/projects", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify($json) }}", "options": {} }, "id": "44444444-5555-6666-7777-888888888888", "name": "Save project", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1120, 300 ], "retryOnFail": true, "maxTries": 4, "waitBetweenTries": 3000 }, { "parameters": { "resource": "message", "operation": "sendMessage", "chatId": "5499280257", "text": "=✅ Neuer Kunde angelegt: {{ $('Save client').item.json.added }}\n{{ $('Compute').item.json.business_name }} — Tier {{ $('Compute').item.json.tier }}\nServices: {{ $('Compute').item.json.services }}\nGebühr: {{ $('Compute').item.json.monthly_fee_eur || '—' }}€/{{ $('Compute').item.json.cycle }}\nGo-Live Ziel: {{ $('Build project').item.json.go_live_date }}", "additionalFields": { "appendAttribution": false } }, "id": "ae19e543-1a6b-4466-8af8-bb436f51091b", "name": "Notify Telegram", "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 1340, 300 ], "credentials": { "telegramApi": { "id": "d9s4Ec5ocEH8FAxh", "name": "SMB Telegram (leads bot)" } } }, { "parameters": { "jsCode": "const cid=$('Save client').first().json.added;\nconst c=($('Compute').first().json.client)||{};\nconst password=Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,6);\nconst hours=[0,1,2,3,4,5].map(weekday=>({weekday,opens_at:'09:00',closes_at:'18:00'}));\nconst locationBody={client_id:cid,name:'Hauptfiliale'};\nconst resourceBody={client_id:cid,name:'Hauptressource',hours};\nconst serviceBody={client_id:cid,name:'Termin',duration_minutes:30,price:0};\nreturn [{json:{cid,locationBody,resourceBody,serviceBody,userEmail:c.email,userPassword:password}}];" }, "id": "prov-build-provisioning", "name": "Build provisioning", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 680, 520 ] }, { "parameters": { "options": {}, "method": "POST", "url": "http://smb-crm:8080/api/locations", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify($json.locationBody) }}" }, "id": "prov-create-location", "name": "Create location", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 900, 340 ], "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "continueOnFail": true }, { "parameters": { "options": {}, "method": "POST", "url": "http://smb-crm:8080/api/resources", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify(Object.assign({}, $('Build provisioning').item.json.resourceBody, { location_id: $json.location_id })) }}" }, "id": "prov-create-resource", "name": "Create resource", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1120, 420 ], "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "continueOnFail": true }, { "parameters": { "options": {}, "method": "POST", "url": "http://smb-crm:8080/api/services", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify($json.serviceBody) }}" }, "id": "prov-create-service", "name": "Create service", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 900, 520 ], "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "continueOnFail": true }, { "parameters": { "options": {}, "method": "POST", "url": "http://smb-crm:8080/api/owner_users", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ client_id: $json.cid, email: $json.userEmail, password: $json.userPassword }) }}" }, "id": "prov-create-owner-user", "name": "Create owner user", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 900, 620 ], "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "continueOnFail": true }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "c0000000-1111-2222-3333-aaaaaaaaaaaa", "leftValue": "={{ $json.user_id }}", "rightValue": "", "operator": { "type": "string", "operation": "notEmpty", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "prov-user-created-check", "name": "User created?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [ 1120, 620 ] }, { "parameters": { "options": {}, "method": "POST", "url": "http://smb-crm:8080/api/credentials", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-CRM-Token", "value": "__CRM_TOKEN__" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ client_id: $('Build provisioning').item.json.cid, label: 'Owner-Login', username: $('Build provisioning').item.json.userEmail, secret: $('Build provisioning').item.json.userPassword }) }}" }, "id": "prov-save-credential", "name": "Save credential", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1340, 620 ], "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "continueOnFail": true } ], "connections": { "Onboard webhook": { "main": [ [ { "node": "Compute", "type": "main", "index": 0 } ] ] }, "Compute": { "main": [ [ { "node": "Save client", "type": "main", "index": 0 } ] ] }, "Save client": { "main": [ [ { "node": "Build project", "type": "main", "index": 0 }, { "node": "Build provisioning", "type": "main", "index": 0 } ] ] }, "Build project": { "main": [ [ { "node": "Save project", "type": "main", "index": 0 } ] ] }, "Save project": { "main": [ [ { "node": "Notify Telegram", "type": "main", "index": 0 } ] ] }, "Build provisioning": { "main": [ [ { "node": "Create location", "type": "main", "index": 0 }, { "node": "Create service", "type": "main", "index": 0 }, { "node": "Create owner user", "type": "main", "index": 0 } ] ] }, "Create location": { "main": [ [ { "node": "Create resource", "type": "main", "index": 0 } ] ] }, "Create owner user": { "main": [ [ { "node": "User created?", "type": "main", "index": 0 } ] ] }, "User created?": { "main": [ [ { "node": "Save credential", "type": "main", "index": 0 } ], [] ] } }, "settings": { "executionOrder": "v1", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false } }