Extract data from resume and create PDF with Gotenberg
Workflow JSON
{"nodes": [{"id": "79849bb5-00a4-42e6-92c4-b06c7a20eb3e", "name": "OpenAI Chat Model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [1580, 340], "parameters": {"model": "gpt-4-turbo-preview", "options": {"temperature": 0, "responseFormat": "json_object"}}, "credentials": {"openAiApi": {"id": "", "name": "[Your openAiApi]"}}, "typeVersion": 1}, {"id": "85df0106-1f78-4412-8751-b84d417c8bf9", "name": "Convert education to HTML", "type": "n8n-nodes-base.code", "position": [2420, 180], "parameters": {"mode": "runOnceForEachItem", "jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((education, index) => {\n if (index > 0) {\n html += '<br /><br />'; // Add a new line if it's not the first item\n }\n html += `<b>Institution:</b> ${education.institution}<br />\n<b>Start year:</b> ${education.start_year}<br />\n<b>Degree:</b> ${education.degree}`;\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.education;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};"}, "typeVersion": 2}, {"id": "da4fc45d-712f-4171-b72a-66b74b4d8e05", "name": "Auto-fixing Output Parser", "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", "position": [1820, 340], "parameters": {}, "typeVersion": 1}, {"id": "225a7513-6fd4-4672-9b40-b10b00f121a7", "name": "OpenAI Chat Model1", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [1740, 520], "parameters": {"options": {"temperature": 0}}, "credentials": {"openAiApi": {"id": "", "name": "[Your openAiApi]"}}, "typeVersion": 1}, {"id": "0606c99d-a080-4277-b071-1bc0c93bb2e3", "name": "Structured Output Parser", "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "position": [1960, 520], "parameters": {"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"personal_info\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"address\": { \"type\": \"string\" },\n \"email\": { \"type\": \"string\", \"format\": \"email\" },\n \"github\": { \"type\": \"string\"},\n \"linkedin\": { \"type\": \"string\" }\n }\n },\n \"employment_history\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"position\": { \"type\": \"string\" },\n \"company\": { \"type\": \"string\" },\n \"duration\": { \"type\": \"string\" },\n \"responsibilities\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n },\n \"education\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"institution\": { \"type\": \"string\" },\n \"start_year\": { \"type\": \"integer\" },\n \"degree\": { \"type\": \"string\" }\n }\n }\n },\n \"projects\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"year\": { \"type\": \"integer\" },\n \"description\": { \"type\": \"string\" },\n \"technologies\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n },\n \"volunteering\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"activity\": { \"type\": \"string\" },\n \"location\": { \"type\": \"string\" },\n \"date\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" }\n }\n }\n },\n \"programming_languages\": {\n \"type\": \"object\",\n \"properties\": {\n \"languages\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"tools\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"methodologies\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n },\n \"foreign_languages\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"language\": { \"type\": \"string\" },\n \"level\": { \"type\": \"string\" }\n }\n }\n }\n }\n}\n"}, "typeVersion": 1}, {"id": "027975cd-768a-4048-858d-9060f48ab622", "name": "Convert employment history to HTML", "type": "n8n-nodes-base.code", "position": [2420, -20], "parameters": {"mode": "runOnceForEachItem", "jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((item, index) => {\n if (index > 0) {\n html += '<br />'; // Add a new line if it's not the first item\n }\n html += `<b>Position:</b> ${item.position}\n<b>Company:</b> ${item.company}\n<br />\n<b>Duration:</b> ${item.duration}\n<br />\n<b>Responsibilities:</b>\n`;\n\n item.responsibilities.forEach((responsibility, i) => {\n html += `- ${responsibility}`;\n if (i < item.responsibilities.length - 1 || index < list.length - 1) {\n html += '<br />'; // Add new line if it's not the last responsibility in the last item\n }\n });\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.employment_history;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};"}, "typeVersion": 2}, {"id": "823a241d-1c68-40a9-8f2c-f1bdfaab7603", "name": "Convert projects to HTML", "type": "n8n-nodes-base.code", "position": [2420, 380], "parameters": {"mode": "runOnceForEachItem", "jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((project, index) => {\n if (index > 0) {\n html += '<br />'; // Add a new line if it's not the first project\n }\n html += `<b>Name:</b> ${project.name}<br />\n<b>Year:</b> ${project.year}<br />\n<b>Description:</b> ${project.description}<br /><br />\n<b>Technologies:</b>\n<br />`;\n\n project.technologies.forEach((technology, i) => {\n html += `- ${technology}`;\n if (i < project.technologies.length - 1 || index < list.length - 1) {\n html += '<br />'; // Add new line if it's not the last technology in the last project\n }\n });\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.projects;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};\n"}, "typeVersion": 2}, {"id": "a12eb0e1-1cb9-4b83-a1ec-42dd8214f6bc", "name": "Convert volunteering to HTML", "type": "n8n-nodes-base.code", "position": [2420, 580], "parameters": {"mode": "runOnceForEachItem", "jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((event, index) => {\n if (index > 0) {\n html += '<br />'; // Add a new line if it's not the first volunteering event\n }\n html += `<b>Activity:</b> ${event.activity}<br />\n<b>Location:</b> ${event.location}<br />\n<b>Date:</b> ${event.date}<br />\n<b>Description:</b> ${event.description}<br />`;\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.volunteering;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};\n"}, "typeVersion": 2}, {"id": "70b67b80-d22d-4eea-8c97-3d2cb2b9bbfc", "name": "Telegram trigger", "type": "n8n-nodes-base.telegramTrigger", "position": [360, 340], "webhookId": "d6829a55-a01b-44ac-bad3-2349324c8515", "parameters": {"updates": ["message"], "additionalFields": {}}, "credentials": {"telegramApi": {"id": "", "name": "[Your telegramApi]"}}, "typeVersion": 1.1}, {"id": "21bead1d-0665-44d5-b623-b0403c9abd6c", "name": "Auth", "type": "n8n-nodes-base.if", "position": [600, 340], "parameters": {"options": {}, "conditions": {"options": {"leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "7ca4b4c3-e23b-4896-a823-efc85c419467", "operator": {"type": "number", "operation": "equals"}, "leftValue": "={{ $json.message.chat.id }}", "rightValue": 0}]}}, "typeVersion": 2}, {"id": "de76d6ec-3b0e-44e0-943d-55547aac2e46", "name": "No operation (unauthorized)", "type": "n8n-nodes-base.noOp", "position": [860, 520], "parameters": {}, "typeVersion": 1}, {"id": "439f5e2c-be7d-486b-a1f1-13b09f77c2c8", "name": "Check if start message", "type": "n8n-nodes-base.if", "position": [860, 220], "parameters": {"options": {}, "conditions": {"options": {"leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "1031f14f-9793-488d-bb6b-a021f943a399", "operator": {"type": "string", "operation": "notEquals"}, "leftValue": "={{ $json.message.text }}", "rightValue": "/start"}]}}, "typeVersion": 2}, {"id": "af5f5622-c338-40c0-af72-90e124ed7ce1", "name": "No operation (start message)", "type": "n8n-nodes-base.noOp", "position": [1120, 360], "parameters": {}, "typeVersion": 1}, {"id": "2efae11a-376b-44aa-ab91-9b3dea82ede0", "name": "Get file", "type": "n8n-nodes-base.telegram", "position": [1120, 120], "parameters": {"fileId": "={{ $json.message.document.file_id }}", "resource": "file"}, "credentials": {"telegramApi": {"id": "", "name": "[Your telegramApi]"}}, "typeVersion": 1.1}, {"id": "88fd1002-ad2c-445f-92d4-11b571db3788", "name": "Extract text from PDF", "type": "n8n-nodes-base.extractFromFile", "position": [1380, 120], "parameters": {"options": {}, "operation": "pdf"}, "typeVersion": 1}, {"id": "9dfc204b-c567-418a-93a3-9b72cf534a8c", "name": "Set parsed fileds", "type": "n8n-nodes-base.set", "position": [2040, 120], "parameters": {"options": {}}, "typeVersion": 3.2}, {"id": "314c771a-5ff2-484f-823b-0eab88f43ea3", "name": "Personal info", "type": "n8n-nodes-base.set", "position": [2420, -380], "parameters": {"fields": {"values": [{"name": "personal_info", "stringValue": "=<b><u>Personal info</u></b>\n<br /><br />\n<b>Name:</b> {{ $json.personal_info.name }}\n<br />\n<b>Address:</b> {{ $json.personal_info.address }}\n<br />\n<b>Email:</b> {{ $json.personal_info.email }}\n<br />\n<b>GitHub:</b> {{ $json.personal_info.github }}\n<br />"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "be6b32e8-6000-4235-a723-0e22828ead45", "name": "Technologies", "type": "n8n-nodes-base.set", "position": [2420, -200], "parameters": {"fields": {"values": [{"name": "technologies", "stringValue": "=<b><u>Technologies</u></b>\n<br /><br />\n<b>Programming languages:</b> {{ $json.programming_languages.languages.join(', ') }}\n<br />\n<b>Tools:</b> {{ $json.programming_languages.tools.join(', ') }}\n<br />\n<b>Methodologies:</b> {{ $json.programming_languages.methodologies.join(', ') }}\n<br />"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "ab726d61-84b8-4af7-a195-33e1add89153", "name": "Employment history", "type": "n8n-nodes-base.set", "position": [2640, -20], "parameters": {"fields": {"values": [{"name": "employment_history", "stringValue": "=<b><u>Employment history</u></b>\n<br /><br />\n{{ $json[\"htmlOutput\"] }}"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "692f9555-6102-4d3c-b0a1-868e27e3c343", "name": "Education", "type": "n8n-nodes-base.set", "position": [2640, 180], "parameters": {"fields": {"values": [{"name": "education", "stringValue": "=<b><u>Education</u></b>\n<br /><br />\n{{ $json[\"htmlOutput\"] }}"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "258728f2-1f03-4786-8197-feb9f1bc4dfe", "name": "Projects", "type": "n8n-nodes-base.set", "position": [2640, 380], "parameters": {"fields": {"values": [{"name": "projects", "stringValue": "=<b><u>Projects</u></b>\n<br /><br />\n{{ $json[\"htmlOutput\"] }}"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "3c819ce4-235a-4b12-a396-d33dca9f80da", "name": "Volunteering", "type": "n8n-nodes-base.set", "position": [2640, 580], "parameters": {"fields": {"values": [{"name": "volunteering", "stringValue": "=<b><u>Volunteering</u></b>\n<br /><br />\n{{ $json[\"htmlOutput\"] }}"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "41bd7506-7330-4c25-8b43-aa3c836736fc", "name": "Merge education and employment history", "type": "n8n-nodes-base.merge", "position": [2880, 100], "parameters": {"mode": "combine", "options": {}, "combinationMode": "multiplex"}, "typeVersion": 2.1}, {"id": "d788da36-360b-4009-82ad-2f206fad8e53", "name": "Merge projects and volunteering", "type": "n8n-nodes-base.merge", "position": [2880, 500], "parameters": {"mode": "combine", "options": {}, "combinationMode": "multiplex"}, "typeVersion": 2.1}, {"id": "57c20e19-3d84-41c0-a415-1d55cb031da1", "name": "Merge personal info and technologies", "type": "n8n-nodes-base.merge", "position": [3140, -160], "parameters": {"mode": "combine", "options": {}, "combinationMode": "multiplex"}, "typeVersion": 2.1}, {"id": "f12be010-8375-4ff7-ba8e-9c2c870f648b", "name": "Merge all", "type": "n8n-nodes-base.merge", "position": [3400, 200], "parameters": {"mode": "combine", "options": {}, "combinationMode": "multiplex"}, "typeVersion": 2.1}, {"id": "d6428167-2c75-42a5-a905-7590ff1d6a25", "name": "Set final data", "type": "n8n-nodes-base.set", "position": [3620, 200], "parameters": {"fields": {"values": [{"name": "output", "stringValue": "={{ $json.personal_info }}\n<br /><br />\n{{ $json.employment_history }}\n<br /><br />\n{{ $json.education }}\n<br /><br />\n{{ $json.projects }}\n<br /><br />\n{{ $json.volunteering }}\n<br /><br />\n{{ $json.technologies }}"}]}, "include": "none", "options": {}}, "typeVersion": 3.2}, {"id": "9ea13c62-2e09-4b37-b889-66edaef1fcf1", "name": "Convert raw to base64", "type": "n8n-nodes-base.code", "position": [3840, 200], "parameters": {"mode": "runOnceForEachItem", "jsCode": "const encoded = Buffer.from($json.output).toString('base64');\n\nreturn { encoded };"}, "typeVersion": 2}, {"id": "c4474fa1-b1b5-432f-b30e-100201c9ec7c", "name": "Convert to HTML", "type": "n8n-nodes-base.convertToFile", "position": [4060, 200], "parameters": {"options": {"fileName": "index.html", "mimeType": "text/html"}, "operation": "toBinary", "sourceProperty": "encoded"}, "typeVersion": 1.1}, {"id": "3c4d2010-1bdc-4f01-bb1a-bd0128017787", "name": "Generate plain PDF doc", "type": "n8n-nodes-base.httpRequest", "position": [4340, 200], "parameters": {"url": "http://gotenberg:3000/forms/chromium/convert/html", "method": "POST", "options": {"response": {"response": {"responseFormat": "file"}}}, "sendBody": true, "contentType": "multipart-form-data", "bodyParameters": {"parameters": [{"name": "files", "parameterType": "formBinaryData", "inputDataFieldName": "data"}]}}, "typeVersion": 4.1}, {"id": "2b3cd55f-21a3-4c14-905f-82b158aa3fd0", "name": "Send PDF to the user", "type": "n8n-nodes-base.telegram", "position": [4640, 200], "parameters": {"chatId": "={{ $('Telegram trigger').item.json[\"message\"][\"chat\"][\"id\"] }}", "operation": "sendDocument", "binaryData": true, "additionalFields": {"fileName": "={{ $('Set parsed fileds').item.json[\"personal_info\"][\"name\"].toLowerCase().replace(' ', '-') }}.pdf"}}, "credentials": {"telegramApi": {"id": "", "name": "[Your telegramApi]"}}, "typeVersion": 1.1}, {"id": "54fe1d2d-eb9d-4fe1-883f-1826e27ac873", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [540, 180], "parameters": {"width": 226.21234567901217, "height": 312.917333333334, "content": "### Add chat ID\nRemember to set your actual ID to trigger automation from Telegram."}, "typeVersion": 1}, {"id": "b193a904-260b-4d45-8a66-e3cb46fc7ce4", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [800, 83.43940740740783], "parameters": {"width": 229.64938271604922, "height": 293.54824691358016, "content": "### Ignore start message\nWorkflow ignores initial`/start` message sent to the bot."}, "typeVersion": 1}, {"id": "d5c95d8f-b699-4a8e-9460-a4f5856b5e6f", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [1066, -20], "parameters": {"width": 211.00246913580224, "height": 302.41975308642, "content": "### Download resume file\nBased on file ID, node performs downloading of the file uploaded by user."}, "typeVersion": 1}, {"id": "2de0751d-8e11-457e-8c38-a6dcca59190c", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [1320, -20], "parameters": {"width": 217.87654320987633, "height": 302.41975308642, "content": "### Extract text from PDF\nNode extracts readable text form PDF."}, "typeVersion": 1}, {"id": "4b9ccab8-ff6c-408f-93fe-f148034860a0", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [1580, -20], "parameters": {"width": 410.9479506172837, "height": 302.41975308642, "content": "### Parse resume data\nCreate structured data from text extracted from resume. Chain uses OpenAI `gpt-4-turbo-preview` model and JSON response mode. **Adjust JSON schema in output parser to your needs.**"}, "typeVersion": 1}, {"id": "bfb1d382-90fa-4bff-8c38-04e53bcf5f58", "name": "Parse resume data", "type": "@n8n/n8n-nodes-langchain.chainLlm", "position": [1660, 120], "parameters": {"prompt": "={{ $json.text }}", "messages": {"messageValues": [{"message": "Your task is to extract all necessary data such as first name, last name, experience, known technologies etc. from the provided resume text and return in well-unified JSON format. Do not make things up."}]}}, "typeVersion": 1.3}, {"id": "7e8eb10a-f21c-4a9c-90b1-b71537b78356", "name": "Merge other data", "type": "n8n-nodes-base.merge", "position": [3140, 340], "parameters": {"mode": "combine", "options": {}, "combinationMode": "multiplex"}, "typeVersion": 2.1}, {"id": "7c4398de-7b4d-4095-b38f-eaf099d2991b", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [2340, -491.4074074074074], "parameters": {"width": 1196.8442469135782, "height": 1260.345679012346, "content": "### Format HTML\nFormat HTML for each resume section (employment history, projects etc.)."}, "typeVersion": 1}, {"id": "9de2f504-6ff0-4b00-8e0d-436c789b4e23", "name": "Sticky Note7", "type": "n8n-nodes-base.stickyNote", "position": [3580, 40], "parameters": {"width": 638.6516543209876, "height": 322.5837037037037, "content": "### Create HTML file\nFrom formatted output create `index.html` file in order to run PDF conversion."}, "typeVersion": 1}, {"id": "11abdff5-377e-490d-9136-15c24ff6a05e", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [4260, 39.83604938271645], "parameters": {"color": 3, "width": 262.0096790123454, "height": 322.5837037037035, "content": "### Convert file to PDF\nForm `index.html` create PDF using [Gotenberg](https://gotenberg.dev/). If you're not familiar with this software, feel free to check out [my tutorial on YouTube](https://youtu.be/bo15xdjXf1Y?si=hFZMTfjzfSOLOLPK)."}, "typeVersion": 1}, {"id": "73fb81d0-5218-4311-aaec-7fa259d8cbd3", "name": "Sticky Note9", "type": "n8n-nodes-base.stickyNote", "position": [4560, 40], "parameters": {"width": 262.0096790123454, "height": 322.5837037037035, "content": "### Send PDF file to user\nDeliver converted PDF to Telegram user (based on chat ID)."}, "typeVersion": 1}, {"id": "bb5fa375-4cc9-4559-a014-7b618d6c5f32", "name": "Sticky Note10", "type": "n8n-nodes-base.stickyNote", "position": [-280, 128], "parameters": {"width": 432.69769500990674, "height": 364.2150828344463, "content": "## \u26a0\ufe0f Note\n\nThis is *resume extractor* workflow that I had a pleasure to present during [n8n community hangout](https://youtu.be/eZacuxrhCuo?si=KkJQrgQuvLxj-6FM&t=1701\n) on March 7, 2024.\n\n1. Remember to add your credentials and configure nodes.\n2. This node requires installed [Gotenberg](https://gotenberg.dev/) for PDF generation. If you're not familiar with this software, feel free to check out [my tutorial on YouTube](https://youtu.be/bo15xdjXf1Y?si=hFZMTfjzfSOLOLPK). If you don't want to self-host Gotenberg, you use other PDF generation provider (PDFMonkey, ApiTemplate or similar).\n3. If you like this workflow, please subscribe to [my YouTube channel](https://www.youtube.com/@workfloows) and/or [my newsletter](https://workfloows.com/).\n\n**Thank you for your support!**"}, "typeVersion": 1}], "connections": {"Auth": {"main": [[{"node": "Check if start message", "type": "main", "index": 0}], [{"node": "No operation (unauthorized)", "type": "main", "index": 0}]]}, "Get file": {"main": [[{"node": "Extract text from PDF", "type": "main", "index": 0}]]}, "Projects": {"main": [[{"node": "Merge projects and volunteering", "type": "main", "index": 0}]]}, "Education": {"main": [[{"node": "Merge education and employment history", "type": "main", "index": 1}]]}, "Merge all": {"main": [[{"node": "Set final data", "type": "main", "index": 0}]]}, "Technologies": {"main": [[{"node": "Merge personal info and technologies", "type": "main", "index": 1}]]}, "Volunteering": {"main": [[{"node": "Merge projects and volunteering", "type": "main", "index": 1}]]}, "Personal info": {"main": [[{"node": "Merge personal info and technologies", "type": "main", "index": 0}]]}, "Set final data": {"main": [[{"node": "Convert raw to base64", "type": "main", "index": 0}]]}, "Convert to HTML": {"main": [[{"node": "Generate plain PDF doc", "type": "main", "index": 0}]]}, "Merge other data": {"main": [[{"node": "Merge all", "type": "main", "index": 1}]]}, "Telegram trigger": {"main": [[{"node": "Auth", "type": "main", "index": 0}]]}, "OpenAI Chat Model": {"ai_languageModel": [[{"node": "Parse resume data", "type": "ai_languageModel", "index": 0}]]}, "Parse resume data": {"main": [[{"node": "Set parsed fileds", "type": "main", "index": 0}]]}, "Set parsed fileds": {"main": [[{"node": "Convert employment history to HTML", "type": "main", "index": 0}, {"node": "Convert education to HTML", "type": "main", "index": 0}, {"node": "Convert projects to HTML", "type": "main", "index": 0}, {"node": "Personal info", "type": "main", "index": 0}, {"node": "Convert volunteering to HTML", "type": "main", "index": 0}, {"node": "Technologies", "type": "main", "index": 0}]]}, "Employment history": {"main": [[{"node": "Merge education and employment history", "type": "main", "index": 0}]]}, "OpenAI Chat Model1": {"ai_languageModel": [[{"node": "Auto-fixing Output Parser", "type": "ai_languageModel", "index": 0}]]}, "Convert raw to base64": {"main": [[{"node": "Convert to HTML", "type": "main", "index": 0}]]}, "Extract text from PDF": {"main": [[{"node": "Parse resume data", "type": "main", "index": 0}]]}, "Check if start message": {"main": [[{"node": "Get file", "type": "main", "index": 0}], [{"node": "No operation (start message)", "type": "main", "index": 0}]]}, "Generate plain PDF doc": {"main": [[{"node": "Send PDF to the user", "type": "main", "index": 0}]]}, "Convert projects to HTML": {"main": [[{"node": "Projects", "type": "main", "index": 0}]]}, "Structured Output Parser": {"ai_outputParser": [[{"node": "Auto-fixing Output Parser", "type": "ai_outputParser", "index": 0}]]}, "Auto-fixing Output Parser": {"ai_outputParser": [[{"node": "Parse resume data", "type": "ai_outputParser", "index": 0}]]}, "Convert education to HTML": {"main": [[{"node": "Education", "type": "main", "index": 0}]]}, "Convert volunteering to HTML": {"main": [[{"node": "Volunteering", "type": "main", "index": 0}]]}, "Merge projects and volunteering": {"main": [[{"node": "Merge other data", "type": "main", "index": 1}]]}, "Convert employment history to HTML": {"main": [[{"node": "Employment history", "type": "main", "index": 0}]]}, "Merge personal info and technologies": {"main": [[{"node": "Merge all", "type": "main", "index": 0}]]}, "Merge education and employment history": {"main": [[{"node": "Merge other data", "type": "main", "index": 0}]]}}}How to Import This Workflow
- 1Copy the workflow JSON above using the Copy Workflow JSON button.
- 2Open your n8n instance and go to Workflows.
- 3Click Import from JSON and paste the copied workflow.
Don't have an n8n instance? Start your free trial at n8nautomation.cloud
Related Templates
ETL pipeline
Automate your data extraction, transformation, and loading with this robust ETL pipeline, designed to efficiently process and analyze information from various sources. This workflow begins on a schedule, fetching tweets from Twitter/X, then storing them in MongoDB for initial processing. The MongoDB data is then sent to Google Cloud Natural Language for sentiment analysis or entity extraction, with the results subsequently prepared and stored in PostgreSQL. A conditional check on the PostgreSQL data determines whether to send an alert to Slack, ensuring timely notifications for critical insights or anomalies. This powerful automation is ideal for marketing teams monitoring brand sentiment, researchers analyzing public opinion, or businesses tracking competitor activity, providing actionable intelligence without manual data handling. By automating data ingestion, enrichment, and storage, this workflow significantly reduces the time and effort spent on data preparation, allowing teams to focus on analysis and strategic decision-making while ensuring data consistency and accessibility.
SQL agent with memory
Empower your data analysis with the SQL agent with memory workflow, automating the process of querying databases using natural language. This powerful workflow connects OpenAI's advanced language models with your local SQL databases, allowing you to interact with your data through a conversational interface. Initially, the workflow downloads a chinook.zip example database, extracts it, and saves the chinook.db file locally, making it immediately available for querying. The AI Agent, powered by OpenAI Chat Model and supported by a Window Buffer Memory, interprets your natural language questions, translates them into SQL queries, executes them against your local chinook.db, and provides the results back to you. This is incredibly useful for data analysts, business intelligence professionals, or anyone needing quick insights from their databases without writing complex SQL queries, significantly reducing the time and specialized knowledge required for data exploration. By leveraging the Chat Trigger, users can easily initiate conversations and receive immediate, intelligent responses, streamlining data access and accelerating decision-making.
Prepare CSV files with GPT-4
Transform raw, unstructured text into perfectly formatted CSV files using the power of GPT-4 with this n8n workflow. This automation connects OpenAI's advanced language model to process your input, then meticulously structures the output into a usable CSV format. Ideal for data analysts, marketers, or researchers, this workflow helps you extract specific information from large text datasets, such as customer reviews, survey responses, or article summaries, and prepare it for analysis in spreadsheets or databases. By automating the extraction and formatting of data, you significantly reduce manual data entry errors and save countless hours of tedious work, allowing you to focus on insights rather than data preparation. The workflow manually triggers, sending your text to OpenAI, then splits the responses into manageable batches, parses the JSON output, converts it into a structured table, and finally saves a clean, UTF-8 encoded CSV file to disk, ensuring compatibility across various systems.