HN 직업 업데이트
고급
이것은HR분야의자동화 워크플로우로, 16개의 노드를 포함합니다.주로 Set, Code, Limit, Filter, Airtable 등의 노드를 사용하며. Gemini AI를 사용하여 Hacker News 직업 포스팅 추출 및 구조화하고 Airtable에 저장
사전 요구사항
- •Airtable API Key
- •대상 API의 인증 정보가 필요할 수 있음
- •Google Gemini API Key
사용된 노드 (16)
카테고리
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "ExmRkYWlTAPhA2IQ",
"meta": {
"instanceId": "e19d1d1e8279ed4f1e9dcdd2328b7c5082def05206ccc115a1f38a5872651e05",
"templateCredsSetupCompleted": true
},
"name": "HN Jobs update",
"tags": [],
"nodes": [
{
"id": "2e510877-4fd3-4e46-a1ad-b44187226b78",
"name": "분할",
"type": "n8n-nodes-base.splitOut",
"position": [
340,
400
],
"parameters": {
"options": {},
"fieldToSplitOut": "hits"
},
"typeVersion": 1
},
{
"id": "b5a9c1f3-f167-4646-8f11-97f4be32ff93",
"name": "구조화된 출력 파서",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2780,
600
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"company\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Name of the hiring company\"\n },\n \"title\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Job title/role being advertised\"\n },\n \"location\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Work location including remote/hybrid status\"\n },\n \"type\": {\n \"type\": [\n \"string\",\n null\n ],\n \"enum\": [\n \"FULL_TIME\",\n \"PART_TIME\",\n \"CONTRACT\",\n \"INTERNSHIP\",\n \"FREELANCE\",\n null\n ],\n \"description\": \"Employment type (Full-time, Contract, etc)\"\n },\n \"work_location\": {\n \"type\": [\n \"string\",\n null\n ],\n \"enum\": [\n \"REMOTE\",\n \"HYBRID\",\n \"ON_SITE\",\n null\n ],\n \"description\": \"Work arrangement type\"\n },\n \"salary\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Compensation details if provided\"\n },\n \"description\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Main job description text including requirements and team info\"\n },\n \"apply_url\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Direct application/job posting URL\"\n },\n \"company_url\": {\n \"type\": [\n \"string\",\n null\n ],\n \"description\": \"Company website or careers page\"\n }\n }\n}\n"
},
"typeVersion": 1.2
},
{
"id": "80012214-5045-4c54-a5e1-cf7b76a611c3",
"name": "Who is hiring 게시물 검색",
"type": "n8n-nodes-base.httpRequest",
"position": [
140,
400
],
"parameters": {
"url": "https://uj5wyc0l7x-dsn.algolia.net/1/indexes/Item_dev_sort_date/query",
"method": "POST",
"options": {},
"jsonBody": "{\n \"query\": \"\\\"Ask HN: Who is hiring\\\"\",\n \"analyticsTags\": [\n \"web\"\n ],\n \"page\": 0,\n \"hitsPerPage\": 30,\n \"minWordSizefor1Typo\": 4,\n \"minWordSizefor2Typos\": 8,\n \"advancedSyntax\": true,\n \"ignorePlurals\": false,\n \"clickAnalytics\": true,\n \"minProximity\": 7,\n \"numericFilters\": [],\n \"tagFilters\": [\n [\n \"story\"\n ],\n []\n ],\n \"typoTolerance\": \"min\",\n \"queryType\": \"prefixNone\",\n \"restrictSearchableAttributes\": [\n \"title\",\n \"comment_text\",\n \"url\",\n \"story_text\",\n \"author\"\n ],\n \"getRankingInfo\": true\n}",
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"queryParameters": {
"parameters": [
{
"name": "x-algolia-agent",
"value": "Algolia for JavaScript (4.13.1); Browser (lite)"
},
{
"name": "x-algolia-application-id",
"value": "UJ5WYC0L7X"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Accept-Language",
"value": "en-GB,en-US;q=0.9,en;q=0.8"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "DNT",
"value": "1"
},
{
"name": "Origin",
"value": "https://hn.algolia.com"
},
{
"name": "Referer",
"value": "https://hn.algolia.com/"
},
{
"name": "Sec-Fetch-Dest",
"value": "empty"
},
{
"name": "Sec-Fetch-Mode",
"value": "cors"
},
{
"name": "Sec-Fetch-Site",
"value": "cross-site"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
},
{
"name": "sec-ch-ua",
"value": "\"Chromium\";v=\"133\", \"Not(A:Brand\";v=\"99\""
},
{
"name": "sec-ch-ua-mobile",
"value": "?0"
},
{
"name": "sec-ch-ua-platform",
"value": "\"macOS\""
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "sV79MeBXuKW0vlk4",
"name": "Header Auth account"
}
},
"typeVersion": 4.2
},
{
"id": "58a1f06b-0e41-4f73-9a47-5134806e4249",
"name": "관련 데이터 가져오기",
"type": "n8n-nodes-base.set",
"position": [
640,
400
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "73dd2325-faa7-4650-bd78-5fc97cc202de",
"name": "title",
"type": "string",
"value": "={{ $json.title }}"
},
{
"id": "44918eac-4510-440e-9ac0-bf14d2b2f3af",
"name": "createdAt",
"type": "string",
"value": "={{ $json.created_at }}"
},
{
"id": "00eb6f09-2c22-411c-949c-886b2d95b6eb",
"name": "updatedAt",
"type": "string",
"value": "={{ $json.updated_at }}"
},
{
"id": "2b4f9da6-f60e-46e0-ba9d-3242fa955a55",
"name": "storyId",
"type": "string",
"value": "={{ $json.story_id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d69eb7f3-383f-4e67-a0e7-b5930cfc8b26",
"name": "최신 게시물 가져오기",
"type": "n8n-nodes-base.filter",
"position": [
920,
400
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d7dd7175-2a50-45aa-bd3e-4c248c9193c4",
"operator": {
"type": "dateTime",
"operation": "after"
},
"leftValue": "={{ $json.createdAt }}",
"rightValue": "={{$now.minus({days: 30})}} "
}
]
}
},
"typeVersion": 2.2
},
{
"id": "737cce8c-2ef0-4421-bccf-d9bdfa308385",
"name": "하위 항목(채용 공고) 분리",
"type": "n8n-nodes-base.splitOut",
"position": [
1400,
400
],
"parameters": {
"options": {},
"fieldToSplitOut": "kids"
},
"typeVersion": 1
},
{
"id": "13e36405-f049-4d3d-a17c-f14b42817ba1",
"name": "구조화된 데이터로 변환",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2540,
400
],
"parameters": {
"text": "={{ $json.cleaned_text }}",
"messages": {
"messageValues": [
{
"message": "Extract the JSON data"
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.5
},
{
"id": "40d699ab-bf6d-402b-8192-c485a3525d27",
"name": "텍스트 추출",
"type": "n8n-nodes-base.set",
"position": [
1800,
400
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6affa370-56ce-4ad8-8534-8f753fdf07fc",
"name": "text",
"type": "string",
"value": "={{ $json.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a20afe14-6457-4aa3-9135-75733c704723",
"name": "텍스트 정리",
"type": "n8n-nodes-base.code",
"position": [
2000,
400
],
"parameters": {
"jsCode": "// In a Function node in n8n\nconst inputData = $input.all();\n\nfunction cleanAllPosts(data) {\n return data.map(item => {\n try {\n // Check if item exists and has the expected structure\n if (!item || typeof item !== 'object') {\n return { cleaned_text: '', error: 'Invalid item structure' };\n }\n\n // Get the text, with multiple fallbacks\n let text = '';\n if (typeof item === 'string') {\n text = item;\n } else if (item.json && item.json.text) {\n text = item.json.text;\n } else if (typeof item.json === 'string') {\n text = item.json;\n } else {\n text = JSON.stringify(item);\n }\n\n // Make sure text is a string\n text = String(text);\n \n // Perform the cleaning operations\n try {\n text = text.replace(///g, '/');\n text = text.replace(/'/g, \"'\");\n text = text.replace(/&\\w+;/g, ' ');\n text = text.replace(/<[^>]*>/g, '');\n text = text.replace(/\\|\\s*/g, '| ');\n text = text.replace(/\\s+/g, ' ');\n text = text.replace(/\\s*(https?:\\/\\/[^\\s]+)\\s*/g, '\\n$1\\n');\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n text = text.trim();\n } catch (cleaningError) {\n console.log('Error during text cleaning:', cleaningError);\n // Return original text if cleaning fails\n return { cleaned_text: text, warning: 'Partial cleaning applied' };\n }\n\n return { cleaned_text: text };\n \n } catch (error) {\n console.log('Error processing item:', error);\n return { \n cleaned_text: '', \n error: `Processing error: ${error.message}`,\n original: item\n };\n }\n }).filter(result => result.cleaned_text || result.error); \n}\n\ntry {\n return cleanAllPosts(inputData);\n} catch (error) {\n console.log('Fatal error:', error);\n return [{ \n cleaned_text: '', \n error: `Fatal error: ${error.message}`,\n input: inputData \n }];\n}\n"
},
"typeVersion": 2
},
{
"id": "8ba5a5b4-0d03-46f8-90a1-7550913b77dd",
"name": "테스트용 제한 (선택 사항)",
"type": "n8n-nodes-base.limit",
"position": [
2220,
400
],
"parameters": {
"maxItems": 5
},
"typeVersion": 1
},
{
"id": "d5535a17-79f1-4dc2-941a-ea4dd6a109a8",
"name": "결과를 airtable에 기록",
"type": "n8n-nodes-base.airtable",
"position": [
3200,
400
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "app3Gb4cEMflRuqzy",
"cachedResultUrl": "https://airtable.com/app3Gb4cEMflRuqzy",
"cachedResultName": "HN Who is hiring?"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tbl4JrmWPcxiUuCiX",
"cachedResultUrl": "https://airtable.com/app3Gb4cEMflRuqzy/tbl4JrmWPcxiUuCiX",
"cachedResultName": "Table 1"
},
"columns": {
"value": {
"Type": "={{ $json.output.type }}",
"Title": "={{ $json.output.title }}",
"Salary": "={{ $json.output.salary }}",
"Company": "={{ $json.output.company }}",
"Location": "={{ $json.output.location }}",
"Apply_url": "={{ $json.output.apply_url }}",
"Description": "={{ $json.output.description }}",
"company_url": "={{ $json.output.company_url }}",
"work_location": "={{ $json.output.work_location }}"
},
"schema": [
{
"id": "Title",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Company",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Location",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Location",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "work_location",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "work_location",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Description",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Salary",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Salary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Apply_url",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Apply_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "company_url",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "company_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "create"
},
"credentials": {
"airtableTokenApi": {
"id": "H0gK9cFHnootcYwf",
"name": "Airtable Personal Access Token account"
}
},
"typeVersion": 2.1
},
{
"id": "e51caae1-c8d1-4954-91a5-d0dfde442346",
"name": "HI API: 개별 채용 공고 가져오기",
"type": "n8n-nodes-base.httpRequest",
"position": [
1600,
400
],
"parameters": {
"url": "=https://hacker-news.firebaseio.com/v0/item/{{ $json.kids }}.json?print=pretty",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "880d31e0-41fa-434d-a3d0-ac850ede0b59",
"name": "HN API: 메인 게시물 가져오기",
"type": "n8n-nodes-base.httpRequest",
"position": [
1200,
400
],
"parameters": {
"url": "=https://hacker-news.firebaseio.com/v0/item/{{ $json.storyId }}.json?print=pretty",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "e1bc30b5-b792-4f1e-8d38-ead61178c5fd",
"name": "코드",
"type": "n8n-nodes-base.code",
"position": [
2900,
400
],
"parameters": {
"jsCode": "function convertSalaryRangeToNumber(salaryStr) {\n if (!salaryStr) return null;\n\n // Remove $ and spaces, convert to lowercase\n salaryStr = salaryStr.replace(/\\$/g, '').replace(/\\s/g, '').toLowerCase();\n\n // Replace 'k' with '000'\n salaryStr = salaryStr.replace(/k/g, '000');\n\n // Split by dash, en dash, em dash\n const parts = salaryStr.split(/[-–—]/);\n\n // Extract numbers\n const numbers = parts.map(part => {\n // Remove non-digit/non-dot characters\n const cleaned = part.replace(/[^\\d.]/g, '');\n return cleaned ? parseFloat(cleaned) : NaN;\n }).filter(num => !isNaN(num));\n\n if (numbers.length === 0) return null;\n if (numbers.length === 1) return numbers[0];\n if (numbers.length === 2) return (numbers[0] + numbers[1]) / 2;\n\n // fallback if more than 2 numbers (rare)\n return numbers[0];\n}\n\n// Example usage inside n8n Function node\n// Assume input data is in items, and salary is in item.json.salary\nfor (let item of items) {\n const salaryStr = item.json.salary;\n item.json.salary_numeric = convertSalaryRangeToNumber(salaryStr);\n}\n\nreturn items;\n"
},
"typeVersion": 2
},
{
"id": "294d6c73-8946-4ee7-8d60-11b72ecb3964",
"name": "Google Gemini 채팅 모델",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2600,
620
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash"
},
"credentials": {
"googlePalmApi": {
"id": "PyKkDHOogdm7OBzV",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "6a6c4536-a57a-4e58-a76f-81eef755fa19",
"name": "일정 트리거",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-20,
400
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 2
}
]
}
},
"typeVersion": 1.2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "e5356e09-7a30-467a-a848-507087afb818",
"connections": {
"e1bc30b5-b792-4f1e-8d38-ead61178c5fd": {
"main": [
[
{
"node": "d5535a17-79f1-4dc2-941a-ea4dd6a109a8",
"type": "main",
"index": 0
}
]
]
},
"2e510877-4fd3-4e46-a1ad-b44187226b78": {
"main": [
[
{
"node": "58a1f06b-0e41-4f73-9a47-5134806e4249",
"type": "main",
"index": 0
}
]
]
},
"a20afe14-6457-4aa3-9135-75733c704723": {
"main": [
[
{
"node": "8ba5a5b4-0d03-46f8-90a1-7550913b77dd",
"type": "main",
"index": 0
}
]
]
},
"40d699ab-bf6d-402b-8192-c485a3525d27": {
"main": [
[
{
"node": "a20afe14-6457-4aa3-9135-75733c704723",
"type": "main",
"index": 0
}
]
]
},
"d69eb7f3-383f-4e67-a0e7-b5930cfc8b26": {
"main": [
[
{
"node": "880d31e0-41fa-434d-a3d0-ac850ede0b59",
"type": "main",
"index": 0
}
]
]
},
"6a6c4536-a57a-4e58-a76f-81eef755fa19": {
"main": [
[
{
"node": "80012214-5045-4c54-a5e1-cf7b76a611c3",
"type": "main",
"index": 0
}
]
]
},
"58a1f06b-0e41-4f73-9a47-5134806e4249": {
"main": [
[
{
"node": "d69eb7f3-383f-4e67-a0e7-b5930cfc8b26",
"type": "main",
"index": 0
}
]
]
},
"880d31e0-41fa-434d-a3d0-ac850ede0b59": {
"main": [
[
{
"node": "737cce8c-2ef0-4421-bccf-d9bdfa308385",
"type": "main",
"index": 0
}
]
]
},
"294d6c73-8946-4ee7-8d60-11b72ecb3964": {
"ai_languageModel": [
[
{
"node": "13e36405-f049-4d3d-a17c-f14b42817ba1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"b5a9c1f3-f167-4646-8f11-97f4be32ff93": {
"ai_outputParser": [
[
{
"node": "13e36405-f049-4d3d-a17c-f14b42817ba1",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"737cce8c-2ef0-4421-bccf-d9bdfa308385": {
"main": [
[
{
"node": "e51caae1-c8d1-4954-91a5-d0dfde442346",
"type": "main",
"index": 0
}
]
]
},
"13e36405-f049-4d3d-a17c-f14b42817ba1": {
"main": [
[
{
"node": "e1bc30b5-b792-4f1e-8d38-ead61178c5fd",
"type": "main",
"index": 0
}
]
]
},
"8ba5a5b4-0d03-46f8-90a1-7550913b77dd": {
"main": [
[
{
"node": "13e36405-f049-4d3d-a17c-f14b42817ba1",
"type": "main",
"index": 0
}
]
]
},
"80012214-5045-4c54-a5e1-cf7b76a611c3": {
"main": [
[
{
"node": "2e510877-4fd3-4e46-a1ad-b44187226b78",
"type": "main",
"index": 0
}
]
]
},
"e51caae1-c8d1-4954-91a5-d0dfde442346": {
"main": [
[
{
"node": "40d699ab-bf6d-402b-8192-c485a3525d27",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 인사
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
HN 채용 정보 추출
Hacker News 채용 정보 추출 및 분석
Set
Code
Limit
+
Set
Code
Limit
20 노드Julian Kaiser
인사
시각화 참조 라이브러리에서 n8n 노드를 탐색
可视化 참조 라이브러리에서 n8n 노드를 탐색
If
Ftp
Set
+
If
Ftp
Set
113 노드I versus AI
기타
콘텐츠생성기 v3
AI驱动블로그자동화:사용GPT-4생성并게시SEO기사至WordPress및Twitter
If
Set
Code
+
If
Set
Code
144 노드Jay Emp0
콘텐츠 제작
실시간 - Gemini 및 Creatomate를 사용한 바이럴 AI 동영상 제작 및 게시 자동화
Gemini와 Creatomate를 사용한 AI 비디오 제작 및 다중 플랫폼 게시 자동화
Set
Code
Wait
+
Set
Code
Wait
47 노드Intuz
콘텐츠 제작
WordPress 블로그 자동화 프로페셔널 에디션(심층 연구) v2.1 마켓
GPT-4o, Perplexity AI 및 다국어 지원을 사용한 SEO 최적화 블로그 생성 자동화
If
Set
Xml
+
If
Set
Xml
125 노드Daniel Ng
콘텐츠 제작
콘텐츠 생성기 v4
콘텐츠 팜 v4 - ChatGPT 5와 Gemini를 사용하여 WordPress 블로그 자동화
If
Set
Code
+
If
Set
Code
168 노드Jay Emp0