{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "161e4cdd-577a-4f7a-a29e-222d0036ed43",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -768,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "b2120ce5-179e-4827-a091-95f2b4c87f69",
      "name": "Remove Intern",
      "type": "n8n-nodes-base.filter",
      "position": [
        1648,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7c012b9c-9e41-4ce6-b957-f54c8ba7cf32",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ \n!($json.text || '').toLowerCase().includes('internship ') &&\n!($json.text || '').toLowerCase().includes('intern ') &&\n!($json.text || '').toLowerCase().includes('interns ')\n}}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f88265e3-73e3-469e-bb33-8721d29054d3",
      "name": "Removing Noise",
      "type": "n8n-nodes-base.filter",
      "position": [
        768,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "73b68bd1-5491-45dd-a9ad-27205ad357e5",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{\n!($json.text || '').toLowerCase().includes('tips for') &&\n!($json.text || '').toLowerCase().includes('lessons learned') &&\n!($json.text || '').toLowerCase().includes('hot take') &&\n!($json.text || '').toLowerCase().includes('unpopular opinion') &&\n!($json.text || '').toLowerCase().includes('in my experience') &&\n!($json.text || '').toLowerCase().includes('what i learned') &&\n\n!($json.text || '').toLowerCase().includes('i built') &&\n!($json.text || '').toLowerCase().includes('we built') &&\n!($json.text || '').toLowerCase().includes('i build') &&\n!($json.text || '').toLowerCase().includes('just built') &&\n!($json.text || '').toLowerCase().includes('launching') &&\n!($json.text || '').toLowerCase().includes('my project') &&\n!($json.text || '').toLowerCase().includes('just shipped') &&\n\n!($json.text || '').toLowerCase().includes('thread:') &&\n!($json.text || '').toLowerCase().includes('\ud83e\uddf5') &&\n!($json.text || '').toLowerCase().includes('agree?') &&\n!($json.text || '').toLowerCase().includes('what do you think') &&\n!($json.text || '').toLowerCase().includes('follow me') &&\n!($json.text || '').toLowerCase().includes('stop paying') &&\n!($json.text || '').toLowerCase().includes('we automate') &&\n!($json.text || '').toLowerCase().includes('i automate') &&\n!($json.text || '').toLowerCase().includes('here is how') &&\n!($json.text || '').toLowerCase().includes('most linkedin') &&\n!($json.text || '').toLowerCase().includes('here is the stack') &&\n!($json.text || '').toLowerCase().includes('using today') &&\n!($json.text || '').toLowerCase().includes('a day in my life') &&\n!($json.text || '').toLowerCase().includes(\"i'm calling it\") &&\n!($json.text || '').toLowerCase().includes(\"i'll share updates\") &&\n!($json.text || '').toLowerCase().includes(\"workshop \") &&\n!($json.text || '').toLowerCase().includes(\"eventbrite\") &&\n!($json.text || '').toLowerCase().includes(\"registration\") &&\n!($json.text || '').toLowerCase().includes(\"tired of\") &&\n!($json.text || '').toLowerCase().includes(\"not hiring\") &&\n!($json.text || '').toLowerCase().includes('saved hours') &&\n!($json.text || '').toLowerCase().includes('spending hours') &&\n!($json.text || '').toLowerCase().includes('stop waisting time')\n}}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "a0dd98a8-9812-4c70-adf0-218a0f8b1907",
      "name": "Remove Job Seakers",
      "type": "n8n-nodes-base.filter",
      "position": [
        1024,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5ebeffe8-af6d-44fc-baff-0a11ed6ad69b",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ \n!($json.text || '').toLowerCase().includes(\"i'm actively looking\") &&\n!($json.text || '').toLowerCase().includes(\"i am actively looking\") &&\n!($json.text || '').toLowerCase().includes(\"seeking my next role\") &&\n!($json.text || '').toLowerCase().includes(\"looking for my next role\") &&\n!($json.text || '').toLowerCase().includes(\"open to new opportunities\") &&\n!($json.text || '').toLowerCase().includes(\"i'm open to work\") &&\n!($json.text || '').toLowerCase().includes(\"i am open to work\") &&\n!($json.text || '').toLowerCase().includes(\"hire me\") &&\n!($json.text || '').toLowerCase().includes(\"my next opportunity\") &&\n!($json.text || '').toLowerCase().includes(\"what i'm looking for\") &&\n!($json.text || '').toLowerCase().includes(\"what i am looking for\") &&\n!($json.text || '').toLowerCase().includes(\"excited to share my cv\")\n}}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8935a5b5-b297-4edc-980b-51da64d4ad24",
      "name": "Generate Fingerprint",
      "type": "n8n-nodes-base.set",
      "position": [
        -144,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d26a1e51-9789-4a0a-9440-585ce9ed0b2d",
              "name": "fingerprint",
              "type": "string",
              "value": "={{\n  (() => {\n    const text = ($json.text || '').toLowerCase().trim();\n    const words = text.split(/\\s+/);\n    const midIndex = Math.floor(words.length / 2);\n    return words.slice(midIndex - 5, midIndex + 5).join(' ');\n  })()\n}}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "05240ec7-9d88-443d-9496-ef1b28949a77",
      "name": "If Intent true",
      "type": "n8n-nodes-base.filter",
      "position": [
        1440,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7c012b9c-9e41-4ce6-b957-f54c8ba7cf32",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.hiringIntent }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0f282796-64d4-4855-a082-643d24a40679",
      "name": "Match Job Title",
      "type": "n8n-nodes-base.filter",
      "position": [
        1840,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "53dae17b-3863-4631-a137-af5d67c2ceaf",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ \n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation specialist')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation expert')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation analyst')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('automation consultant')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('workflow engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('workflow developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('workflow specialist')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('workflow automation')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('integration engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('integration specialist')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('integration developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai automation engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai automation specialist')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai automation expert')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai agent engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('ai agent developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('no-code developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('no-code engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('low-code developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('low-code engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('crm automation')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n expert')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n developer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n specialist')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n wizard')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n workflow')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n analyst')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('n8n consultant')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('gtm engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('growth engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('systems automation')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('technical automation')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('systems engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('system engineer')) ||\n(($json.cleanedText || $json.text || '').toLowerCase().includes('business automation'))\n}}",
              "rightValue": ""
            },
            {
              "id": "4437c76b-fe68-4c90-a14c-09685a94a922",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ ($json.text || '').toLowerCase().includes('n8n') }}",
              "rightValue": "n8n"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "859e56be-2529-4941-830e-baa7534ad79a",
      "name": "Enrich Data",
      "type": "n8n-nodes-base.code",
      "position": [
        2096,
        0
      ],
      "parameters": {
        "jsCode": "const posts = $input.all();\nconst results = [];\n\n// ============================================\n// \u2705 STEP 1: Unicode to Plain Text Converter\n// ============================================\nfunction toPlainText(str) {\n  if (!str) return '';\n\n  // Unicode ranges mapping to plain ASCII\n  const ranges = [\n    // Bold serif: \ud835\udc00-\ud835\udc19, \ud835\udc1a-\ud835\udc33\n    [0x1D400, 0x1D419, 'A'], [0x1D41A, 0x1D433, 'a'],\n    // Italic serif: \ud835\udc3c-\ud835\udc4d, \ud835\udc4e-\ud835\udc67\n    [0x1D434, 0x1D44D, 'A'], [0x1D44E, 0x1D467, 'a'],\n    // Bold italic serif: \ud835\udc68-\ud835\udc81, \ud835\udc82-\ud835\udc9b\n    [0x1D468, 0x1D481, 'A'], [0x1D482, 0x1D49B, 'a'],\n    // Sans bold: \ud835\uddd4-\ud835\udded, \ud835\uddee-\ud835\ude07\n    [0x1D5D4, 0x1D5ED, 'A'], [0x1D5EE, 0x1D607, 'a'],\n    // Sans italic: \ud835\ude08-\ud835\ude21, \ud835\ude22-\ud835\ude3b\n    [0x1D608, 0x1D621, 'A'], [0x1D622, 0x1D63B, 'a'],\n    // Sans bold italic: \ud835\ude40-\ud835\ude55 (used by LinkedIn bold)\n    [0x1D63C, 0x1D655, 'A'], [0x1D656, 0x1D66F, 'a'],\n    // Monospace: \ud835\ude70-\ud835\ude89, \ud835\ude8a-\ud835\udea3\n    [0x1D670, 0x1D689, 'A'], [0x1D68A, 0x1D6A3, 'a'],\n  ];\n\n  let result = '';\n  for (const char of str) {\n    const code = char.codePointAt(0);\n    let replaced = false;\n    for (const [start, end, base] of ranges) {\n      if (code >= start && code <= end) {\n        const offset = base.charCodeAt(0);\n        result += String.fromCharCode(offset + (code - start));\n        replaced = true;\n        break;\n      }\n    }\n    if (!replaced) result += char;\n  }\n\n  // Also handle bold digits: \ud835\udfec-\ud835\udff5 (LinkedIn uses these too)\n  result = result.replace(/[\ud835\udfec\ud835\udfed\ud835\udfee\ud835\udfef\ud835\udff0\ud835\udff1\ud835\udff2\ud835\udff3\ud835\udff4\ud835\udff5]/g, (c) => {\n    const boldDigits = '\ud835\udfec\ud835\udfed\ud835\udfee\ud835\udfef\ud835\udff0\ud835\udff1\ud835\udff2\ud835\udff3\ud835\udff4\ud835\udff5';\n    return String(boldDigits.indexOf(c));\n  });\n\n  return result;\n}\n\n// ============================================\n// \u2705 STEP 2: Process Each Post\n// ============================================\nfor (const post of posts) {\n  const rawText = post.json.text || '';\n\n  // Convert bold/italic/bold-italic \u2192 plain text\n  const plainText = toPlainText(rawText);\n\n  // Use plain text for all extractions below\n  const lowerText = plainText.toLowerCase();\n\n  // \u2705 Extract lnkd.in URLs\n  const applyLinks = plainText.match(/https?:\\/\\/lnkd\\.in\\/[^\\s\\]\\)\"]+/g) || [];\n\n  // \u2705 Extract normal URLs (excluding lnkd.in)\n  const otherLinks = plainText.match(/https?:\\/\\/(?!lnkd\\.in)[^\\s\\]\\)\"]+/g) || [];\n\n  // \u2705 Extract WhatsApp links\n  const whatsappLinks = plainText.match(/https?:\\/\\/wa\\.me\\/[^\\s]+/g) || [];\n\n  // \u2705 Extract emails\n  const emails = plainText.match(/[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}/g) || [];\n\n  // \u2705 Extract phone numbers\n  const rawPhones = plainText.match(\n    /(?:\\+|00)?[\\s.-]?(\\d{1,3})[\\s.-]?\\(?(\\d{2,4})\\)?[\\s.-]?(\\d{2,4})[\\s.-]?(\\d{2,6})(?:[\\s.-]?(\\d{1,4}))?/g\n  ) || [];\n\n  // Clean & filter valid phone numbers only\n  const phones = rawPhones\n    .map(p => p.trim().replace(/\\s+/g, ' '))\n    .filter(p => {\n      const digits = p.replace(/\\D/g, '');\n      return digits.length >= 7 && digits.length <= 15;\n    });\n\n  // \u2705 Job Type Detection (now works even if word was bold/italic)\n  let job_type = 'On-Site';\n  if (lowerText.includes('remote')) {\n    job_type = 'Remote';\n  } else if (lowerText.includes('hybrid')) {\n    job_type = 'Hybrid';\n  }\n\n  results.push({\n    json: {\n      original_text: rawText,\n      plain_text:    plainText,\n      job_type,\n\n      // \u2705 First item only\n      apply_link_1: applyLinks[0] || null,\n      email_1:      emails[0]     || null,\n      phone_1:      phones[0]     || null,\n      whatsapp_1:   whatsappLinks[0] || null,\n\n      // \u2705 All items \u2014 comma separated string\n      all_apply_links: applyLinks.join(', ') || null,\n      all_emails:      emails.join(', ')     || null,\n      all_phones:      phones.join(', ')     || null,\n      all_other_links: otherLinks.join(', ') || null,\n      all_whatsapp:    whatsappLinks.join(', ') || null,\n    }\n  });\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "8f67f0a4-3ff1-4b31-abe0-b21a53e140c2",
      "name": "FInal Output",
      "type": "n8n-nodes-base.set",
      "position": [
        2288,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4d59d5c6-904c-4571-9723-ef0463c1f499",
              "name": "job_type",
              "type": "string",
              "value": "={{ $json.job_type }}"
            },
            {
              "id": "f43c89be-1773-4893-add3-132f3666b063",
              "name": "apply_link_1",
              "type": "string",
              "value": "={{ $json.apply_link_1 }}"
            },
            {
              "id": "5dbcbf57-30ed-43c4-b7e0-9ceeef668e93",
              "name": "email_1",
              "type": "string",
              "value": "={{ $json.email_1 }}"
            },
            {
              "id": "3cc1d3d3-db40-491d-ad1e-6de3cf7a972f",
              "name": "phone_1",
              "type": "string",
              "value": "={{ $json.phone_1 }}"
            },
            {
              "id": "4e7cabe1-94f6-4b5e-88af-6bcd9d81a973",
              "name": "whatsapp_1",
              "type": "string",
              "value": "={{ $json.whatsapp_1 }}"
            },
            {
              "id": "a023ca80-f0e0-48b6-8ef2-c545a18d3ec3",
              "name": "all_apply_links",
              "type": "string",
              "value": "={{ $json.all_apply_links }}"
            },
            {
              "id": "50db5+1234567890f-8842-f29b5821a5e3",
              "name": "all_emails",
              "type": "string",
              "value": "={{ $json.all_emails }}"
            },
            {
              "id": "ba837192-9ff3-45b3-b688-7ec8e97e01c0",
              "name": "all_phones",
              "type": "string",
              "value": "={{ $json.all_phones }}"
            },
            {
              "id": "9ad67de8-6d08-4515-aa0d-17807c8a6589",
              "name": "all_other_links",
              "type": "string",
              "value": "={{ $json.all_other_links }}"
            },
            {
              "id": "cfb7741d-7add-4c03-8bae-3e73309178e8",
              "name": "all_whatsapp",
              "type": "string",
              "value": "={{ $json.all_whatsapp }}"
            },
            {
              "id": "4f8cafb4-5299-4cbd-9fb0-5d2b25d9aa5e",
              "name": "post_text",
              "type": "string",
              "value": "={{ $('Match Job Title').item.json.text }}"
            },
            {
              "id": "fa2e835d-ec37-4bca-9406-8312c9d40157",
              "name": "post_url",
              "type": "string",
              "value": "={{ $('Match Job Title').item.json.url }}"
            },
            {
              "id": "f02ebf9a-e06c-4bab-99cc-a1a490bf760c",
              "name": "authorName",
              "type": "string",
              "value": "={{ $('Match Job Title').item.json.authorName }}"
            },
            {
              "id": "29064672-ca9b-4010-8ffe-ea21c483dca9",
              "name": "authorLinkedin",
              "type": "string",
              "value": "=https://www.linkedin.com/in/{{ $('Match Job Title').item.json.authorProfileId }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fdcd4596-2878-44f2-a0e1-84b231ee9e5e",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2480,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $json.email_1 }}",
            "jobType": "={{ $json.job_type }}",
            "postURL": "={{ $json.post_url }}",
            "applyLink": "={{ $json.apply_link_1 }}",
            "all_emails": "={{ $json.all_emails }}",
            "all_phones": "={{ $json.all_phones }}",
            "authorName": "={{ $json.authorName }}",
            "phoneNumber": "={{ $json.phone_1 }}",
            "postContent": "={{ $json.post_text }}",
            "publishedDate": "={{ $('Match Job Title').item.json.postedAtISO.toDateTime().format('dd-MM-yyyy') }}",
            "authorLinkedin": "={{ $json.authorLinkedin }}",
            "all_apply_links": "={{ $json.all_apply_links }}",
            "all_other_links": "={{ $json.all_other_links }}",
            "all_whatsapp_links": "={{ $json.all_whatsapp }}"
          },
          "schema": [
            {
              "id": "postContent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "postContent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "postURL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "postURL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "jobType",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "jobType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "publishedDate",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "publishedDate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phoneNumber",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "phoneNumber",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "applyLink",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "applyLink",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "authorName",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "authorName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "authorLinkedin",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "authorLinkedin",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "all_apply_links",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "all_apply_links",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "all_emails",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "all_emails",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "all_phones",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "all_phones",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "all_other_links",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "all_other_links",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "all_whatsapp_links",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "all_whatsapp_links",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": false,
          "cellFormat": "RAW",
          "locationDefine": {
            "values": {
              "headerRow": 2
            }
          }
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1E3fxJDn8E-q6Z4Ietptb18R-WJUuslFtDqZ4zrPE41c/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1E3fxJDn8E-q6Z4Ietptb18R-WJUuslFtDqZ4zrPE41c",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1E3fxJDn8E-q6Z4Ietptb18R-WJUuslFtDqZ4zrPE41c/edit?usp=drivesdk",
          "cachedResultName": "n8n Hiring posts data"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "32996479-fa27-47c0-8f69-435616075f93",
      "name": "Remove Duplicates Posts",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        96,
        0
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "fingerprint"
      },
      "typeVersion": 2
    },
    {
      "id": "ebaff9b1-46a1-454d-8bcd-dfbe20eba0e9",
      "name": "If Job Not in Databse",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        336,
        0
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "post_ID",
              "keyValue": "={{ $json.urn }}"
            }
          ]
        },
        "operation": "rowNotExists",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "PP5qAMSqzrJ365gC",
          "cachedResultUrl": "/projects/UixkftX5yd6UCJ81/datatables/PP5qAMSqzrJ365gC",
          "cachedResultName": "Post Job Scraper"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "1a8269c8-c59e-4332-a169-ec279de1af5b",
      "name": "Insert row",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        544,
        96
      ],
      "parameters": {
        "columns": {
          "value": {
            "post_ID": "={{ $json.urn }}"
          },
          "schema": [
            {
              "id": "post_ID",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "post_ID",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "post_ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "optimizeBulk": true
        },
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "PP5qAMSqzrJ365gC",
          "cachedResultUrl": "/projects/UixkftX5yd6UCJ81/datatables/PP5qAMSqzrJ365gC",
          "cachedResultName": "Post Job Scraper"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "3a01fab7-b578-46df-a730-372cd0fb1039",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        -528
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## \ud83c\udfaf LinkedIn Hiring Post Scraper - For Any Role or Tool\n\n**Who is this for?**\nFreelancers, agencies, and job seekers who want to automatically track LinkedIn hiring posts for any skill, tool, or job title \u2014 without checking manually every day.\n\n**What it does**\nScrapes LinkedIn post search results every 6 hours, removes noise and job seekers, confirms real hiring intent, matches your target job titles, extracts contact info, and saves every lead to Google Sheets automatically.\n\n---\n\n### How it works\n\n1. **Schedule Trigger** \u2014 runs every 6 hours automatically\n2. **Get Posts** \u2014 Apify scrapes LinkedIn posts from your custom search URLs\n3. **Generate Fingerprint** \u2014 removes duplicate posts within the same run\n4. **Database Check** \u2014 skips any post already seen in a previous run\n5. **Removing Noise** \u2014 filters out tips, events, and self-promo posts\n6. **Remove Job Seekers** \u2014 removes \"hire me\" and \"open to work\" posts\n7. **Check Hiring Intent** \u2014 confirms the post is a genuine hiring post\n8. **Match Job Title** \u2014 keeps only posts matching your tool + job titles\n9. **Enrich Data** \u2014 extracts email, phone, WhatsApp, and apply links\n10. **Google Sheets** \u2014 logs every clean lead automatically\n\n---\n\n### Who benefits\n\n**Freelancers** \u2014 find clients posting for your exact skill set\n\n**Agencies** \u2014 build a hiring signal pipeline for outreach\n\n**Job seekers** \u2014 catch opportunities before anyone else does\n\n---\n\n### Setup Checklist\n- [ ] Add Apify credentials to **Get Posts**\n- [ ] Paste your own LinkedIn search URLs in **Get Posts**\n- [ ] Create a DataTable named **Post Job Scraper** with one column: `post_ID`\n- [ ] Connect your Google Sheet in **Append row in sheet**\n- [ ] Customize job titles and tool name in **Match Job Title**"
      },
      "typeVersion": 1
    },
    {
      "id": "b5339372-7c94-42ef-a34c-29d28a161b60",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 384,
        "content": "## \u23f0 Schedule & Data Collection\n\n**Schedule Trigger**\n\u26a0\ufe0f Currently runs every **6 hours** \u2014 adjust interval if needed.\n\n---\n\n**Apify Actor**\n\u26a0\ufe0f Build your search URL directly on LinkedIn, copy it from the browser, then paste it inside the `urls` array in this node.\n\nCurrent URLs are pre-set for **n8n hiring posts** \u2014 replace with your own.\n\n\u26a0\ufe0f `\"limitPerSource\": 150` \u2192 max posts per URL. Change as needed."
      },
      "typeVersion": 1
    },
    {
      "id": "009ab6b6-9ab2-48e9-86dc-186de630fdc5",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 608,
        "content": "## \ud83d\udd04 Deduplication & Database Check\n\nTwo-layer system to prevent duplicate posts across all runs.\n\n**Layer 1 \u2014 Fingerprint**\nCatches duplicates within the same run. \u26a0\ufe0f No changes needed.\n\n**Layer 2 \u2014 DataTable**\nChecks LinkedIn post URN against database. If seen before \u2192 skipped permanently.\n\n\u26a0\ufe0f **Setup required:**\n- Create a DataTable named **\"Post Job Scraper\"**\n- Add one column: `post_ID` (string)\n- Link it in **\"If Job Not in Database\"** and **\"Insert row\"** nodes"
      },
      "typeVersion": 1
    },
    {
      "id": "4d964c17-09fa-47ce-9786-384dd1a44a77",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 448,
        "content": "## \ud83e\uddf9 Data Filtering & Cleaning\n\n**Removing Noise**\nRemoves thought leadership, self-promo, events, and engagement posts.\n\u26a0\ufe0f Add your own phrases inside this node if needed.\n\n---\n\n**Remove Job Seekers**\nRemoves \"hire me\" and \"open to work\" style posts.\n\u26a0\ufe0f Add more phrases inside this node if needed."
      },
      "typeVersion": 1
    },
    {
      "id": "e56ea876-5b80-4308-a541-5d32f5c4cea1",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 592,
        "content": "## \ud83c\udfaf Intent Analysis & Job Title Matching\n\n**Intent Analyzer**\nChecks if the post is a real hiring post using 35+ hiring phrases.\nAlso converts LinkedIn bold/italic text to plain ASCII before checking.\n\u26a0\ufe0f No changes needed.\n\n---\n\n**Remove Intern** \ud83d\udeab\nRemoves internship and fresher posts automatically.\n\u26a0\ufe0f No changes needed.\n\n---\n\n**Match Job Title** \ud83c\udfaf \u2190 Main Customization Point\n\nTwo conditions work together with **AND** logic:\n1. Post must contain your **tool name** (currently `n8n`)\n2. Post must mention one of your **target job titles**\n\n\u26a0\ufe0f Open this node and customize:\n- Replace `n8n` with your tool (e.g. Zapier, Make)\n- Add or remove job titles to match what you are looking for"
      },
      "typeVersion": 1
    },
    {
      "id": "73fb4e0f-a537-4c5a-ba5b-57f6b56442f5",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 352,
        "content": "## \ud83d\udcca Data Enrichment & Output\n\nExtracts emails, phone numbers, WhatsApp links, and apply links from the post \u2014 then logs everything into Google Sheets.\n\n\u26a0\ufe0f Replace the Google Sheet ID with your own inside the **\"Append row in sheet\"** node."
      },
      "typeVersion": 1
    },
    {
      "id": "d5b43d9d-76aa-40ae-bc53-3d0df46b6120",
      "name": "Check Hiring Intent",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        0
      ],
      "parameters": {
        "jsCode": "// Helper: Convert Unicode bold/italic to plain ASCII\nfunction normalizeText(text) {\n  if (!text) return '';\n  \n  let result = '';\n  for (const char of text) {\n    const code = char.codePointAt(0);\n    \n    if (code >= 0x1D400 && code <= 0x1D7FF) {\n      if      (code >= 0x1D400 && code <= 0x1D419) result += String.fromCharCode(code - 0x1D400 + 65);\n      else if (code >= 0x1D41A && code <= 0x1D433) result += String.fromCharCode(code - 0x1D41A + 97);\n      else if (code >= 0x1D434 && code <= 0x1D44D) result += String.fromCharCode(code - 0x1D434 + 65);\n      else if (code >= 0x1D44E && code <= 0x1D467) result += String.fromCharCode(code - 0x1D44E + 97);\n      else if (code >= 0x1D468 && code <= 0x1D481) result += String.fromCharCode(code - 0x1D468 + 65);\n      else if (code >= 0x1D482 && code <= 0x1D49B) result += String.fromCharCode(code - 0x1D482 + 97);\n      else if (code >= 0x1D5D4 && code <= 0x1D5ED) result += String.fromCharCode(code - 0x1D5D4 + 65);\n      else if (code >= 0x1D5EE && code <= 0x1D607) result += String.fromCharCode(code - 0x1D5EE + 97);\n      else if (code >= 0x1D608 && code <= 0x1D621) result += String.fromCharCode(code - 0x1D608 + 65);\n      else if (code >= 0x1D622 && code <= 0x1D63B) result += String.fromCharCode(code - 0x1D622 + 97);\n      else if (code >= 0x1D63C && code <= 0x1D655) result += String.fromCharCode(code - 0x1D63C + 65);\n      else if (code >= 0x1D656 && code <= 0x1D66F) result += String.fromCharCode(code - 0x1D656 + 97);\n      else result += char;\n    } else {\n      result += char;\n    }\n  }\n  \n  return result\n    .replace(/[\\u2018\\u2019\\u02BC\\u0060]/g, \"'\")\n    .toLowerCase();\n}\n\n// Process ALL items\nconst results = $input.all().map(item => {\n  const rawText = item.json.text || '';\n  const cleanText = normalizeText(rawText);\n\n  const keywordMatches = {\n    'hiring a':                  cleanText.includes('hiring a'),\n    'hiring:':                   cleanText.includes('hiring:'),\n    'we are hiring':             cleanText.includes('we are hiring'),\n    \"we're hiring (curly)\":      cleanText.includes(\"we\\u2019re hiring\"),\n    \"we're hiring (straight)\":   cleanText.includes(\"we're hiring\"),\n    'hiring for':                cleanText.includes('hiring for'),\n    'looking for':               cleanText.includes('looking for'),\n    'need to hire':              cleanText.includes('need to hire'),\n    'open position':             cleanText.includes('open position'),\n    'job opportunity':           cleanText.includes('job opportunity'),\n    \"i'm hiring\":                cleanText.includes(\"i'm hiring\"),\n    'i am hiring':               cleanText.includes('i am hiring'),\n    'i am looking for':          cleanText.includes('i am looking for'),\n    'i am looking a':            cleanText.includes('i am looking a'),\n    'i am looking an':           cleanText.includes('i am looking an'),\n    'i am looking to':           cleanText.includes('i am looking to'),\n    \"i'm looking to\":            cleanText.includes(\"i'm looking to\"),\n    \"i'm looking for\":           cleanText.includes(\"i'm looking for\"),\n    \"i'm looking a\":             cleanText.includes(\"i'm looking a\"),\n    \"i'm looking an\":            cleanText.includes(\"i'm looking an\"),\n    'now hiring':                cleanText.includes('now hiring'),\n    'join our team':             cleanText.includes('join our team'),\n    'we are looking for':        cleanText.includes('we are looking for'),\n    'apply now':                 cleanText.includes('apply now'),\n    'job opening':               cleanText.includes('job opening'),\n    'immediate opening':         cleanText.includes('immediate opening'),\n    'hiring ai engineer':        cleanText.includes('hiring ai engineer'),\n    'sourcing for':          cleanText.includes('sourcing for'),\n    'currently sourcing':    cleanText.includes('currently sourcing'),\n    'how to apply':          cleanText.includes('how to apply'),\n    'apply through the link': cleanText.includes('apply through the link'),\n    'apply here':               cleanText.includes('apply here'),\n    'apply via the link':       cleanText.includes('apply via the link'),\n    'position has opened':      cleanText.includes('position has opened'),\n    'share your resume':        cleanText.includes('share your resume'),\n    'kindly share your resume': cleanText.includes('kindly share your resume'),\n    'send your resume':         cleanText.includes('send your resume'),\n    'send us your resume':      cleanText.includes('send us your resume'),\n  };\n\n  const hiringIntent = Object.values(keywordMatches).some(v => v === true);\n\n  return {\n    json: {\n      ...item.json,\n      cleanedText: cleanText,\n      hiringIntent,\n      matchedKeywords: Object.entries(keywordMatches)\n        .filter(([k, v]) => v)\n        .map(([k]) => k),\n    }\n  };\n});\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "ebf9cc88-e6d2-494f-8b08-f5befd66e2c4",
      "name": "Get Posts",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        -480,
        0
      ],
      "parameters": {
        "actorId": {
          "__rl": true,
          "mode": "id",
          "value": "Wpp1BZ6yGWjySadk3"
        },
        "timeout": {},
        "operation": "Run actor and get dataset",
        "customBody": "{\n    \"deepScrape\": true,\n    \"limitPerSource\": 150,\n    \"rawData\": false,\n    \"urls\": [\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cautomation%20expert%E2%80%9D%20AND%20%E2%80%9Chiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=FACETED_SEARCH&sortBy=%5B%22date_posted%22%5D\",\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cautomation%20engineer%E2%80%9D%20AND%20hiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=GLOBAL_SEARCH_HEADER&sortBy=%5B%22date_posted%22%5D\",\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cautomation%20specialist%E2%80%9D%20AND%20%E2%80%9Chiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=FACETED_SEARCH&sortBy=%5B%22date_posted%22%5D\",\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cworkflow%20automation%E2%80%9D%20AND%20hiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=GLOBAL_SEARCH_HEADER&sortBy=%5B%22date_posted%22%5D\",\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cn8n%20expert%20%E2%80%9C%20AND%20%E2%80%9Chiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=GLOBAL_SEARCH_HEADER&sortBy=%5B%22date_posted%22%5D\",\n      \"https://www.linkedin.com/search/results/content/?keywords=%E2%80%9Cai%20automation%E2%80%9D%20AND%20hiring%E2%80%9D%20AND%20%E2%80%9Cn8n%E2%80%9D%20NOT%20%28%E2%80%9Cintern%E2%80%9D%20OR%20%E2%80%9Cinternship%E2%80%9D%29%20%20NOT%20%E2%80%9Copen%20to%20work%E2%80%9D&origin=GLOBAL_SEARCH_HEADER&sortBy=%5B%22date_posted%22%5D\"\n    ]\n}"
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Get Posts": {
      "main": [
        [
          {
            "node": "Generate Fingerprint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert row": {
      "main": [
        []
      ]
    },
    "Enrich Data": {
      "main": [
        [
          {
            "node": "FInal Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FInal Output": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Intern": {
      "main": [
        [
          {
            "node": "Match Job Title",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Intent true": {
      "main": [
        [
          {
            "node": "Remove Intern",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Removing Noise": {
      "main": [
        [
          {
            "node": "Remove Job Seakers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Job Title": {
      "main": [
        [
          {
            "node": "Enrich Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Job Seakers": {
      "main": [
        [
          {
            "node": "Check Hiring Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Hiring Intent": {
      "main": [
        [
          {
            "node": "If Intent true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Fingerprint": {
      "main": [
        [
          {
            "node": "Remove Duplicates Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Job Not in Databse": {
      "main": [
        [
          {
            "node": "Insert row",
            "type": "main",
            "index": 0
          },
          {
            "node": "Removing Noise",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates Posts": {
      "main": [
        [
          {
            "node": "If Job Not in Databse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}