{ "nodes": [ { "id": "import-squarespace-signups-to-mailchimp-0", "name": "When clicking ‘Test workflow’", "type": "n8n-nodes-base.manualTrigger", "position": [ -280, 120 ], "parameters": {}, "typeVersion": 1 }, { "id": "import-squarespace-signups-to-mailchimp-1", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -280, -160 ], "parameters": { "rule": { "interval": [ { "field": "days", "daysInterval": 1, "triggerAtHour": 0, "triggerAtMinute": 0 } ] } }, "typeVersion": 1.2 }, { "name": "Configure sheet and audience", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": "function config({spreadsheetId,sheetName,listId}){for(const[k,v]of Object.entries({spreadsheetId,sheetName,listId}))if(typeof v!=='string'||!v.trim()||v.startsWith('YOUR_'))throw Error('Configure '+k);return{spreadsheetId,sheetName,listId,range:\"'\"+sheetName.replace(/'/g,\"''\")+\"'\"}}\n\nconst server='YOUR_MAILCHIMP_SERVER_PREFIX';if(!/^[a-z]{2}[0-9]{1,3}$/.test(server))throw Error('Configure the Mailchimp server prefix');return [{json:{...config({spreadsheetId:'YOUR_SPREADSHEET_ID',sheetName:'Signups',listId:'YOUR_MAILCHIMP_AUDIENCE_ID'}),server}}];" }, "id": "import-squarespace-signups-to-mailchimp-2" }, { "id": "import-squarespace-signups-to-mailchimp-3", "name": "Read newsletter signups", "type": "n8n-nodes-base.httpRequest", "position": [ 0, 0 ], "parameters": { "method": "GET", "url": "={{ \"https://sheets.googleapis.com/v4/spreadsheets/\" + encodeURIComponent($(\"Configure sheet and audience\").first().json.spreadsheetId) + \"/values/\" + encodeURIComponent($(\"Configure sheet and audience\").first().json.range) }}", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleSheetsOAuth2Api", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "valueRenderOption", "value": "FORMATTED_VALUE" } ] }, "options": { "timeout": 30000 } }, "typeVersion": 4.2 }, { "name": "Validate all signups", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": "function validate({values}){if(!Array.isArray(values))throw Error('Invalid sheet response');if(!values.length)return{items:[]};const h=values[0];if(!Array.isArray(h))throw Error('Invalid header');const fields=['Email Address','Name','Submitted On'],idx=fields.map(x=>h.indexOf(x));if(idx.some(x=>x<0)||fields.some(x=>h.filter(y=>y===x).length!==1))throw Error('Required headers are missing or duplicated');const seen=new Set(),items=[];for(const row of values.slice(1)){if(!Array.isArray(row)||row.every(x=>x===null||x===undefined||x===''))continue;const [email,name,time]=idx.map(i=>row[i]);if(typeof email!=='string'||!/^\\S+@\\S+\\.\\S+$/.test(email.trim())||typeof name!=='string'||!name.trim()||typeof time!=='string'||!/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.\\d+)?(?:Z|[+-]\\d\\d:\\d\\d)$/.test(time)||!Number.isFinite(Date.parse(time)))throw Error('Each signup requires an email, name and ISO timestamp with time zone');const m=time.match(/^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(?:\\.\\d+)?(Z|([+-])(\\d\\d):(\\d\\d))$/),d=new Date(Date.UTC(+m[1],+m[2]-1,+m[3]));if(d.getUTCFullYear()!==+m[1]||d.getUTCMonth()!==+m[2]-1||d.getUTCDate()!==+m[3]||+m[4]>23||+m[5]>59||+m[6]>59||(m[7]!=='Z'&&(+m[9]>23||+m[10]>59)))throw Error('Invalid signup timestamp');const key=email.trim().toLowerCase();if(seen.has(key))throw Error('Duplicate email in the sheet');seen.add(key);items.push({email:email.trim(),name:name.trim(),timestamp:new Date(time).toISOString()})}return{items}}\n\nreturn validate({values:$input.first().json.values??[]}).items.map((json,i)=>({json,pairedItem:{item:0}}));" }, "id": "import-squarespace-signups-to-mailchimp-4" }, { "name": "Import one signup at a time", "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "parameters": { "batchSize": 1, "options": {} }, "id": "import-squarespace-signups-to-mailchimp-5" }, { "name": "Add the Mailchimp subscriber", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "parameters": { "method": "POST", "url": "={{ \"https://\" + $(\"Configure sheet and audience\").first().json.server + \".api.mailchimp.com/3.0/lists/\" + encodeURIComponent($(\"Configure sheet and audience\").first().json.listId) + \"/members\" }}", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "contentType": "json", "specifyBody": "json", "jsonBody": "={{ JSON.stringify({email_address:$json.email,status:\"subscribed\",merge_fields:{FNAME:$json.name},timestamp_signup:$json.timestamp}) }}", "options": { "timeout": 30000, "redirect": { "redirect": { "followRedirects": false } }, "response": { "response": { "fullResponse": true, "responseFormat": "json", "neverError": false } } } }, "id": "import-squarespace-signups-to-mailchimp-6" }, { "name": "Confirm the subscriber", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": "function confirm({body,statusCode,bodyEncoding,expected}){if(statusCode!==200||bodyEncoding||!body||typeof body.id!=='string'||!body.id||typeof body.email_address!=='string'||body.email_address.toLowerCase()!==expected.toLowerCase()||body.status!=='subscribed')throw Error('Mailchimp did not confirm the subscriber');return{member:body}}\n\nconst x=$input.first().json,p=$('Import one signup at a time').item.json;return [{json:confirm({body:x.body,statusCode:x.statusCode,bodyEncoding:null,expected:p.email}).member}];" }, "id": "import-squarespace-signups-to-mailchimp-7" } ], "pinData": {}, "connections": { "When clicking ‘Test workflow’": { "main": [ [ { "node": "Configure sheet and audience", "type": "main", "index": 0 } ] ] }, "Schedule Trigger": { "main": [ [ { "node": "Configure sheet and audience", "type": "main", "index": 0 } ] ] }, "Configure sheet and audience": { "main": [ [ { "node": "Read newsletter signups", "type": "main", "index": 0 } ] ] }, "Read newsletter signups": { "main": [ [ { "node": "Validate all signups", "type": "main", "index": 0 } ] ] }, "Validate all signups": { "main": [ [ { "node": "Import one signup at a time", "type": "main", "index": 0 } ] ] }, "Add the Mailchimp subscriber": { "main": [ [ { "node": "Confirm the subscriber", "type": "main", "index": 0 } ] ] }, "Confirm the subscriber": { "main": [ [ { "node": "Import one signup at a time", "type": "main", "index": 0 } ] ] }, "Import one signup at a time": { "main": [ [], [ { "node": "Add the Mailchimp subscriber", "type": "main", "index": 0 } ] ] } }, "name": "Import Squarespace Signups to Mailchimp", "settings": { "timezone": "UTC", "executionOrder": "v1" }, "active": false }