Tailor your Google Docs CV to any job using Ollama and Groq

Go to Workflow
1 views
Built by Rishi Rishi
Created on May 10, 2026

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?

| 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

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

Go to console.groq.com
Sign up / log in
Navigate to API Keys β†’ Create a new key
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:
Username: admin
Password: changeme

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

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

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

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

This workflow was created by Rishi and shared publicly on the n8n community template library. n8nFind indexes it for discovery — the workflow remains the property of its original creator.

Nodes Used (7)

Basic LLM Chain
@n8n/n8n-nodes-langchain.chainLlm
Code
n8n-nodes-base.code
Google Docs
n8n-nodes-base.googleDocs
Google Drive
n8n-nodes-base.googleDrive
Groq Chat Model
@n8n/n8n-nodes-langchain.lmChatGroq
HTTP Request
n8n-nodes-base.httpRequest
Ollama Chat Model
@n8n/n8n-nodes-langchain.lmChatOllama