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動画制作と投稿を自動化
AI動画制作とマルチプラットフォーム公開にはGeminiとCreatomateを活用しましょう
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