πŸ‘₯ Tailor your Google Docs CV to any job using Ollama and Groq

⚑ 85 views Β· πŸ‘₯ HR & Recruitment

πŸ’‘ Pro Tip β€” HTTP Request scraping tends to break when sites update their markup. If you’re scraping a major platform, check if ScraperNode covers it β€” it has maintained scrapers for LinkedIn, Instagram, TikTok, YouTube, and 20+ other platforms that return structured data.

View All Scrapers

Description

🎯 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?

StepModelWhy
Keyword ExtractionOllama llama3.1:8b (local)Free, private, no API costs. Reasoning about which keywords actually matter for ATS
Text RewritingGroq llama-3.3-70b-versatile (cloud)Larger model = better at natural language. Produces find/replace pairs that read naturally

What Gets Modified

Formatting Preservation

The workflow copies your original Google Doc (not recreates it), then uses replaceAllText to swap text in-place. This means:


Setup Steps

Prerequisites

1. 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

2. Get a Groq API Key

  1. Go to console.groq.com
  2. Sign up / log in
  3. Navigate to API Keys β†’ Create a new key
  4. Copy the key (starts with gsk_...)

3. 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

4. Start n8n

docker compose up -d

n8n will be available at http://localhost:5678

Default credentials:

> ⚠️ Change these in docker-compose.yml for production use.

5. Import the Workflow

  1. Open n8n at http://localhost:5678
  2. Go to Workflows β†’ Import from File
  3. Select cv-keyword-optimizer.json
  4. You’ll see credential warnings on some nodes β€” that’s expected

6. Set Up Google Credentials

  1. In n8n, go to Settings β†’ Credentials
  2. Create a Google Docs OAuth2 credential
    • Follow n8n’s OAuth2 setup guide for Google
    • Required scopes: https://www.googleapis.com/auth/documents
  3. Create a Google Drive OAuth2 credential
    • Required scopes: https://www.googleapis.com/auth/drive
  4. Click each node with a ⚠️ warning β†’ select your credential from the dropdown

7. Activate & Use

  1. Toggle the workflow Active
  2. Open the form URL shown in the trigger node (or go to http://localhost:5678/form/cv-keyword-optimizer-form)
  3. Fill in:
    • Google Docs CV Link (required)
    • Job Posting URL or Job Description (at least one)
  4. Submit and wait ~30-60 seconds
  5. 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

IssueSolution
Ollama connection refusedMake sure ollama serve is running. n8n reaches it via host.docker.internal:11434
Groq 429 rate limitFree tier has limits. Wait a minute and retry
Scraping fails on LinkedInLinkedIn blocks scrapers. Paste the JD manually instead
Google Docs auth errorRe-check OAuth2 credentials in n8n. Ensure correct scopes
Replacements don’t applyThe AI’s β€œfind” text must exactly match the CV. Check the Changes Summary for what was attempted
Empty response from OllamaModel may still be loading. First run takes longer. Timeout is set to 5 min

πŸ”— Nodes Used

HTTP Request, Google Drive, Google Docs, Basic LLM Chain, Ollama Chat Model, n8n Form Trigger

πŸ“₯ Import

Download workflow.json and import into n8n: Workflow menu β†’ Import from File

πŸ“– Importing guide Β· πŸ”‘ Credential setup