HH Job Parser
Shared 10/20/2025
1 views
Visual Workflow
JSON Code
{
"id": "bZExXXjMZbhWbtiy",
"meta": {
"instanceId": "a7951da00dc167f722a4bd0bc0e175503754ae4ae331d85018109ce22f7c48f6",
"templateCredsSetupCompleted": true
},
"name": "OClick/1.0",
"tags": [],
"nodes": [
{
"id": "70ce1f80-03b5-434c-99ed-cd8e31f35c94",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-256,
168
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "fbc4f82c-1b40-46d6-ad2b-7ad27f0c11dd",
"name": "Auto-search",
"type": "n8n-nodes-base.httpRequest",
"position": [
-32,
168
],
"parameters": {
"url": "https://api.hh.ru/saved_searches/vacancies",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"queryParameters": {
"parameters": [
{
"name": "page",
"value": "0"
},
{
"name": "per_page",
"value": "10"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "4d2e08b7-ab89-4815-a3f9-fedb91035d3f",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
192,
168
],
"parameters": {
"options": {},
"fieldToSplitOut": "items"
},
"typeVersion": 1
},
{
"id": "cb9603b9-6cd6-421a-b855-2431c9c1c33b",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
416,
168
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "96d0a2cc-b2ed-4a93-941b-2278aa255c79",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.new_items.count }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "86febd0c-cbaf-4720-865f-3163ccecd70b",
"name": "Split Out1",
"type": "n8n-nodes-base.splitOut",
"position": [
865,
168
],
"parameters": {
"options": {},
"fieldToSplitOut": "items"
},
"typeVersion": 1
},
{
"id": "3ca0be82-3e29-4956-9b17-54d89548b283",
"name": "Remove Duplicates",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
1089,
168
],
"parameters": {
"compare": "selectedFields",
"options": {},
"fieldsToCompare": "id"
},
"typeVersion": 2
},
{
"id": "162e429d-2a5d-4b9b-a4a6-35d955bb8576",
"name": "Vacancy Response",
"type": "n8n-nodes-base.httpRequest",
"position": [
192,
672
],
"parameters": {
"url": "https://api.hh.ru/negotiations",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "message"
},
{
"name": "resume_id",
"value": "054142d0ff0f5da2090039ed1f47344b585273"
},
{
"name": "vacancy_id"
}
]
},
"genericAuthType": "oAuth2Api",
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "abb1d406-feaa-47fb-9cd7-273a1556d4af",
"name": "Vacancy Details",
"type": "n8n-nodes-base.httpRequest",
"position": [
640,
168
],
"parameters": {
"url": "={{ $json.items.url }}",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "dc7e737f-1120-4105-a201-f8cd37cebef6",
"name": "Response Don't Exists",
"type": "n8n-nodes-base.if",
"position": [
-32,
672
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a97521dd-f952-4b74-b1b3-26b03878482a",
"operator": {
"type": "array",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.items }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e5c7a975-7447-4faa-8ea8-11c50613112e",
"name": "Vacancy Reponses List",
"type": "n8n-nodes-base.httpRequest",
"position": [
-256,
672
],
"parameters": {
"url": "https://api.hh.ru/negotiations",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"queryParameters": {
"parameters": [
{
"name": "page",
"value": "0"
},
{
"name": "per_page",
"value": "10"
},
{
"name": "order_by",
"value": "updated_at"
},
{
"name": "order",
"value": "desc"
},
{
"name": "vacancy_id",
"value": "126529083"
},
{
"name": "status",
"value": "all"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "90d5f3e3-504c-418d-b7dd-82ca5acb5965",
"name": "Chunking",
"type": "n8n-nodes-base.code",
"position": [
2458,
264
],
"parameters": {
"jsCode": "const items = $input.all();\nconst out = [];\n\nfor (const item of items) {\n const doc = item.json.data ?? item.json;\n if (!doc) continue;\n\n // гарантируем, что sections — массив (в твоём случае они всегда есть)\n const sections = Array.isArray(doc.sections) ? doc.sections : [];\n\n let secIndex = 0;\n for (const sec of sections) {\n // безопасные дефолты\n const sectionName = sec && sec.section ? String(sec.section) : `section_${secIndex}`;\n const sectionText = sec && sec.text ? String(sec.text).trim() : '';\n\n // Unicode-safe slug (короткий, для id)\n const rawSlug = sectionName.toLowerCase().replace(/\\s+/g, '_');\n const sectionSlug = rawSlug.replace(/[^\\p{L}\\p{N}_-]/gu, '').slice(0, 50) || `sec${secIndex}`;\n\n // уникальный id чанка\n const chunkId = `${doc.id ?? 'doc'}_${secIndex}_${sectionSlug}`;\n\n // content: заголовок секции + текст\n //const content = `### ${sectionName}\\n\\n${sectionText}`;\n const content = `${sectionText}`;\n\n // сохраняем в metadata только поля, которые соответствуют исходной схеме документа\n const metadata = {\n // id чанка (уникален)\n id: chunkId,\n // оригинальный документный id\n document_id: doc.id ?? null,\n // основной набор полей из оригинального документа (копируем как есть)\n title: doc.title ?? null,\n salary_range: doc.salary_range ?? null,\n location: doc.location ?? null,\n // experience — копируем целиком (объект {id, name} или null)\n experience: doc.experience ?? null,\n // ключевые навыки — сохраняем оригинал (массив объектов или пустой массив)\n key_skills: doc.key_skills ?? [],\n source_url: doc.source_url ?? null,\n employment_type: doc.employment_type ?? null,\n work_format: doc.work_format ?? null,\n company: doc.company ?? null,\n // информация о секции для удобства поиска/фильтрации\n section: sectionName\n };\n\n out.push({ json: { content, metadata } });\n secIndex++;\n }\n\n // если sections пустой — сейчас мы не создаём чанков (поведение по умолчанию)\n}\n\nreturn out;\n"
},
"executeOnce": false,
"typeVersion": 2
},
{
"id": "96107c13-1e42-4765-8db3-8a317a2099c8",
"name": "qwen3-embedding",
"type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
"position": [
2669,
468.5
],
"parameters": {
"model": "qwen3-embedding:8b"
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "cf086d55-3263-414f-8127-5755fbca4bb8",
"name": "qwen3:4b:it:q8",
"type": "@n8n/n8n-nodes-langchain.lmOllama",
"position": [
1987,
99
],
"parameters": {
"model": "qwen3:4b-instruct-2507-q8_0",
"options": {
"topK": 1,
"topP": 1,
"numCtx": 8192,
"lowVram": false,
"mainGpu": 0,
"useMMap": true,
"numBatch": 128,
"useMLock": true,
"numThread": 14,
"vocabOnly": false,
"temperature": 0,
"repeatPenalty": 1,
"penalizeNewline": false,
"presencePenalty": 0,
"frequencyPenalty": 0
}
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "b5ddbd7a-7ad2-4dae-80a1-c5858a82873e",
"name": "Token Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
"position": [
2856,
665.5
],
"parameters": {
"chunkSize": 500,
"chunkOverlap": 100
},
"typeVersion": 1
},
{
"id": "a35d520f-55ce-4bf8-b103-cf9275600c8f",
"name": "Save To Qdrant",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"position": [
2699.5,
257.5
],
"parameters": {
"mode": "insert",
"options": {},
"qdrantCollection": {
"__rl": true,
"mode": "id",
"value": "vacancies"
}
},
"credentials": {
"qdrantApi": {
"id": "sFfERYppMeBnFNeA",
"name": "Local QdrantApi database"
}
},
"typeVersion": 1.3
},
{
"id": "b3350ecd-22f7-4d3d-98e7-8746480c288d",
"name": "Set Payload",
"type": "n8n-nodes-qdrant.qdrant",
"onError": "continueErrorOutput",
"position": [
3123,
264
],
"parameters": {
"filter": "={\n \"must\": [\n {\n \"key\": \"metadata.id\",\n \"match\": {\n \"value\": \"{{ $json.metadata.id }}\"\n }\n }\n ]\n}",
"points": "=",
"payload": "={\n \"id\": \"{{ $json.metadata.id }}\",\n \"title\": \"{{ $('Chunking').item.json.metadata.title }}\",\n \"experience\": \"{{ $('Chunking').item.json.metadata.experience.id }}\",\n \"key_skills\": {{ JSON.stringify($('Chunking').item.json.metadata.key_skills) }},\n \"section\": \"{{ $('Chunking').item.json.metadata.section }}\"\n}",
"resource": "payload",
"operation": "setPayload",
"collectionName": {
"__rl": true,
"mode": "name",
"value": "vacancies"
},
"requestOptions": {
"timeout": 10000,
"allowUnauthorizedCerts": true
}
},
"credentials": {
"qdrantRestApi": {
"id": "5UV8rQE53hqsh82x",
"name": "Qdrant account"
}
},
"retryOnFail": false,
"typeVersion": 1
},
{
"id": "1f37befa-0a0e-483d-84dc-92f97a4cbfec",
"name": "Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
1924,
-112
],
"parameters": {
"text": "={{ $json.sections }}",
"options": {},
"attributes": {
"attributes": [
{
"name": "responsibilities",
"description": "обязанности / что нужно делать;"
},
{
"name": "requirements",
"required": true,
"description": "обязательные требования / необходимый опыт;"
},
{
"name": "additional",
"description": "only optional / desirable skills or experience (explicitly indicated as \"Would be a plus\", \"Welcome if\", \"Desirable\", \"preferred\", \"will be a plus\").\\n IMPORTANT RULES (must follow exactly):\\n1) Use heading-based extraction first: if input contains \"Welcome if\", \"Would be a plus\", \"Desirable\" or similar, extract the text under that heading into \"advantages\".\\n2) If there are lines/sentences containing the optional indicators (see list below), include them in \"advantages\".\\n3) **Do NOT** include in \"advantages\" any marketing/benefits/conditions text such as \"What we offer\", \"Dream job\", \"official employment\", \"paid vacation\", \"remotely\", \"schedule\", \"team\", \"adaptation\" — these are company perks, not desirable experience, and must be excluded from advantages.\\n4) If a sentence matches both optional-indicator and benefit keywords, prefer treating it as BENEFIT and therefore do NOT place it into \"advantages\" unless it clearly expresses desirable SKILL/EXPERIENCE.\\n5) If no relevant optional/desirable items are found, OMIT the \"advantages\" section entirely (do not include it with empty text).\\n6) Preserve original wording and line breaks. Do NOT summarize or paraphrase."
}
]
}
},
"executeOnce": false,
"retryOnFail": true,
"typeVersion": 1.2
},
{
"id": "e4afd87f-bf00-4e54-8913-765027f94a31",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1713,
174.5
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "c19605f4-5f2e-4748-b4c2-f248627699b3",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
1980,
264
],
"parameters": {
"mode": "combine",
"options": {
"clashHandling": {
"values": {
"resolveClash": "preferInput1"
}
}
},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "af2cc2b7-aaad-42b3-af84-81e2aeeb8a1a",
"name": "ObjToStrArr",
"type": "n8n-nodes-base.code",
"position": [
2247,
264
],
"parameters": {
"jsCode": "const items = $input.all();\n\nreturn items.map(item => {\n if (Array.isArray(item.json.key_skills)) {\n item.json.key_skills = item.json.key_skills.map(skill => skill.name);\n }\n return item;\n});"
},
"typeVersion": 2
},
{
"id": "c77a967d-05bf-4c4f-a88f-5e0bf4e23d11",
"name": "Sections cleanup",
"type": "n8n-nodes-base.code",
"position": [
2247,
-13.5
],
"parameters": {
"jsCode": "const input = $input.first().json.output;\nconst sections = Object.keys(input)\n .map(key => ({\n section: key,\n text: input[key].replace(/\\n/g, ' ')\n }))\n .filter(section => section.text.trim() !== '');\nreturn [{ json: { sections } }];"
},
"typeVersion": 2
},
{
"id": "09bf7483-d866-45cf-8ff5-a51a2ecede2a",
"name": "Load Content/Metadata",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
2786,
468.5
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "=source_url",
"value": "={{ $json.metadata.source_url }}"
},
{
"name": "=company",
"value": "={{ $json.metadata.company }}"
},
{
"name": "=location",
"value": "={{ $json.metadata.location }}"
},
{
"name": "employment_type",
"value": "={{ $('Chunking').item.json.metadata.employment_type }}"
},
{
"name": "work_format",
"value": "={{ $('Chunking').item.json.metadata.work_format }}"
},
{
"name": "salary_range",
"value": "={{ $('Chunking').item.json.metadata.salary_range }}"
},
{
"name": "id",
"value": "={{ $('Chunking').item.json.metadata.id }}"
},
{
"name": "key_skills",
"value": "={{ $json.metadata.key_skills }}"
},
{
"name": "experience_id",
"value": "={{ $json.metadata.experience.id }}"
},
{
"name": "section",
"value": "={{ $json.metadata.section }}"
},
{
"name": "title",
"value": "={{ $json.metadata.title }}"
}
]
}
},
"jsonData": "={{ $('Chunking').item.json.content }}",
"jsonMode": "expressionData",
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "43490c76-a93b-40d2-92d2-a34e912e3c05",
"name": "Payload Extraction",
"type": "n8n-nodes-base.set",
"position": [
1537,
192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cbca6f2d-469e-4be9-a42f-02e4403eb2f8",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "8dc8b87c-bfb7-4655-abd7-c54e5d30a4d4",
"name": "title",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "91281710-76ee-4531-bf5c-ca6e4c5707be",
"name": "salary_range",
"type": "object",
"value": "={{ $json.salary_range }}"
},
{
"id": "f1953bd7-2ba2-4fb7-b9a8-cf226bf58b25",
"name": "location",
"type": "string",
"value": "={{ $json.address.city }}"
},
{
"id": "c197a189-80ba-4834-8c3a-40e33dfa0759",
"name": "experience",
"type": "object",
"value": "={{ $json.experience }}"
},
{
"id": "d2a8f427-565e-49e2-a606-3c5a6cac1836",
"name": "sections",
"type": "string",
"value": "={{ $json.description }}"
},
{
"id": "ba314b21-e78c-425e-b975-10bb2432ef3d",
"name": "key_skills",
"type": "array",
"value": "={{ $json.key_skills }}"
},
{
"id": "6b91dc6d-84cf-4ec8-b9f5-decc788efd3f",
"name": "source_url",
"type": "string",
"value": "={{ $json.alternate_url }}"
},
{
"id": "0a9e300a-f2ea-4ada-be3d-ef971441e80f",
"name": "employment_type",
"type": "object",
"value": "={{ $json.employment_form }}"
},
{
"id": "8bbaf1fc-9da7-4fc7-84ca-850a8e1905ea",
"name": "work_format",
"type": "array",
"value": "={{ $json.work_format }}"
},
{
"id": "5b72d543-b957-4dfb-aaa1-f55b1a685248",
"name": "company",
"type": "string",
"value": "={{ $json.employer.name }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "1dd77057-c683-4524-8545-2cc7d7749083",
"name": "Get Vacancy Details",
"type": "n8n-nodes-base.httpRequest",
"position": [
1313,
168
],
"parameters": {
"url": "=https://api.hh.ru/vacancies/{{ $json.id }}",
"options": {
"batching": {
"batch": {
"batchSize": 10
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"typeVersion": 4.2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "5f7b94af-e233-49f5-bd83-b08cf0029758",
"connections": {
"If": {
"main": [
[],
[
{
"node": "Vacancy Details",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "ObjToStrArr",
"type": "main",
"index": 0
}
]
]
},
"Chunking": {
"main": [
[
{
"node": "Save To Qdrant",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Split Out1": {
"main": [
[
{
"node": "Remove Duplicates",
"type": "main",
"index": 0
}
]
]
},
"Auto-search": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"ObjToStrArr": {
"main": [
[
{
"node": "Chunking",
"type": "main",
"index": 0
}
]
]
},
"Save To Qdrant": {
"main": [
[
{
"node": "Set Payload",
"type": "main",
"index": 0
}
]
]
},
"Token Splitter": {
"ai_textSplitter": [
[
{
"node": "Load Content/Metadata",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"qwen3:4b:it:q8": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
],
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Vacancy Details": {
"main": [
[
{
"node": "Split Out1",
"type": "main",
"index": 0
}
]
]
},
"qwen3-embedding": {
"ai_embedding": [
[
{
"node": "Save To Qdrant",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Auto-search",
"type": "main",
"index": 0
}
]
]
},
"Sections cleanup": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Remove Duplicates": {
"main": [
[
{
"node": "Get Vacancy Details",
"type": "main",
"index": 0
}
]
]
},
"Payload Extraction": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Get Vacancy Details": {
"main": [
[
{
"node": "Payload Extraction",
"type": "main",
"index": 0
}
]
]
},
"Information Extractor": {
"main": [
[
{
"node": "Sections cleanup",
"type": "main",
"index": 0
}
]
]
},
"Load Content/Metadata": {
"ai_document": [
[
{
"node": "Save To Qdrant",
"type": "ai_document",
"index": 0
}
]
]
},
"Response Don't Exists": {
"main": [
[
{
"node": "Vacancy Response",
"type": "main",
"index": 0
}
]
]
},
"Vacancy Reponses List": {
"main": [
[
{
"node": "Response Don't Exists",
"type": "main",
"index": 0
}
]
]
}
}
}