Tailor your Google Docs CV to any job using Ollama and Groq
π― CV Keyword Optimizer
An AI-powered n8n workflow that automatically tailors your resume to any job description by injecting relevant keywords β without touching your formatting, layout, or design.
How It Works
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β User Input (Form) β β CV Google Docs Link + Job URL or Pasted JD β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 1. Read CV from Google Docs API β β 2. Extract full CV text (handles tables, paragraphs, etc.) β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 3. Get Job Description β β βββ URL provided? β Scrape job page, strip HTML to text β β β βββ Scrape failed? β Fall back to manual JD β β βββ No URL? β Use manually pasted JD directly β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 4. π Local Ollama (llama3.1:8b) β β Analyzes JD + CV β Extracts & ranks 10-20 ATS keywords β β Output: keyword, priority, target bullet, reason β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 5. βοΈ Groq API (Llama 3.3 70B) β β Takes ranked keywords + CV β Produces find/replace pairs β β Naturally weaves keywords into experience bullet points β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 6. Copy original CV via Google Drive API β β (preserves ALL formatting, tables, styles) β β β β 7. Apply replacements via Google Docs batchUpdate API β β (replaceAllText β formatting stays intact) β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 8. Output β β β New Google Doc link β β π Changelog: original text β updated text + keywords added β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Why Two AI Models?
| Step | Model | Why | |------|-------|-----| | Keyword Extraction | Ollama llama3.1:8b (local) | Free, private, no API costs. Reasoning about which keywords actually matter for ATS | | Text Rewriting | Groq llama-3.3-70b-versatile (cloud) | Larger model = better at natural language. Produces find/replace pairs that read naturally |
What Gets Modified
β Experience/work bullet points β Skills/technical skills lines β Name, contact info, education, dates, company names, job titles β never touched
Formatting Preservation
The workflow copies your original Google Doc (not recreates it), then uses replaceAllText to swap text in-place. This means:
β Tables, columns, fonts, colors β all preserved β Bold, italic, underline β all preserved β Custom spacing, margins β all preserved β Original doc is untouched (changes go to the copy)
Setup Steps
Prerequisites
Docker installed Ollama installed locally A Groq API key (free tier works) Google account with Docs & Drive access
- Install & Start Ollama
macOS brew install ollama
Start the Ollama server ollama serve
Pull the model (in another terminal) ollama pull llama3.1:8b
Verify it's running: curl http://localhost:11434/api/tags
- Get a Groq API Key
Go to console.groq.com Sign up / log in Navigate to API Keys β Create a new key Copy the key (starts with gsk_...)
- Configure Environment
cd cv-generator
Create .env from template cp .env.example .env
Edit .env and add your Groq key GROQ_API_KEY=gsk_your_key_here
- Start n8n
docker compose up -d
n8n will be available at http://localhost:5678
Default credentials: Username: admin Password: changeme
> β οΈ Change these in docker-compose.yml for production use.
- Import the Workflow
Open n8n at http://localhost:5678 Go to Workflows β Import from File Select cv-keyword-optimizer.json You'll see credential warnings on some nodes β that's expected
- Set Up Google Credentials
In n8n, go to Settings β Credentials Create a Google Docs OAuth2 credential Follow n8n's OAuth2 setup guide for Google Required scopes: https://www.googleapis.com/auth/documents Create a Google Drive OAuth2 credential Required scopes: https://www.googleapis.com/auth/drive Click each node with a β οΈ warning β select your credential from the dropdown
- Activate & Use
Toggle the workflow Active Open the form URL shown in the trigger node (or go to http://localhost:5678/form/cv-keyword-optimizer-form) Fill in: Google Docs CV Link (required) Job Posting URL or Job Description (at least one) Submit and wait ~30-60 seconds Get your optimized CV link + detailed changelog
Project Structure
cv-generator/ βββ cv-keyword-optimizer.json # n8n workflow definition βββ docker-compose.yml # n8n container config βββ .env # Environment variables (not committed) βββ .env.example # Template for .env βββ .gitignore # Ignores .env βββ README.md # This file
Troubleshooting
| Issue | Solution | |-------|----------| | Ollama connection refused | Make sure ollama serve is running. n8n reaches it via host.docker.internal:11434 | | Groq 429 rate limit | Free tier has limits. Wait a minute and retry | | Scraping fails on LinkedIn | LinkedIn blocks scrapers. Paste the JD manually instead | | Google Docs auth error | Re-check OAuth2 credentials in n8n. Ensure correct scopes | | Replacements don't apply | The AI's "find" text must exactly match the CV. Check the Changes Summary for what was attempted | | Empty response from Ollama | Model may still be loading. First run takes longer. Timeout is set to 5 min |
Related Templates
AI Weather Forecasts with MCP Integration
Real-time Weather Forecasts with MCP Tools This n8n workflow demonstrates how to integrate real-time weather intelligen...
Google Sheets UI for n8n Workflow
Google Sheets UI for Workflow Control This n8n template provides a practical and efficient way to manage your n8n workf...
Demo Workflow - How to use workflowStaticData()
This workflow demonstrates how to use the workflowStaticData() function to set any type of variable that will persist wi...
π Please log in to import templates to n8n and favorite templates
Workflow Visualization
Loading...
Preparing workflow renderer
Comments (0)
Login to post comments