Recruiting teams spend hours on first-round screening—parsing LinkedIn profiles, cross-referencing job requirements, and writing candidate summaries. It’s critical work, but it’s repetitive and error-prone. What if you could automate the entire initial review, freeing your team to focus on real conversations with the best candidates?
This n8n workflow does exactly that: a recruiter sends a LinkedIn profile URL via Telegram, three AI agents powered by Google Gemini analyze the candidate against the job requirements, and a formatted assessment comes back within seconds. Everything is logged to Google Sheets for your records. Let’s build it.
Prefer to skip the setup? Grab the ready-made template → and be up and running in under 10 minutes.
What You’ll Build
- A Telegram bot receives a LinkedIn profile URL from a recruiter
- The workflow scrapes the candidate’s profile data using Apify
- It retrieves the job description from your Google Drive folder
- Three specialized AI agents evaluate the candidate: one scores JD match, one delivers a detailed analysis, and one synthesizes a recruiter-ready recommendation
- Results are stored as a row in Google Sheets for future reference
- A formatted summary is sent back to Telegram with the screening verdict
How It Works — The Big Picture
The workflow orchestrates a multi-stage evaluation: it gathers data from three sources (LinkedIn, Google Drive, Apify), processes it through three independent LLM agents, consolidates the results, and delivers them both to a persistent data store and back to the recruiter in real time.
┌──────────────────────────────────────────────────────────────────────────┐ │ AI CANDIDATE SCREENING PIPELINE │ │ │ │ 1. Telegram Trigger │ │ ↓ │ │ 2. Extract LinkedIn URL → 3. Apify Scraper (LinkedIn Profile) │ │ ↓ │ │ 4. Poll Apify Status → 5. Get Apify Results │ │ ↓ │ │ 6. Google Drive: Fetch Job Description │ │ 7. Extract PDF Text │ │ ↓ │ │ 8–10. Three Parallel LLM Agents (Gemini 2.5 Pro) │ │ • Agent 1: JD Matching Score │ │ • Agent 2: Detailed Candidate Analysis │ │ • Agent 3: Recruiter Recommendation │ │ ↓ │ │ 11. Merge Agent Results │ │ 12. Add to Google Sheets │ │ 13. Format & Send Telegram Summary │ │ ↓ │ │ 14. Telegram Send (Final Message) │ └──────────────────────────────────────────────────────────────────────────┘
What You’ll Need
- n8n account (Cloud or self-hosted, version 1.0+)
- Telegram Bot API—a bot token created via BotFather
- Google Account with access to Google Drive, Google Sheets, and the Gemini API
- Apify Account with API access and a LinkedIn Scraper actor already configured
- Google Drive Folder containing job description PDFs (one per role)
- Google Sheets Document where candidate results will be stored
- LinkedIn URL(s) to test with—public profiles work best
Estimated build time: 45–60 minutes from scratch, or under 10 minutes with the template.
Part 1 — The Trigger and Data Collection
Step 1: Telegram Trigger and URL Extraction
The workflow starts when your recruiter sends a message with a LinkedIn profile link. The Telegram trigger node listens for incoming messages, and a Set node extracts the LinkedIn URL for processing.
Configuration: Set the Telegram Bot token in the credential field. The trigger fires every time a message arrives. A downstream Set node extracts the URL string from the message text using a simple expression.
{
"message": "Please screen this candidate: https://www.linkedin.com/in/james-carter-52a1b3c/",
"linkedinUrl": "https://www.linkedin.com/in/james-carter-52a1b3c/",
"timestamp": "2026-04-08T10:15:00Z"
}
Tip: Make sure your recruiter includes the full LinkedIn profile URL in their message. Private or incomplete URLs will cause the Apify scraper to fail silently. Train users to send the full URL like https://www.linkedin.com/in/username/.
Step 2: Apify LinkedIn Scraper Trigger and Polling
Once you have the URL, send it to Apify’s LinkedIn Profile Scraper actor. Apify will queue the job asynchronously, so you need to poll for results. The workflow launches the actor, then checks its status repeatedly until it’s done.
Configuration: In the Apify node, set the Actor ID to your LinkedIn Scraper actor, pass the LinkedIn URL as input, and call the actor. Store the Run ID for polling. Use a Wait node to space out polling calls (2–3 seconds apart, 30–40 attempts). Once the status shows “Succeeded,” fetch the results from the Apify output dataset.
{
"runId": "YOUR_RUN_ID_FROM_APIFY",
"status": "Succeeded",
"profile": {
"name": "James Carter",
"headline": "Senior Software Engineer at TechCorp",
"location": "Austin, TX, USA",
"about": "10+ years building scalable systems. Expertise in cloud architecture and team leadership.",
"experience": [
{
"title": "Senior Software Engineer",
"company": "TechCorp Inc.",
"duration": "2022–Present",
"description": "Led platform modernization, reducing infrastructure costs by 35%."
}
],
"skills": ["Python", "AWS", "System Design", "Leadership", "Docker", "Kubernetes"],
"endorsements": 247
}
}
Important: Apify’s LinkedIn scraper may hit rate limits if called too frequently. Keep polling intervals at 2–3 seconds and fail gracefully if a profile can’t be scraped (use an IF node to check the status).
Step 3: Fetch Job Description from Google Drive
Your Google Drive folder holds job descriptions as PDFs. In parallel with the Apify scrape, the workflow fetches the correct job description. A Set node stores the job title or folder ID for lookup, and a Google Drive node finds and downloads the PDF.
Configuration: Use Google Drive credentials (OAuth2). Set the operation to “Download File” and specify your folder structure. You may hard-code the folder ID or pass it dynamically based on recruiter input. Extract the PDF file ID and download the binary content.
{
"jobDescriptionFile": {
"id": "1a2b3c4d5e6f7g8h9i0j_JOB_DESC",
"name": "Senior_Software_Engineer_2026.pdf",
"mimeType": "application/pdf",
"size": 45230,
"downloadUrl": "https://drive.google.com/file/d/1a2b3c4d5e6f7g8h9i0j_JOB_DESC/view"
}
}
Part 2 — Document Processing and AI Analysis
Step 4: Extract Text from PDF Job Description
PDF files need to be converted to plain text before the AI agents can analyze them. An n8n PDF Extractor node (or a Code node using a library like pdfkit) parses the PDF and outputs clean text.
Configuration: Feed the downloaded PDF binary into a PDF Extract node. Set it to extract all text. The output is clean, line-broken text suitable for LLM processing.
{
"jobDescriptionText": "Senior Software Engineer - Full-Time, Austin, TX\n\nAbout the Role:\nWe're seeking a Senior Software Engineer to lead our platform modernization initiative...\n\nKey Responsibilities:\n- Design and implement scalable microservices\n- Mentor junior engineers\n- Collaborate with product and design teams\n\nRequired Skills:\n- 8+ years software engineering experience\n- Proficiency in Python, Go, or Rust\n- AWS or GCP certification preferred\n- Strong system design fundamentals\n\nCompensation:\n$180,000–$220,000 + equity"
}
Step 5–7: Three Parallel AI Agents (Gemini 2.5 Pro with LangChain)
This is where the intelligence happens. Three specialized LangChain agents, each powered by Google Gemini 2.5 Pro, evaluate the candidate from different angles. They run in parallel for speed, each receiving the same candidate profile and job description but with a different prompt.
Agent 1: JD Matching Agent
Purpose: Assign a match score (0–100%) and list which job requirements the candidate meets and which they lack.
Prompt: “You are a recruitment analyst. Compare this candidate’s profile to the job description. Score the match from 0–100%. List which required skills are present, which are missing, and which desired skills the candidate has. Be precise and numerical.”
{
"matchScore": 78,
"requiredSkillsMet": ["Python", "AWS", "System Design", "Leadership"],
"requiredSkillsMissing": [],
"desiredSkillsPresent": ["Docker", "Kubernetes"],
"reasoning": "Strong match on core backend skills and architecture. Leadership experience aligns with mentoring expectations."
}
Agent 2: Detailed Analysis Agent
Purpose: Provide a deep-dive evaluation of the candidate’s background, strengths, gaps, and how they’d perform in the role.
Prompt: “You are a senior recruiter reviewing this candidate. Write a comprehensive 2–3 paragraph evaluation of their fit for the role. Consider their experience trajectory, demonstrated technical depth, leadership maturity, and any red flags or concerns. Be constructive but honest.”
{
"analysis": "James Carter presents a strong profile for this role. His 10 years in software engineering, with the last 4 focused on platform modernization at TechCorp, directly mirror the responsibilities outlined. His experience leading infrastructure cost optimization demonstrates both technical depth and business acumen. However, his background is predominantly in established, large-scale systems; this role will require exposure to startup-pace decision-making. His skill set is very current—Docker, Kubernetes, and AWS are all heavily weighted in the job description. No significant gaps identified beyond the typical onboarding curve."
}
Agent 3: Recruiter Recommendation Agent
Purpose: Synthesize the other two analyses and produce a hiring recommendation for the recruiter (e.g., “Strong Yes,” “Yes with caveats,” “No”).
Prompt: “Based on the candidate profile, job description, and the above analyses, provide a short hiring recommendation. Choose from: ‘Strong Yes—move to phone screen,’ ‘Yes, with caveats,’ ‘Maybe—needs clarification on specific skills,’ ‘No—not a fit.’ Explain your recommendation in 1–2 sentences.”
{
"recommendation": "Strong Yes—move to phone screen",
"rationale": "Carter's technical skills and leadership experience are a strong fit. His platform modernization background directly aligns with the role's core responsibility. Recommend phone screen to assess cultural fit and career motivation."
}
Tip: Parallel execution is critical for speed. All three agents should start at the same time (use a Merge node to combine their outputs). If one agent times out, the workflow won’t block the others—use error handlers to catch and log failures gracefully.
Part 3 — Results Storage and Final Output
Step 8: Merge Agent Results and Add to Google Sheets
Once all three agents finish, a Merge node combines their outputs into a single structured result. This consolidated data is then added as a new row to your Google Sheets document, creating a searchable archive of all screening decisions.
Configuration: Set up the Merge node to combine all agent outputs under a single object. In the Google Sheets node, configure the operation to “Append Row” into your spreadsheet. Map each agent result to a column: matchScore, analysis, recommendation, linkedinUrl, timestamp, and candidateName.
{
"linkedinUrl": "https://www.linkedin.com/in/james-carter-52a1b3c/",
"candidateName": "James Carter",
"timestamp": "2026-04-08T10:15:00Z",
"matchScore": 78,
"requiredSkillsMet": "Python, AWS, System Design, Leadership",
"requiredSkillsMissing": "None",
"analysis": "James Carter presents a strong profile...",
"recommendation": "Strong Yes—move to phone screen"
}
Step 9: Format and Send Telegram Summary
The final step sends a formatted message back to the recruiter via Telegram. The message includes the match score, the recommendation, and a brief summary for quick review.
Configuration: Use a Set node to format the output as a readable Telegram message (emoji, line breaks, bold text). Then use a Telegram Send node to deliver it to the recruiter’s chat ID (or the original chat where they sent the URL).
{
"telegramMessage": "✅ SCREENING COMPLETE\\n\\nCandidate: James Carter\\nMatch Score: 78%\\nRecommendation: Strong Yes—move to phone screen\\n\\nProfile: Senior Software Engineer at TechCorp (10 yrs exp)\\nKey Fit: Python, AWS, System Design, Leadership all present.\\n\\nFull analysis saved to screening sheet.",
"chatId": "YOUR_RECRUITER_CHAT_ID"
}
Tip: Add a conditional branch here. If the recommendation is “No,” prefix the Telegram message with a ⛔ emoji. If it’s “Strong Yes,” use a 🚀 emoji. This gives the recruiter instant visual feedback before they even read the details.
The Data Structure
All screening results are logged to a Google Sheets document. This becomes your searchable candidate database. Each row captures one screening event, with columns for the LinkedIn URL, candidate name, all three agent outputs, and the timestamp.
| Column | Type | Example | Description |
|---|---|---|---|
Date |
Date | 2026-04-08 | Screening date (auto-populate with workflow timestamp) |
Candidate Name |
Text | James Carter | Full name from LinkedIn profile |
LinkedIn URL |
URL | https://www.linkedin.com/in/james-carter-52a1b3c/ | Link to original profile |
Job Title Screened For |
Text | Senior Software Engineer | Which job description was used |
Match Score |
Number | 78 | 0–100 from Agent 1 |
Required Skills Met |
Text | Python, AWS, System Design, Leadership | Comma-separated list from Agent 1 |
Required Skills Missing |
Text | (none) | Gaps the candidate should address |
Detailed Analysis |
Long Text | James Carter presents a strong profile… | Full paragraph from Agent 2 |
Recommendation |
Text | Strong Yes—move to phone screen | Decision from Agent 3 |
Important: Set up the Google Sheets document with these column headers before importing the workflow. The column names must match exactly—the workflow expects Candidate Name, Match Score, etc. If you rename columns, update the field mappings in the Google Sheets node.
Full System Flow
Here’s the complete end-to-end journey, from recruiter message to final Telegram response:
┌─────────────────────────────────────────────────────────────────────────┐ │ FULL AI SCREENING PIPELINE │ │ │ │ TRIGGER │ │ ┌──────────────────┐ │ │ │ Telegram Message │ (Recruiter sends LinkedIn URL) │ │ └────────┬─────────┘ │ │ │ │ │ DATA GATHERING (Parallel) │ │ ├──→ Apify LinkedIn Scraper ────→ Poll for Results │ │ │ │ │ └──→ Google Drive ────→ Download Job Description PDF │ │ │ │ │ Extract PDF Text │ │ │ │ │ ↓ (Wait for both) │ │ │ │ │ AI ANALYSIS (3 Parallel Agents) │ │ ├──→ Agent 1: JD Match Score & Skills Gap │ │ ├──→ Agent 2: Detailed Candidate Analysis │ │ └──→ Agent 3: Recruiter Recommendation │ │ │ │ │ ↓ (Merge all agent outputs) │ │ │ │ │ PERSISTENCE & OUTPUT │ │ ├──→ Add Row to Google Sheets │ │ │ │ │ └──→ Format & Send Telegram Summary │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ Recruiter Receives Summary in Telegram│ (with score + recommendation) │ └──────────────────────────────────────┘ │ │ │ │ ✅ Full screening complete in 30–60 seconds │ │ │ └─────────────────────────────────────────────────────────────────────────┘
Testing Your Workflow
Before letting your team loose on the workflow, run through this test plan to confirm everything is wired correctly.
- Send a test LinkedIn URL via Telegram: Use a public profile (e.g., your own LinkedIn or a known public figure). Send a message to your bot like: “Please screen: https://www.linkedin.com/in/sarah-thompson-engineering/”
- Monitor the n8n execution: Open the workflow’s execution history in n8n and watch for successful node completion. Check that Apify returns profile data, Google Drive successfully downloads the PDF, and all three agents produce output.
- Check Telegram for the response: Within 30–60 seconds, you should receive a formatted message with a match score and recommendation.
- Verify the Google Sheets row: Open your screening spreadsheet and confirm that a new row was added with all the candidate details and agent analysis.
| Problem | Likely Cause | Fix |
|---|---|---|
| Telegram message not triggering workflow | Bot token incorrect or Telegram node not listening on the right chat | Re-check bot token in Telegram credential. Confirm you’re messaging the correct bot. |
| Apify scraper returns empty profile | LinkedIn profile is private or URL is malformed | Test with a public profile. Ensure recruiter sends full URL (https://www.linkedin.com/in/username/). |
| Google Drive node returns “File not found” | Job description PDF is not in the specified folder, or folder ID is wrong | Double-check folder ID in Google Drive config. Confirm PDF file exists and is accessible. |
| Gemini agents time out or return empty responses | API quota exceeded, malformed prompt, or credential not authenticated | Check Google Cloud console for quota limits. Re-authenticate Gemini credential. Simplify the prompt if needed. |
| Google Sheets append fails | Column names don’t match, sheet is read-only, or credentials lack write access | Verify column headers match exactly. Check sheet permissions. Re-authenticate Google Sheets credential. |
| Telegram response is delayed (>2 minutes) | Apify polling is slow, or Gemini API is slow | Reduce polling interval slightly (1–2 sec). Check n8n logs for slow node execution. |
Frequently Asked Questions
Can I screen candidates for multiple jobs at once?
Yes. Instead of hard-coding a single job description, modify the workflow to accept a job title as an input parameter. Add a conditional step that looks up the corresponding PDF from Google Drive based on the title sent in the Telegram message. For example, if the recruiter sends “Screen for Senior Software Engineer,” the workflow finds and uses that specific job description.
What if Apify can’t scrape a LinkedIn profile?
Apify may fail on private profiles, suspended profiles, or if LinkedIn rate-limits the scraper. Add an error handler branch after the Apify polling step. If the status is “Failed,” send a message back to the recruiter explaining the issue and ask them to provide a public-facing profile link or a resume PDF instead. You can then use a PDF extractor node to parse the resume and proceed with the same AI agents.
How much does this cost to run?
Costs depend on your service usage. Gemini API charges per 1,000 input tokens (~$0.075) and 1,000 output tokens (~$0.3). A typical screening run uses about 5,000–8,000 tokens total, so roughly $0.05–$0.10 per candidate. Apify charges based on actor runs (LinkedIn scraper ~$0.05–$0.15 per run). Google Sheets and Google Drive are included in your Google Workspace account (no additional charge). Telegram Bot is free. Total cost per screening: roughly $0.10–$0.30.
Can I customize the AI agents’ evaluation criteria?
Absolutely. Each agent’s instructions are defined in the LangChain prompt. Edit the prompt in each agent node to emphasize different criteria. For example, if your role prioritizes “leadership and mentoring ability,” adjust Agent 2’s prompt to focus on those traits. Or if you want more detail, ask the agents to return structured JSON with sub-scores instead of prose.
What if the recruiter needs to screen a candidate without a LinkedIn profile?
Create an alternative input path. After the initial Telegram message, add a conditional step: if the message contains a LinkedIn URL, proceed with Apify; if it contains a resume attachment or a Drive link, fetch and parse that instead. Both paths merge at the “AI Analysis” stage, so the agents evaluate the same data regardless of source.
How do I integrate this with my existing ATS (Applicant Tracking System)?
Most modern ATSs expose an API for candidate creation. After screening results are added to Google Sheets, add a conditional node that checks the recommendation. If it’s “Strong Yes,” make an HTTP POST request to your ATS’s API with the candidate details, match score, and recruiter notes. This creates a pre-filled candidate record that the recruiter can review and move forward in your hiring workflow.
Get the AI Candidate Screening Template
Stop screening manually. Import the complete 55-node workflow in under 10 minutes, configure your credentials, and let AI agents handle first-round reviews while you focus on real conversations.
Instant download · Works on n8n Cloud and self-hosted · Setup guide included
What’s Next?
- Add a second-stage review: Create a companion workflow that triggers when a recruiter flags a candidate for deeper evaluation. It can compile a detailed dossier from LinkedIn, recent GitHub contributions, and portfolio links.
- Expand to video interviews: Integrate a video interview scheduling tool (e.g., Calendly, Slack) to automatically send a booking link to “Strong Yes” candidates, streamlining the next step.
- Multi-language support: Use Google Translate in parallel with Gemini to evaluate candidates from non-English profiles, opening your talent pool globally.
- Scoring refinement: Once you have 20–30 screening results in Google Sheets, analyze which candidates actually performed well in interviews and phone screens. Use that data to fine-tune the agents’ prompts and weightings for even better predictions.