Telegram + LinkedIn: tailored resume PDFs on demand
Tailoring a resume shouldn’t mean duplicating files, rewriting the same bullets, and then wondering which “final_v7_reallyfinal.pdf” you actually sent. But that’s the reality when every job needs a slightly different angle.
If you’re a job seeker applying to several roles a week, this resume PDF automation keeps you moving fast without getting sloppy. A recruiter who helps candidates polish materials can use it to generate clean variants on demand. And a career coach can turn “send me the link” into “here’s your tailored PDF” while the client is still motivated.
You’ll send a LinkedIn job link (or paste a job description) to Telegram, and n8n will return a role-matched resume PDF plus a shareable link. Below, you’ll see exactly what it automates, what you need, and where people usually get stuck.
How This Automation Works
Here’s the complete workflow you’ll be setting up:
n8n Workflow Template: Telegram + LinkedIn: tailored resume PDFs on demand
flowchart LR
subgraph sg0["OnTelegramMessage Flow"]
direction LR
n0@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Send a document"]
n2@{ icon: "mdi:robot", form: "rounded", label: "GetTailoredJsonResume", pos: "b", h: 48 }
n3@{ icon: "mdi:robot", form: "rounded", label: "EnsureJsonResumeSchema", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "SetJsonResume", pos: "b", h: 48 }
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>GenerateResume"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>GetResumePdf"]
n7@{ icon: "mdi:swap-vertical", form: "rounded", label: "SetFinalFields", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IsLinkedinUrl", pos: "b", h: 48 }
n9@{ icon: "mdi:swap-vertical", form: "rounded", label: "SetJobLink", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>MapJob"]
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>GetJobHTML"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/html.dark.svg' width='40' height='40' /></div><br/>ParseJobHTML"]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>GetJsonResume"]
n14@{ icon: "mdi:swap-vertical", form: "rounded", label: "SetAllFields", pos: "b", h: 48 }
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>OnTelegramMessage"]
n10 --> n11
n11 --> n12
n9 --> n10
n6 --> n7
n12 --> n13
n14 --> n2
n13 --> n14
n8 --> n9
n8 --> n13
n4 --> n5
n5 --> n6
n7 --> n1
n15 --> n8
n2 --> n4
n0 -.-> n2
n0 -.-> n3
n3 -.-> n2
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n15 trigger
class n2,n3 ai
class n0 aiModel
class n8 decision
class n5,n6,n11,n13 api
class n10 code
classDef customIcon fill:none,stroke:none
class n1,n5,n6,n10,n11,n12,n13,n15 customIcon
Why This Matters: Tailoring Resumes Without the Rewrite Spiral
Most resume tailoring breaks for boring reasons. You open an old version, copy a few bullets, tweak a summary, then try to mirror the job post without sounding like you swallowed keywords. After that you export to PDF, realize the formatting shifted, fix it, and export again. Do this a few times in a week and it’s not just “time spent.” It’s mental drag. It also creates version mixups that are honestly embarrassing, like sending a product-marketing resume to a data analyst role because the filenames looked the same.
It adds up fast. Here’s where it breaks down in real life:
- Every application becomes a mini project, so you delay applying until “later,” which quietly kills momentum.
- Manual edits invite inconsistencies, like a skills section that doesn’t match your updated experience bullets.
- PDF exports are a time sink when spacing and headings shift, especially after last-minute changes.
- Without a repeatable process, you can’t scale beyond a handful of high-effort applications per week.
What You’ll Build: Telegram → Tailored Resume PDF Generator
This workflow turns a job link into a ready-to-send resume PDF without the back-and-forth edits. You message a Telegram bot with a LinkedIn job URL (or paste the job description), and n8n grabs the job content via HTTP. It also fetches your baseline resume in JSON Resume format from a public location (many people use GitHub Gist). Then an OpenRouter-powered LLM agent rewrites and reshapes your resume content to better match the role, while still keeping it factual and structured. Once the tailored resume JSON is validated, the workflow generates an HTML version and a PDF, then sends the PDF back to you in Telegram with download links.
The flow starts in Telegram, moves through “job extraction + resume fetch,” then uses AI to tailor your resume, and finishes with a generated PDF delivered back to the same chat. If LinkedIn scraping needs it, proxy support is available so you can still extract job details reliably.
What You’re Building
| What Gets Automated | What You’ll Achieve |
|---|---|
|
|
Expected Results
Say you apply to 5 roles in a week. Manually, tailoring (about 30 minutes) plus cleanup and PDF exporting (about 15 minutes) is roughly 45 minutes per role, or close to 4 hours total. With this workflow, you spend about 2 minutes sending the link and skimming the output, then wait a few minutes for generation. That’s around 15 minutes of hands-on work for the week, not an entire afternoon.
Before You Start
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Telegram Bot to receive job links and reply with PDFs.
- OpenRouter account to power the AI resume tailoring.
- Public JSON Resume URL (host it on GitHub Gist or similar).
Skill level: Intermediate. You won’t write “real code,” but you should be comfortable connecting accounts, adding API keys, and testing a workflow end to end.
Want someone to build this for you? Talk to an automation expert (free 15-minute consultation).
Step by Step
A Telegram message kicks it off. You send a LinkedIn job URL (or a pasted job description) to your bot, and the workflow immediately checks what you sent so it knows how to proceed.
The job post gets retrieved and parsed. n8n uses HTTP Request to fetch the job page HTML (optionally through a proxy) and extracts the important bits, like responsibilities and requirements, so the AI has real context to work with.
Your baseline resume is pulled from one source. The workflow fetches your JSON Resume, assembles clean input fields, then uses an OpenRouter LLM chain to tailor the content. A structured validation step checks the output against a resume schema so you don’t get malformed sections or missing fields.
HTML and PDF are generated and delivered. Once the tailored JSON is mapped, another HTTP call generates the resume output files, then the PDF and links are sent back to you in Telegram as a document.
You can easily modify the tailoring prompt to match your voice, or swap the output destination from Telegram to a storage tool, based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Telegram Trigger
This workflow starts when a Telegram message is received and checks if a LinkedIn URL is present.
- Add the Telegram Message Trigger node and set Updates to
message. - Credential Required: Connect your telegramApi credentials in Telegram Message Trigger.
- In Check LinkedIn Link, set the condition Left Value to
{{ $json.message?.entities.find(item => item.type === 'url') }}with the operator exists.
Step 2: Connect Job and Resume Data Sources
Pull the LinkedIn job page, extract the HTML data, and fetch the base resume JSON used for AI tailoring.
- In Assign Job Link, set job_link to
{{ $('Telegram Message Trigger').item.json.message.link_preview_options.url }}. - In Derive Job Identifier, keep the provided JavaScript that extracts job_id from the LinkedIn URL.
- Configure Retrieve Job HTML with URL set to
=https://www.linkedin.com/jobs/view/{{ $json.job_id }}. - In Extract Job HTML Data, set Operation to
extractHtmlContentand keep the CSS selectors for description, title, and location. - In Fetch Resume JSON, set URL to
https://gist.githubusercontent.com/daniel-iliesh/3c03c0669cb75f70aa04e5f2bb6d79c1/raw/resume.json. - Check LinkedIn Link outputs to both Assign Job Link and Fetch Resume JSON in parallel, so both job and resume data are prepared for the next step.
Step 3: Set Up Input Mapping and AI Resume Tailoring
Merge job description and resume JSON, then generate an optimized resume using the LLM and schema validation.
- In Assemble Input Fields, map jd to
{{ $("Check LinkedIn Link").item.json.message?.link_preview_options ? $("Extract Job HTML Data").item.json.title + "\n" + $("Extract Job HTML Data").item.json.location + "\n" + $("Extract Job HTML Data").item.json.description : $("Check LinkedIn Link").item.json.message.text }}. - Set =json_resume to
{{ $json.data.parseJson() }}and keep the provided resume_schema JSON object. - Set job_id to
{{ $if($("Derive Job Identifier").isExecuted, $node["Derive Job Identifier"].json?.job_id, $now.toMillis()) }}and job_title to{{ $if($("Extract Job HTML Data").isExecuted, $node["Extract Job HTML Data"].json?.title?.split("|")[0], $("Check LinkedIn Link").item.json.message.text.split("\n")[0]) }}. - In Craft Tailored Resume JSON, set Text to
=JOB_DESCRIPTION: {{ $json.jd }} RESUME_JSON: {{ JSON.stringify($json.json_resume) }} RESUME_SCHEMA: {{ JSON.stringify($json.resume_schema) }}. - Open OpenRouter Chat Engine and set Model to
openai/gpt-4.1. Credential Required: Connect your openRouterApi credentials. - Validate Resume Schema is an AI output parser tool; ensure credentials are added to the parent OpenRouter Chat Engine, not on the parser node itself.
Step 4: Configure Resume Rendering and Delivery
Send the tailored resume JSON to the rendering service, fetch the PDF, and deliver it through Telegram.
- In Assign Resume JSON, set Mode to
rawand JSON Output to{{ $json.output }}. - Configure Generate Resume Output with URL
=https://thebackend.rocket-champ.pw/resume, MethodPOST, and JSON Body{{ $("Assign Resume JSON").item.json }}. - Set Fetch Resume PDF URL to
=https://thebackend.rocket-champ.pw{{ $json.pdfUrl }}and JSON Body to{{ JSON.stringify($('Assign Resume JSON').item.json) }}. - In Map Final Fields, set chat_id to
{{ $('Telegram Message Trigger').item.json.message.from.id }}and map html / pdf to=https://thebackend.rocket-champ.pw{{ $('Generate Resume Output').item.json.viewUrl }}and=https://thebackend.rocket-champ.pw{{ $('Generate Resume Output').item.json.pdfUrl }}. - In Dispatch Document File, set Operation to
sendDocument, Chat ID to{{ $('Map Final Fields').item.json.chat_id }}, and enable Binary Data. Credential Required: Connect your telegramApi credentials.
{{ $('Map Final Fields').item.json.html }} and {{ $('Map Final Fields').item.json.pdf }}, so users can open both formats instantly.Step 5: Test and Activate Your Workflow
Validate end-to-end behavior before turning on production use.
- Click Execute Workflow and send a Telegram message containing a LinkedIn job link.
- Confirm Retrieve Job HTML and Extract Job HTML Data populate job content, and Fetch Resume JSON returns the resume JSON payload.
- Verify Craft Tailored Resume JSON outputs schema-valid JSON and Assign Resume JSON passes it into the rendering flow.
- Check that Dispatch Document File sends a document plus HTML/PDF buttons to the Telegram chat.
- Once confirmed, switch the workflow to Active to enable live Telegram-based resume optimization.
null and the LinkedIn page fetch may fail. Always test with a valid job URL.Troubleshooting Tips
- Telegram bot credentials can be correct but still fail if the bot can’t message first or is blocked. Check BotFather settings and confirm your chat ID and webhook status in n8n.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- OpenRouter requests can fail due to model availability, rate limits, or an invalid key. Check your OpenRouter dashboard logs first, then reduce prompt size if you’re sending long job descriptions.
Quick Answers
About 30 minutes if you already have your Telegram bot, JSON Resume URL, and OpenRouter key ready.
No. You’ll mostly connect accounts, paste credentials, and test with a few real job links.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenRouter usage costs, which depend on the model you pick and how long your prompts are.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you probably should. You can adjust the “Craft Tailored Resume JSON” prompt to emphasize leadership, metrics, or a specific industry, then keep the “Validate Resume Schema” step as a safety net. Common tweaks include generating a one-page version, producing a cover letter alongside the resume, or swapping the “Dispatch Document File” Telegram delivery for saving to Drive and sending a link.
Usually it’s a bot token issue or a chat permission problem. Regenerate the token in BotFather, update it in n8n, then confirm the bot can actually message the chat you’re testing with. If it works sometimes and fails other times, look for rate limits or multiple webhooks pointing to different n8n instances.
If you self-host, there’s no execution limit (it mostly depends on your server and OpenRouter limits).
Often, yes, because this flow benefits from multi-step logic: fetching and parsing HTML, assembling structured resume fields, running an LLM chain, validating schema output, and then generating files. n8n handles branching and complex steps without pushing you into expensive “premium task” pricing for every little action. It also has a real self-hosting option, which matters when you’re dealing with sensitive career data. Zapier or Make can still work if you simplify the workflow (for example, no schema validation and no PDF generation). If you want help choosing, Talk to an automation expert and you’ll get a straight recommendation.
Once this is set up, “tailor my resume” becomes a quick message you can send from your phone. The workflow handles the repetitive formatting and rewriting loop so you can focus on applying to the right roles.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.