{ "nodes": [ { "id": "follow-up-hubspot-contacts-with-gmail-0", "name": "Every day at 9 am", "type": "n8n-nodes-base.scheduleTrigger", "position": [ 340, 1280 ], "parameters": { "rule": { "interval": [ { "triggerAtHour": 9 } ] } }, "typeVersion": 1.1 }, { "id": "follow-up-hubspot-contacts-with-gmail-1", "name": "Get previously HubSpot contacts", "type": "n8n-nodes-base.hubspot", "position": [ 840, 1280 ], "parameters": { "operation": "search", "authentication": "oAuth2", "filterGroupsUi": { "filterGroupsValues": [ { "filtersUi": { "filterValues": [ { "operator": "HAS_PROPERTY", "propertyName": "notes_last_contacted|datetime" } ] } } ] }, "additionalFields": { "sortBy": "notes_last_contacted", "direction": "ASCENDING", "properties": [ "firstname", "lastname", "email", "notes_last_contacted" ] } }, "typeVersion": 2 }, { "id": "follow-up-hubspot-contacts-with-gmail-2", "name": "if last contacted before a month", "type": "n8n-nodes-base.if", "position": [ 1120, 1280 ], "parameters": { "options": {}, "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "8d9ad7ef-6e1a-486c-9fac-419ad2660ace", "operator": { "type": "dateTime", "operation": "before" }, "leftValue": "={{ $json.properties.notes_last_contacted }}", "rightValue": "={{ DateTime.now().minus({days: 30}) }}" } ] } }, "typeVersion": 2 }, { "name": "Process contacts one by one", "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "parameters": { "batchSize": 1, "options": {} }, "id": "follow-up-hubspot-contacts-with-gmail-3" }, { "id": "follow-up-hubspot-contacts-with-gmail-4", "name": "Get Hubspot Contact to engagement", "type": "n8n-nodes-base.httpRequest", "position": [ 1340, 1280 ], "parameters": { "method": "GET", "url": "={{ 'https://api.hubapi.com/crm-associations/v1/associations/' + encodeURIComponent($('Process contacts one by one').item.json.id) + '/HUBSPOT_DEFINED/9' }}", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": { "response": { "response": { "responseFormat": "json" } } } }, "typeVersion": 4.1 }, { "name": "Check eligibility and prepare the email", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForEachItem", "jsCode": "function check({current,body,sender}) {\n if(!body||!Array.isArray(body.results)||body.results.some(x=>!(Number.isSafeInteger(x)&&x>0)&&!(typeof x==='string'&&/^\\d+$/.test(x)&&x!=='0'))||typeof body.hasMore!=='boolean')throw Error('Invalid engagement response');\n if(typeof sender!=='string'||!sender.includes('@')||sender.includes('YOUR_'))throw Error('Configure the Gmail sender address before sending');\n const send=current.eligible && body.results.length===1 && !body.hasMore;\n if(send&&(typeof current.email!=='string'||!current.email.includes('@')||typeof current.firstName!=='string'))throw Error('Contact needs an email and first name');\n return {send,sender,to:send?current.email:'',subject:'Following up',body:'Hello '+current.firstName+',\\n\\nI wanted to follow up on our previous conversation.\\n\\nBest regards'};\n}\n\nconst c=$('Process contacts one by one').item.json;return {json:check({current:{eligible:true,id:c.id,email:c.properties.email,firstName:c.properties.firstname??''},body:$json,sender:'YOUR_SENDER_EMAIL'})};" }, "id": "follow-up-hubspot-contacts-with-gmail-5" }, { "name": "Follow up?", "type": "n8n-nodes-base.if", "typeVersion": 2.2, "parameters": { "options": {}, "conditions": { "options": { "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "leftValue": "={{ $json.send }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ] } }, "id": "follow-up-hubspot-contacts-with-gmail-6" }, { "id": "follow-up-hubspot-contacts-with-gmail-7", "name": "Send outreach email", "type": "n8n-nodes-base.gmail", "position": [ 2040, 1060 ], "parameters": { "sendTo": "={{ $json.to }}", "subject": "={{ $json.subject }}", "message": "={{ $json.body }}", "options": { "appendAttribution": false } }, "typeVersion": 2.1 }, { "name": "Prepare the engagement", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForEachItem", "jsCode": "function log({current,to,subject,body,messageId,scheduledAt,sender}) {\n if(typeof messageId!=='string'||!messageId)throw Error('Gmail did not confirm sending');\n if(typeof sender!=='string'||!sender.includes('@')||sender.includes('YOUR_'))throw Error('Configure the Gmail sender address before sending');\n return {payload:{properties:{hs_timestamp:scheduledAt,hs_email_direction:'EMAIL',hs_email_status:'SENT',hs_email_subject:subject,hs_email_text:body,hs_email_headers:JSON.stringify({from:{email:sender},to:[{email:to}]})},associations:[{to:{id:current.id},types:[{associationCategory:'HUBSPOT_DEFINED',associationTypeId:198}]}]}};\n}\n\nconst c=$('Process contacts one by one').item.json,m=$('Check eligibility and prepare the email').item.json;return {json:log({current:{id:c.id},to:m.to,subject:m.subject,body:m.body,messageId:$json.id,scheduledAt:new Date().toISOString(),sender:m.sender}).payload};" }, "id": "follow-up-hubspot-contacts-with-gmail-8" }, { "name": "Log the sent email", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "parameters": { "method": "POST", "url": "https://api.hubapi.com/crm/v3/objects/emails", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ $json }}", "options": { "response": { "response": { "responseFormat": "json" } } } }, "id": "follow-up-hubspot-contacts-with-gmail-9" }, { "name": "Confirm the engagement", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForEachItem", "jsCode": "if(typeof $json.id!==\"string\"||!$json.id)throw Error(\"HubSpot did not confirm the email engagement\");return $input.item;" }, "id": "follow-up-hubspot-contacts-with-gmail-10" } ], "pinData": {}, "connections": { "Every day at 9 am": { "main": [ [ { "node": "Get previously HubSpot contacts", "type": "main", "index": 0 } ] ] }, "Get previously HubSpot contacts": { "main": [ [ { "node": "if last contacted before a month", "type": "main", "index": 0 } ] ] }, "if last contacted before a month": { "main": [ [ { "node": "Process contacts one by one", "type": "main", "index": 0 } ] ] }, "Process contacts one by one": { "main": [ [], [ { "node": "Get Hubspot Contact to engagement", "type": "main", "index": 0 } ] ] }, "Get Hubspot Contact to engagement": { "main": [ [ { "node": "Check eligibility and prepare the email", "type": "main", "index": 0 } ] ] }, "Check eligibility and prepare the email": { "main": [ [ { "node": "Follow up?", "type": "main", "index": 0 } ] ] }, "Follow up?": { "main": [ [ { "node": "Send outreach email", "type": "main", "index": 0 } ], [ { "node": "Process contacts one by one", "type": "main", "index": 0 } ] ] }, "Send outreach email": { "main": [ [ { "node": "Prepare the engagement", "type": "main", "index": 0 } ] ] }, "Prepare the engagement": { "main": [ [ { "node": "Log the sent email", "type": "main", "index": 0 } ] ] }, "Log the sent email": { "main": [ [ { "node": "Confirm the engagement", "type": "main", "index": 0 } ] ] }, "Confirm the engagement": { "main": [ [ { "node": "Process contacts one by one", "type": "main", "index": 0 } ] ] } }, "name": "Follow Up HubSpot Contacts with Gmail", "active": false, "settings": { "timezone": "UTC", "executionOrder": "v1" } }