{
  "name": "CV-analyzer",
  "nodes": [
    {
      "parameters": {
        "promptType": "define",
        "text": "=Zwr\u00f3\u0107 wynik w formacie JSON o strukturze:\n   {\n     \"full_name\": \"...\",\n     \"email\": \"...\",\n     \"phone\": \"...\",\n     \"years_experience\": ...,\n     \"key_skills\": [\"...\", \"...\"],\n     \"job_history\": [{\"company\": \"...\", \"role\": \"...\", \"period\": \"...\"}],\n     \"education\": \"...\",\n     \"match_score\": ...,\n     \"match_reason\": \"...\"\n   }\n\nCa\u0142e CV jest zawarte w {{ $json.text }}",
        "options": {
          "systemMessage": "Jeste\u015b ekspertem HR w agencji marketingowej. Otrzymujesz CV kandydata na stanowisko [wstaw stanowisko, np. \"Specjalista ds. marketingu cyfrowego\"]. \nTwoim zadaniem jest:\n1. Wyodr\u0119bnij: imi\u0119 i nazwisko, e\u2011mail, telefon, lata do\u015bwiadczenia, kluczowe umiej\u0119tno\u015bci (wymie\u0144 max 5), dotychczasowe stanowiska (firma, rola, okres), wykszta\u0142cenie.\n2. Oce\u0144 dopasowanie kandydata do stanowiska w skali 0-100%, uwzgl\u0119dniaj\u0105c: do\u015bwiadczenie w marketingu (waga 40%), znajomo\u015b\u0107 narz\u0119dzi (Google Ads, Meta Ads, SEO \u2013 waga 30%), umiej\u0119tno\u015bci mi\u0119kkie (waga 20%), dodatkowe osi\u0105gni\u0119cia (waga 10%).\n3. Podaj kr\u00f3tkie uzasadnienie oceny (2-3 zdania)."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        -1648,
        -112
      ],
      "id": "35876bb9-c5a5-44e4-9d6a-8efa6103fec3",
      "name": "Analyze CV"
    },
    {
      "parameters": {
        "jsCode": "const aiOutput = $('Analyze CV').first().json.output; // dostosuj pole je\u015bli trzeba\n\n// Wyci\u0105gnij JSON z markdown code blocka lub czystego tekstu\nfunction extractJSON(text) {\n  // Usu\u0144 ```json ... ``` lub ``` ... ```\n  const codeBlockMatch = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n  if (codeBlockMatch) {\n    return JSON.parse(codeBlockMatch[1].trim());\n  }\n\n  // Spr\u00f3buj wyci\u0105gn\u0105\u0107 surowy JSON (np. { ... })\n  const rawMatch = text.match(/\\{[\\s\\S]*\\}/);\n  if (rawMatch) {\n    return JSON.parse(rawMatch[0].trim());\n  }\n\n  throw new Error('Nie znaleziono JSON-a w odpowiedzi AI');\n}\n\nconst parsed = extractJSON(aiOutput);\n\nreturn [{ json: parsed }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1296,
        -112
      ],
      "id": "4b2e90a1-187a-4180-9d84-8b3bf47321e0",
      "name": "Extract JSON"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        -1312,
        160
      ],
      "id": "6f749f42-f32b-473f-98cf-8d93b75a1f2f",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "value": "32c30768-f350-807c-8712-c0b84b0f4048",
          "mode": "list",
          "cachedResultName": "CV\u2019s",
          "cachedResultUrl": "https://www.notion.so/32c30768f350807c8712c0b84b0f4048"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Full Name|title",
              "title": "={{ $json.full_name }}"
            },
            {
              "key": "Email|rich_text",
              "textContent": "={{ $json.email }}"
            },
            {
              "key": "Phone|phone_number",
              "phoneValue": "={{ $json.phone }}"
            },
            {
              "key": "Match Score|rich_text",
              "textContent": "={{ $json.match_score.toString() }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        -992,
        -240
      ],
      "id": "e0723bf0-f683-487d-822d-05f5dcaac355",
      "name": "Create a database page",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Dane kandydata:\n- Imi\u0119 i nazwisko: {{$json.full_name}}\n- Dopasowanie: {{$json.match_score}}%\n- Kluczowe umiej\u0119tno\u015bci: {{$json.key_skills}}\n- Lata do\u015bwiadczenia: {{$json.years_experience}}\n- Uzasadnienie: {{$json.match_reason}}\n\nNazwa firmy: [Twoja agencja, np. \u201eGG Automations\u201d]\nStanowisko, na kt\u00f3re aplikuje: Specjalista ds. automatyzacji marketingu\n\nWygeneruj draft e\u2011maila zgodnie z powy\u017cszymi wytycznymi. Napisz sam\u0105 wiadomo\u015b\u0107 bez tematu ",
        "options": {
          "systemMessage": "=Jeste\u015b asystentem HR w ma\u0142ej agencji marketingowej. Twoim zadaniem jest napisanie spersonalizowanego e\u2011maila do kandydata na podstawie dostarczonych danych z analizy CV.\n\nOtrzymujesz:\n- Imi\u0119 i nazwisko kandydata\n- Ocen\u0119 dopasowania (0\u2013100%)\n- Kluczowe umiej\u0119tno\u015bci\n- Lata do\u015bwiadczenia\n- Uzasadnienie oceny\n\nTwoja odpowied\u017a powinna by\u0107 w j\u0119zyku polskim, profesjonalna, ale ciep\u0142a. Dopasuj tre\u015b\u0107 do wyniku:\n- Je\u015bli dopasowanie >= 70%: napisz e\u2011mail z zaproszeniem na rozmow\u0119 kwalifikacyjn\u0105. Wspomnij o konkretnych umiej\u0119tno\u015bciach kandydata, kt\u00f3re zrobi\u0142y wra\u017cenie. Zaproponuj termin spotkania (lub popro\u015b o propozycj\u0119 terminu). Podaj kr\u00f3tki opis firmy i stanowiska.\n- Je\u015bli dopasowanie < 70%: napisz uprzejm\u0105 odmow\u0119, podzi\u0119kuj za zainteresowanie, zach\u0119\u0107 do \u015bledzenia przysz\u0142ych ofert. Mo\u017cesz delikatnie zasugerowa\u0107 obszary rozwoju, ale zachowaj pozytywny ton.\n\nStruktura e\u2011maila:\n- Temat: [odpowiedni do decyzji]\n- Zwrot grzeczno\u015bciowy\n- Tre\u015b\u0107 \u2013 3\u20134 zdania, plus ewentualnie pro\u015bba o termin rozmowy\n- Podpis: Zesp\u00f3\u0142 rekrutacyjny [nazwa firmy]\n\nNie u\u017cywaj zmiennych w stylu {{$json.full_name}} \u2013 podstaw dane bezpo\u015brednio."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        -1024,
        -48
      ],
      "id": "6c3a1243-0fe7-414c-a77a-d4a04c65094e",
      "name": "Create draft"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        -464,
        -48
      ],
      "id": "763bcca4-a7d0-433e-84b9-ea58c71a7c9b",
      "name": "Notification"
    },
    {
      "parameters": {
        "resource": "draft",
        "subject": "Zaproszenie na rozmow\u0119 kwalifikacyjn\u0105",
        "message": "={{ $json.output }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        -672,
        -48
      ],
      "id": "514d57d8-e88c-4488-98b1-8bb990cd15c4",
      "name": "Create a draft in Gmail",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "simple": false,
        "filters": {
          "readStatus": "unread"
        },
        "options": {
          "downloadAttachments": true
        }
      },
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1.3,
      "position": [
        -2624,
        -112
      ],
      "id": "e471a84d-3e20-413c-93f9-7051352f97d0",
      "name": "On message received",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "get",
        "messageId": "={{ $json.id }}",
        "simple": false,
        "options": {
          "downloadAttachments": true
        }
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        -2032,
        -112
      ],
      "id": "b9a478bf-3d59-4b80-a204-7f73aaa5f4ba",
      "name": "Get a message",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "pdf",
        "binaryPropertyName": "={{ $('On message received').item.binary.attachment_0 }}",
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1.1,
      "position": [
        -1856,
        -112
      ],
      "id": "bfa1771b-0dd1-4f85-a601-854c4af4e6aa",
      "name": "Extract from File"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "9d650dcd-03e9-42b3-9d00-e8b9fd7425d1",
              "leftValue": "={{ $('On message received').item.binary.attachment_0 }}",
              "rightValue": "",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.3,
      "position": [
        -2432,
        -112
      ],
      "id": "22996390-a92c-4c93-88d7-25d984792c71",
      "name": "Filter"
    },
    {
      "parameters": {
        "operation": "markAsRead",
        "messageId": "={{ $json.id }}"
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        -2240,
        -112
      ],
      "id": "a328b139-63ff-4139-bcd0-7f4a0d8e22d2",
      "name": "Mark a message as read",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Analyze CV": {
      "main": [
        [
          {
            "node": "Extract JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract JSON": {
      "main": [
        [
          {
            "node": "Create draft",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create a database page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Create draft",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Analyze CV",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Create draft": {
      "main": [
        [
          {
            "node": "Create a draft in Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a draft in Gmail": {
      "main": [
        [
          {
            "node": "Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On message received": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a message": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Analyze CV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Mark a message as read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark a message as read": {
      "main": [
        [
          {
            "node": "Get a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "a43ff4b0-a6c3-46a7-9376-5517ebcf6e6a",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "kuJMOtnfKAxoVPnZ",
  "tags": []
}