{
  "id": "Vq4i5ZRppnUXKXbZ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "CRM Hiring Enrichment & Slack Alerts with PredictLeads",
  "tags": [],
  "nodes": [
    {
      "id": "b070e426-c383-4350-8e5b-0bf42da3d888",
      "name": "About This Workflow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2880,
        480
      ],
      "parameters": {
        "color": 4,
        "width": 420,
        "height": 400,
        "content": "ABOUT THIS WORKFLOW\n\nPulls HubSpot companies, checks PredictLeads for new job openings, and sends Slack alerts when hiring spikes above 50%.\n\nSetup: HubSpot API, Google Sheets (for historical tracking), Slack bot, PredictLeads API credentials.\n\nUse case: Your sales team wants to know when target accounts ramp up hiring. A spike in engineering roles often means new budget and projects you can sell into.\n\nPredictLeads API: https://predictleads.com\nQuestions: https://www.linkedin.com/in/yaronbeen"
      },
      "typeVersion": 1
    },
    {
      "id": "80fa2c54-73ff-4d86-a3cc-99240a150b17",
      "name": "\ud83d\udccb Sticky: Trigger & Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2368,
        64
      ],
      "parameters": {
        "color": 5,
        "width": 460,
        "height": 778,
        "content": "## \u23f0 Trigger & Company Source\n\n**Nodes:**  \n\u23f0 Daily 9AM Trigger \u2192 \ud83c\udfe2 HubSpot Get Companies\n\n**Description:**  \nThe workflow begins with a scheduled trigger that runs every day at 9 AM.\n\nIt retrieves all companies from HubSpot CRM along with key identifiers such as the company domain, company name, and HubSpot company ID.\n\nThese companies represent the target accounts that will be monitored for hiring activity.  \nThe retrieved company data becomes the input dataset used for job monitoring and hiring signal detection."
      },
      "typeVersion": 1
    },
    {
      "id": "cd07e49b-a398-45b0-b8ad-f2589b3f0c3e",
      "name": "\ud83d\udccb Sticky: Enrichment",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1824,
        112
      ],
      "parameters": {
        "color": 5,
        "width": 780,
        "height": 938,
        "content": "## \ud83d\udd0d Hiring Data Collection\n\n**Nodes:**  \n\ud83d\udd04 Loop Over Companies \u2192 \ud83d\udd0d Fetch Job Openings \u2192 \u2699\ufe0f Filter Target Roles \u2192 \ud83d\udcc2 Read Historical Counts\n\n**Description:**  \nEach company is processed individually using a loop to evaluate its hiring activity.\n\nThe workflow queries the PredictLeads API to retrieve the company\u2019s current job openings.  \nIt then filters the results to focus on specific strategic roles such as sales, engineering, marketing, product, and data.\n\nAt the same time, the workflow retrieves previously stored hiring counts from Google Sheets.  \nThese historical values will be used to compare current hiring activity with past records."
      },
      "typeVersion": 1
    },
    {
      "id": "8441a9af-8161-449e-956b-521a8132379c",
      "name": "\ud83d\udccb Sticky: Processing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -944,
        96
      ],
      "parameters": {
        "color": 5,
        "width": 668,
        "height": 746,
        "content": "## \ud83d\udcca Hiring Spike Detection\n\n**Nodes:**  \nMerge \u2192 \ud83d\udcca Compare vs Historical \u2192 \u2753 Spike Detected?\n\n**Description:**  \nCurrent hiring data is merged with the historical job counts retrieved from Google Sheets.\n\nThe workflow calculates the percentage change between the current number of job openings and the previously recorded count.\n\nIf the increase exceeds the defined threshold (greater than 50%), the workflow flags the company as experiencing a **hiring spike**, which may indicate new projects, budget expansion, or increased operational activity."
      },
      "typeVersion": 1
    },
    {
      "id": "07be4ad9-94af-4567-97a4-a6a257602db1",
      "name": "\ud83d\udccb Sticky: Output",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -80
      ],
      "parameters": {
        "color": 5,
        "width": 556,
        "height": 1114,
        "content": "## \ud83d\udce4 Actions & Alerts\n\n**Nodes:**  \n\ud83c\udfe2 HubSpot Update Company \u2192 \ud83d\udcac Slack Spike Alert \u2192 \ud83d\udcdd Update Google Sheets \u2192 \ud83d\udcdd Update Sheets (No Spike)\n\n**Description:**  \nWhen a hiring spike is detected, the workflow updates the company record in HubSpot to mark the hiring signal and sends a Slack notification to alert the team.\n\nThis allows sales or business development teams to quickly identify companies that may be expanding and potentially require new services or solutions.\n\nRegardless of whether a spike occurs or not, the workflow updates the historical hiring data in Google Sheets so future comparisons remain accurate."
      },
      "typeVersion": 1
    },
    {
      "id": "87a23924-057b-4d87-8750-50723438f9d1",
      "name": "\u23f0 Daily 9AM Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2304,
        608
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "729320a5-0483-42b5-8051-e3f63d888d31",
      "name": "\ud83c\udfe2 HubSpot Get Companies",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        -2080,
        608
      ],
      "parameters": {
        "options": {
          "propertiesCollection": {
            "propertiesValues": {
              "properties": [
                "domain",
                "name",
                "hs_object_id"
              ],
              "propertyMode": "valueOnly"
            }
          }
        },
        "resource": "company",
        "operation": "getAll",
        "returnAll": true,
        "authentication": "oAuth2"
      },
      "credentials": {
        "hubspotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "e71918e2-8d65-4d89-8977-9491c22dc3e1",
      "name": "\ud83d\udd04 Loop Over Companies",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -1760,
        608
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "68ce9eea-9e77-4021-9c12-cf3e50ffad19",
      "name": "\ud83d\udd0d Fetch Job Openings",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1488,
        624
      ],
      "parameters": {
        "url": "=https://predictleads.com/api/v3/companies/{{ $json.properties.domain.value }}/job_openings",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Api-Key",
              "value": "YOUR_PREDICTLEADS_API_KEY"
            },
            {
              "name": "X-Api-Token",
              "value": "YOUR_PREDICTLEADS_API_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c9fbec2f-aebc-4b0f-aa3a-06d1dca17973",
      "name": "\u2699\ufe0f Filter Target Roles",
      "type": "n8n-nodes-base.code",
      "position": [
        -1264,
        624
      ],
      "parameters": {
        "jsCode": "// Configure target roles to monitor\nconst targetRoles = ['sales', 'engineering', 'marketing', 'product', 'data'];\n\nconst domain = $('\ud83d\udd04 Loop Over Companies').first().json.properties.domain;\nconst companyName = $('\ud83d\udd04 Loop Over Companies').first().json.properties.name;\nconst companyId = $('\ud83d\udd04 Loop Over Companies').first().json.properties.hs_object_id;\n\nconst allJobs = $input.first().json.data || [];\n\n// Filter jobs matching target roles\nconst matchingJobs = allJobs.filter(job => {\n  const title = (job.title || '').toLowerCase();\n  return targetRoles.some(role => title.includes(role));\n});\n\nreturn [{\n  json: {\n    domain,\n    companyName,\n    companyId,\n    totalJobCount: allJobs.length,\n    matchingJobCount: matchingJobs.length,\n    matchingJobs: matchingJobs.map(j => j.title),\n    targetRoles\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "858b869b-50f8-48c8-867c-3777dcaa8bef",
      "name": "\ud83d\udcca Compare vs Historical",
      "type": "n8n-nodes-base.code",
      "position": [
        -672,
        640
      ],
      "parameters": {
        "jsCode": "// Read historical data from Google Sheets input (connected via merge/lookup)\nconst current = $input.first().json;\nconst historicalRows = $('\ud83d\udcc2 Read Historical Counts').first().json.rows || [];\n\nconst domain = current.domain;\nconst currentCount = current.matchingJobCount;\n\n// Find previous count for this domain\nconst prevRow = historicalRows.find(r => r.domain === domain);\nconst previousCount = prevRow ? parseInt(prevRow.job_count || '0', 10) : 0;\n\n// Calculate percentage change\nlet percentChange = 0;\nif (previousCount > 0) {\n  percentChange = ((currentCount - previousCount) / previousCount) * 100;\n} else if (currentCount > 0) {\n  percentChange = 100; // New entries count as 100% spike\n}\n\nconst spikeDetected = percentChange > 50;\n\nreturn [{\n  json: {\n    ...current,\n    previousCount,\n    currentCount,\n    percentChange: Math.round(percentChange),\n    spikeDetected,\n    checkDate: new Date().toISOString().split('T')[0]\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "21bcd2c9-65d7-448d-9d06-5dfb3362c296",
      "name": "\ud83d\udcc2 Read Historical Counts",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1376,
        800
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.properties.domain.value }}",
              "lookupColumn": "domain"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit#gid=0",
          "cachedResultName": "HistoricalCounts"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID_01",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit?usp=drivesdk",
          "cachedResultName": "01"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "e0d06224-bf31-44f0-8a35-91c4c0d26afa",
      "name": "\u2753 Spike Detected?",
      "type": "n8n-nodes-base.if",
      "position": [
        -480,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-spike",
              "operator": {
                "name": "filter.operator.equals",
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.spikeDetected }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4365992b-105e-432b-8add-481f728abdcb",
      "name": "\ud83c\udfe2 HubSpot Update Company",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        -48,
        416
      ],
      "parameters": {
        "resource": "company",
        "companyId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.companyId.value }}"
        },
        "operation": "update",
        "updateFields": {
          "customPropertiesUi": {
            "customPropertiesValues": [
              {
                "value": "true",
                "property": "hiring_signal"
              }
            ]
          }
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "hubspotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "0197217f-01f7-4017-80ae-63e0cd42db11",
      "name": "\ud83d\udcdd Update Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        208,
        416
      ],
      "parameters": {
        "columns": {
          "value": {
            "domain": "={{ $('\ud83d\udcca Compare vs Historical').item.json.domain.value }}",
            "job_count": "={{ $('\ud83d\udcca Compare vs Historical').item.json.currentCount }}",
            "check_date": "={{ $('\ud83d\udcca Compare vs Historical').item.json.checkDate }}",
            "company_name": "={{ $('\ud83d\udcca Compare vs Historical').item.json.companyName.value }}",
            "percent_change": "={{ $('\ud83d\udcca Compare vs Historical').item.json.percentChange }}",
            "previous_count": "={{ $('\ud83d\udcca Compare vs Historical').item.json.previousCount }}"
          },
          "schema": [
            {
              "id": "domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "company_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "company_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "job_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "job_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "previous_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "previous_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "percent_change",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "percent_change",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "check_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "check_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "domain"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit#gid=0",
          "cachedResultName": "HistoricalCounts"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID_01",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit?usp=drivesdk",
          "cachedResultName": "01"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "1a954f94-3192-416e-92c5-eece04c75309",
      "name": "\ud83d\udcac Slack Spike Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        112,
        624
      ],
      "parameters": {
        "text": "=:chart_with_upwards_trend: *Hiring Spike Detected*\n\n*Company:* {{ $json.companyName.value }}\n*Domain:* {{ $json.domain.value }}\n*Current Open Roles:* {{ $json.currentCount }}\n*Previous Count:* {{ $json.previousCount }}\n*Change:* +{{ $json.percentChange }}%\n*Target Roles Found:* {{ $json.matchingJobs.join(', ') }}\n*Date:* {{ $json.checkDate }}\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "your-slack-channel"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d7a6621e-9690-4570-8e58-ea4014dd0c7f",
      "name": "\ud83d\udcdd Update Sheets (No Spike)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        16,
        816
      ],
      "parameters": {
        "columns": {
          "value": {
            "domain": "={{ $('\ud83d\udcca Compare vs Historical').item.json.domain.value }}",
            "job_count": "={{ $('\ud83d\udcca Compare vs Historical').item.json.currentCount }}",
            "check_date": "={{ $json.checkDate }}",
            "company_name": "={{ $('\ud83d\udcca Compare vs Historical').item.json.companyName.value }}",
            "percent_change": "={{ $json.percentChange }}",
            "previous_count": "={{ $json.previousCount }}"
          },
          "schema": [
            {
              "id": "domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "company_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "company_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "job_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "job_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "previous_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "previous_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "percent_change",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "percent_change",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "check_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "check_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "domain"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit#gid=0",
          "cachedResultName": "HistoricalCounts"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID_01",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_01/edit?usp=drivesdk",
          "cachedResultName": "01"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "e869fe10-e812-4ce4-ba0d-2be5085133a1",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -864,
        640
      ],
      "parameters": {},
      "typeVersion": 3.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "5017c175-8a42-4aef-b004-4a920fb8bd36",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "\ud83d\udcca Compare vs Historical",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2753 Spike Detected?": {
      "main": [
        [
          {
            "node": "\ud83c\udfe2 HubSpot Update Company",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udcac Slack Spike Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udcdd Update Sheets (No Spike)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23f0 Daily 9AM Trigger": {
      "main": [
        [
          {
            "node": "\ud83c\udfe2 HubSpot Get Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd0d Fetch Job Openings": {
      "main": [
        [
          {
            "node": "\u2699\ufe0f Filter Target Roles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd04 Loop Over Companies": {
      "main": [
        [],
        [
          {
            "node": "\ud83d\udd0d Fetch Job Openings",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udcc2 Read Historical Counts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Update Google Sheets": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Loop Over Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2699\ufe0f Filter Target Roles": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83c\udfe2 HubSpot Get Companies": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Loop Over Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcca Compare vs Historical": {
      "main": [
        [
          {
            "node": "\u2753 Spike Detected?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83c\udfe2 HubSpot Update Company": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Update Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcc2 Read Historical Counts": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\ud83d\udcdd Update Sheets (No Spike)": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Loop Over Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}