Automated Data Parsing with AI-Generated Resumes in n8n
I developed a complex n8n workflow deployed on the client’s server. The system collects job listings from seven German websites, handles some anti-scraping protection using Browserless, stores the collected data in PostgreSQL, sends relevant information to an AI service, and generates personalized job application files: a resume, cover letter, job description file, and a downloadable ZIP archive. The generated files and application packages are also stored in PostgreSQL.
The project started as a relatively simple job vacancy parser for seven websites, but gradually evolved into a complete automated system for job discovery and application preparation.
The client provided a server where I deployed n8n, installed PostgreSQL, and configured Portainer. The project also included configuring Composer and Nginx. I reused part of the server-side knowledge and infrastructure experience gained from one of my previous n8n projects.
The original requirement sounded straightforward: collect vacancies based on predefined search queries, send the information to an AI model, and generate a ready-to-use resume.
However, as development progressed, it became clear that the actual workflow required significantly more complex logic. The system had to handle multiple job sources, anti-scraping mechanisms, duplicate listings, repeated workflow executions, persistent state, previously processed vacancies, regeneration of application packages, and strict rules governing AI-generated content.
Instead of using a cloud-based solution such as Supabase, I proposed deploying PostgreSQL directly on the client’s server. Since one of my goals was to keep the solution as cost-efficient as possible while meeting the client’s requirements, adding another paid or external service to the workflow was unnecessary.
The database stores discovered vacancies, source URLs, page content, company information, and generated application packages.
A separate Python document service was configured for resume rendering. It works with an ODT template and inserts AI-prepared content into the document according to a predefined structure.
In its final version, the workflow collects vacancies from multiple job platforms, checks the database for duplicates, selects an appropriate vacancy, stores its text and metadata, prepares prompts for the AI model, generates a tailored resume and cover letter, validates the generated content for unsupported or unnecessary claims, and finally assembles all generated documents into a complete application package.
The project also involved the Codex AI assistant. Due to the size of the architecture, the large number of nodes, repeated validation steps, errors, and technical routine involved, Codex helped accelerate troubleshooting, analyze problematic parts of the workflow, validate node logic, identify causes of failures, and improve the overall stability of the workflow structure.
Browserless
Finding a reliable way to collect data from protected German job websites was one of the more challenging parts of the project.
I tested several approaches available for n8n, and Browserless proved to be the most capable solution for the problematic websites.
Browserless provides browser automation through remotely controlled browser sessions, allowing websites to be accessed in a way that is much closer to normal browser interaction than a standard HTTP request. This makes it useful for websites that rely heavily on JavaScript or implement anti-bot and anti-scraping mechanisms.
Browserless provides a free tier, while its paid plans include additional functionality for more complex browser automation and protected websites.
I discussed the available options and associated costs with the client in detail. We eventually agreed on using the entry-level paid Browserless plan.
The project took approximately one and a half months to complete, including revisions.
The final architecture was developed incrementally rather than being designed in its current form from the beginning. The project first started as a parser. PostgreSQL was then added for persistent storage, followed by Browserless for protected websites, separate resume-generation logic, AI output validation, application package storage, and both manual and automated execution scenarios.
What the Finished Project Does
- Runs job searches using predefined parameters and prompts.
- Collects vacancy data from seven job websites.
- Uses Browserless where standard HTTP requests are insufficient.
- Checks whether a vacancy already exists in the database.
- Filters duplicate vacancies and avoids regenerating identical application packages unnecessarily.
- Stores vacancies and generated results in PostgreSQL.
- Sends vacancy descriptions to the AI model under strict generation rules.
- Generates a resume tailored to each vacancy.
- Generates a cover letter.
- Creates a separate file containing information about the vacancy.
- Builds a complete downloadable application package.
- Allows previously generated resumes to be rebuilt using data already stored in the database.
- Supports both manual execution and automatic scheduled runs.
Output Files
- Resume in .odt format.
- Cover letter in .txt format.
- Vacancy information in .txt format.
- ZIP archive containing all generated files.
Technology Stack and Tools
- n8n
- PostgreSQL
- Browserless
- Docker
- Portainer
- Python
- JavaScript
- SQL
- JSON
- HTTP Request nodes
- Code nodes
- Cron / Schedule Trigger
- ODT template
- Python document service for resume generation
- AI API for text generation
- Client-hosted Linux server
Key Challenges
- The project requirements evolved throughout development, which gradually increased the complexity of the architecture.
- The final workflow became relatively large, with many branches, conditions, validation steps, nodes, and dependencies.
- Some websites blocked conventional scraping methods, requiring Browserless integration and separate testing for problematic sources.
- German job websites used different HTML structures, URL formats, and access restrictions.
- Resume generation required strict AI rules: the model had to adapt the applicant’s experience to the vacancy without inventing qualifications or unsupported experience.
- ODT rendering required a separate configuration process to ensure that the generated resume followed the template provided by the client.
- Duplicate handling and repeated workflow executions had to be carefully managed to prevent the system from continuously generating the same application packages.
Other projects
Automated Data Parsing with AI-Generated Resumes in n8n