{
  "name": "Job Change - Lusha API",
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1248,
        256
      ],
      "id": "6cdc405c-4fe2-47b4-8fc1-d25e8adc5975",
      "name": "When clicking ‘Execute workflow’"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.lusha.com/api/signals/contacts/search",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "api_key"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={ \n  \"contacts\": {{ $json.ContactsForAPI }}, \n  \"signals\": [\"allSignals\"], \n  \"startDate\": \"{{ $('Translate for bulkAPI call7').item.json.startDate }}\"\n}\n",
        "options": {
          "redirect": {
            "redirect": {}
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        592,
        480
      ],
      "id": "63715c2a-3ec4-4ab8-a2b0-9b5eef5769f8",
      "name": "Get Contact(s) Signals7"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e3fb5eed-3aad-4ad9-8cbe-d67b568b8353",
              "name": "id",
              "value": "={{ $json.Id }}",
              "type": "string"
            },
            {
              "id": "3f3d1658-45e7-41e8-b763-5d9840414c30",
              "name": "social_link",
              "value": "={{ $json.Contact__r.LinkedIn__c }}",
              "type": "string"
            },
            {
              "id": "f06a9380-96a3-4702-b1b8-1005e3db3809",
              "name": "start_date",
              "value": "={{ new Date(new Date().setMonth(new Date().getMonth() - 5)).toISOString().substring(0,10) }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -64,
        480
      ],
      "id": "a151c26d-c3d2-4c2e-a375-218d9a956e7f",
      "name": "Prepare for API Call9"
    },
    {
      "parameters": {
        "jsCode": "const inputItems = $input.all();\n\nconst buildContactSignalRequest = (data) => {\n  const contacts = data.map(({ social_link, id}) => ({ social_link, id}));\n  return {\n    contacts,\n    signals: [\"companyChange\"],\n    startDate: new Date(new Date().setMonth(new Date().getMonth() - 6))\n      .toISOString()\n      .substring(0, 10),\n  };\n};\n\nconst contacts = inputItems.map(item => item.json);\nconst result = buildContactSignalRequest(contacts);\n\nreturn [{ json: result }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        160,
        480
      ],
      "id": "b45985e7-5467-4496-8cdd-4067159fe64f",
      "name": "Translate for bulkAPI call7"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1857e515-d760-4c8c-a194-0949eda45938",
              "name": "ContactsForAPI",
              "value": "={{ $json.contacts }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        368,
        480
      ],
      "id": "39e4991c-818e-4041-8f07-131c8d56c978",
      "name": "build contact list for API7"
    },
    {
      "parameters": {
        "jsCode": "const inputItems = $input.all();\nconst out = [];\n\nconst getSignalBySignalType = (data) => {\n  const { contacts } = data;\n  const results = [];\n  Object.keys(contacts).forEach(salesforceId => {\n    const contactSignals = contacts[salesforceId];\n    let signals = [];\n    for (const contactSignalType in contactSignals) {\n      if (contactSignalType === \"companyChange\" && contactSignals[contactSignalType]?.length) {\n        signals = contactSignals[contactSignalType].length && contactSignals[contactSignalType].map((signal) => ({\n          Id: salesforceId,\n          Lusha_Person_Id__c: `${signal.personId}`,\n          Job_Change_Date__c: signal.signalDate,\n          Lusha_Signals__c: `This contact changed job on ${signal.signalDate} from ${signal.previousCompanyName} to ${signal.currentCompanyName}. Current title: ${signal.currentTitle}`,\n          Previous_domain_Job_Change__c: signal.previousDomain,\n          New_Domain_Job_Change__c: signal.currentDomain,\n          Position: 'Post Sale Won Opps Contacts',\n\n        }))\n        break;\n      }\n\n      if (contactSignalType === \"promotion\" && !Boolean(signals.length) && contactSignals[contactSignalType]?.length) {\n        signals = contactSignals[contactSignalType].length && contactSignals[contactSignalType].map((signal) => ({\n          Id: salesforceId,\n          Lusha_Person_Id__c: `${signal.personId}`,\n          Job_Change_Date__c: signal.signalDate,\n          Lusha_Signals__c: `This contact got promoted to ${signal.currentTitle} on ${signal.signalDate}.`\n        }))\n        break;\n      }\n\n    }\n    if (!Boolean(signals.length)) {\n      signals = [{\n        Id: salesforceId,\n        Lusha_Person_Id__c: contactSignals.personId,\n      }];\n    }\n    results.push(...signals);\n  });\n\n  return results;\n};\n\nfor (const item of inputItems) {\n  const results = getSignalBySignalType(item.json);\n  for (const r of results) out.push({ json: r });\n}\n\nreturn out;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        480
      ],
      "id": "69e2a610-02c7-4acc-9a75-13f2cf4d69c1",
      "name": "Prepare for SFDC Enrichment7"
    },
    {
      "parameters": {
        "batchSize": 100,
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -224,
        240
      ],
      "id": "6ba896b5-6857-437a-af3a-de0c8211801e",
      "name": "Loop Over Items7",
      "alwaysOutputData": false,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "// Process ONLY current batch - don't try to accumulate\nconst currentBatchItems = $input.all();\n\n// Convert current batch to array of objects (not CSV string)\nconst processedRows = currentBatchItems.map(item => ({\n  ID: item.json.ID || item.json.Id || item.json.id || '',\n  'Lusha Person ID': item.json['Lusha Person ID'] || item.json.Lusha_Person_Id__c || item.json.lushaPersonId || '',\n  Signal: item.json.Signal || item.json.signal || item.json.Lusha_Signals__c || '',\n  Date: item.json.Date || item.json.date || item.json.Job_Change_Date__c || '',\n  Previous_domain_Job_Change__c: item.json.Previous_domain_Job_Change__c || item.json.previousDomain || '',\n  New_Domain_Job_Change__c: item.json.New_Domain_Job_Change__c || item.json.newDomain || '',\n  Position: item.json.Position || item.json.position || ''\n}));\n\nconsole.log(`Processing ${processedRows.length} rows in this iteration`);\n\n// Return as separate items (not accumulated CSV)\nreturn processedRows.map(row => ({ json: row }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1136,
        480
      ],
      "id": "c7db23f1-b557-47ad-9fd8-2c60b4158047",
      "name": "New Rows Append7"
    },
    {
      "parameters": {
        "jsCode": "// Create CSV - Initialize with headers\nconst csvHeaders = ['ID', 'Lusha Person ID', 'Signal', 'Date'];\n\nreturn [{\n  json: {\n    ID: 'ID',\n    'Lusha Person ID': 'Lusha Person ID', \n    Signal: 'Signal',\n    Date: 'Date'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1008,
        256
      ],
      "id": "1a294ce7-0673-43cb-850e-9633eb810004",
      "name": "Create CSV7"
    },
    {
      "parameters": {
        "jsCode": "// Code Node: Convert to structured data for Workato\nconst allRows = $input.all().map(item => item.json);\n\n// Create array of objects (not CSV string)\nconst structuredData = allRows.map(row => ({\n  ID: row.ID || row.Id || row.id || '',\n  PERSON_ID: row['Lusha Person ID'] || row.Lusha_Person_Id__c || row.lushaPersonId || '',\n  Signal: row.Signal || row.signal || row.Lusha_Signals__c || '',\n  DATE: row.Date || row.date || row.Job_Change_Date__c || '',\n  Previous_domain_Job_Change__c: row.Previous_domain_Job_Change__c || row.previousDomain || '',\n  New_Domain_Job_Change__c: row.New_Domain_Job_Change__c || row.newDomain || '',\n Position: row.Position || row.position || ''\n}));\n\nconsole.log(`Sending ${structuredData.length} structured records to Workato`);\n\nreturn [{\n  json: {\n    csvData: structuredData, // Array of objects\n    totalRows: structuredData.length,\n    timestamp: new Date().toISOString(),\n    source: 'n8n'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -32,
        96
      ],
      "id": "9f7cbff7-f62b-4287-92e0-240539591064",
      "name": "New CSV Finalize"
    },
    {
      "parameters": {
        "method": "POST",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "csvData",
              "value": "={{ $json.csvData }}"
            },
            {
              "name": "totalRows",
              "value": "={{ $json.totalRows }}"
            },
            {
              "name": "timestamp",
              "value": "={{ $json.timestamp }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        192,
        96
      ],
      "id": "132773fb-5ee3-45fc-a5d8-5c4b9c59f244",
      "name": "Send to Workato",
      "executeOnce": true
    },
    {
      "parameters": {
        "resource": "search",
        "query": "=SELECT Id, Name, Lead_Source__c, Inbound_Outbound__c, Contact__c, Contact__r.Name, Contact__r.Email, Contact__r.Phone, Contact__r.Title, Contact__r.LinkedIn__c, Contact__r.Id FROM SQL__c  WHERE Status__c LIKE 'Qualified' AND Completed_Date__c = LAST_N_DAYS:480 AND (Contact__r.Job_Change_Last_Update__c = null OR Contact__r.Job_Change_Last_Update__c > LAST_N_DAYS:90) AND Company_Over_100__c = true AND \n(Sales_Type__c = 'Scale' OR Sales_Type__c = '') AND\nCountry_Mapping__c != 'India' AND\nCountry_Mapping__c != 'Brazil' AND\nContact__r.LinkedIn__c\t!= null\t ORDER BY Completed_Date__c DESC"
      },
      "type": "n8n-nodes-base.salesforce",
      "typeVersion": 1,
      "position": [
        -704,
        256
      ],
      "id": "1060acd7-9596-4a5d-8d0d-7571ae79f3dd",
      "name": "Qualified Inbounds1",
      "credentials": {
        "salesforceOAuth2Api": {
          "id": "Wf7k3VTmMdPB3Oaz",
          "name": "Yael's Salesforce"
        }
      }
    }
  ],
  "pinData": {
    "When clicking ‘Execute workflow’": [
      {
        "json": {}
      }
    ]
  },
  "connections": {
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "Create CSV7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Contact(s) Signals7": {
      "main": [
        [
          {
            "node": "Prepare for SFDC Enrichment7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare for API Call9": {
      "main": [
        [
          {
            "node": "Translate for bulkAPI call7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Translate for bulkAPI call7": {
      "main": [
        [
          {
            "node": "build contact list for API7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "build contact list for API7": {
      "main": [
        [
          {
            "node": "Get Contact(s) Signals7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare for SFDC Enrichment7": {
      "main": [
        [
          {
            "node": "New Rows Append7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items7": {
      "main": [
        [
          {
            "node": "New CSV Finalize",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare for API Call9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New Rows Append7": {
      "main": [
        [
          {
            "node": "Loop Over Items7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create CSV7": {
      "main": [
        [
          {
            "node": "Qualified Inbounds1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New CSV Finalize": {
      "main": [
        [
          {
            "node": "Send to Workato",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Qualified Inbounds1": {
      "main": [
        [
          {
            "node": "Loop Over Items7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "644bc133-e6f7-482b-b7c5-b16ccf7bfac9",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "ad674be1baa66a175e5700e3a65f1e5e99a1a542888741955c0f8e2cb71dbb75"
  },
  "id": "Wouxo7y6kJ6KV5p5",
  "tags": []
}