Stop manually searching for jobs every day. Learn how to build a self-hosted AI job search agent that scans job portals, understands your resume, and sends real-time alerts to Discord.
Why Job Searching Feels Broken
- Endless scrolling across platforms
- Repetitive filtering
- Missed opportunities due to timing Even worse → most platforms don’t understand your profile deeply.
What You’ll Build
In this tutorial, you’ll create a self-hosted AI job search agent using:
- Langflow
- Docker Desktop
- Pinggy
- Discord
Workflow Overview
Resume → AI Processing → Job Matching → Discord Alerts
Inside the AI Workflow (Visual Breakdown)
Let’s break down what’s happening in this workflow:
1. Resume Input (Read File)
- Uploads your resume (PDF)
- Extracts raw content
2. Prompt Template (Resume Analyzer)
- Converts resume into structured data
- Identifies skills, roles, and experience
3. Language Model (Processing Layer)
- Uses an LLM (like Gemini)
- Transforms unstructured data into meaningful insights
4. Job Source (URL Fetcher)
-
Pulls job listings from multiple platforms:
- RemoteOK
- WorkingNomads
- Python jobs
Ensures broader coverage
5. Job Matching Prompt
-
Compares:
- Candidate profile
- Job descriptions
Filters only relevant jobs
6. Final LLM Processing
- Refines output into clean job alerts
7. Discord Notifier
- Sends real-time alerts using webhooks
This modular design is why Langflow is powerful; you can tweak or replace any block easily.
Step 1: Set Up Langflow with Docker
mkdir langflow-project
cd langflow-project
docker pull langflowai/langflow:latest
Run it:
docker run -p 7860:7860 langflowai/langflow:latest
Or with persistence:
docker run -d \
-p 7860:7860 \
-v langflow_data:/app/langflow \
--name langflow \
langflowai/langflow:latest
Step 2: Convert Resume into Structured Data
Instead of treating your resume as plain text, the system:
- Extracts skills
- Identifies experience
- Builds a structured candidate profile
This enables accurate job matching.
prompt:
You are an AI job assistant.
Analyze the candidate's resume and extract structured information.
Return ONLY valid JSON.
Fields:
- skills
- preferred_job_roles
- experience_level
- location_preference
Resume:
{text}
Return format:
{{
"skills": [],
"preferred_job_roles": [],
"experience_level": "",
"location_preference": ""
}}
Step 3: Aggregate Jobs from Multiple Sources
The system fetches jobs from multiple portals, which:
- Increases opportunities
- Reduces platform bias
- Improves match quality
prompt:
You are an AI job search assistant.
Candidate profile:
{resume}
Job board content:
{jobs}
Your task:
1. Extract jobs that match the candidate profile.
2. For each job, ALWAYS extract the application link if present.
3. The application link may appear as:
- "Apply"
- "Apply here"
- "Read more"
- "View job"
- a URL (http/https)
Rules:
- If a URL is found near a job, use it as the application_link.
- If multiple links exist, choose the most relevant job application link.
IMPORTANT:
- If no application link is found, DO NOT return "Not available".
- Instead, generate a fallback Google search link using:
job title + company name.
Format:
https://www.google.com/search?q=JOB_TITLE+COMPANY+apply
Return ONLY valid JSON.
Return format:
{{
"jobs":[
{{
"company":"",
"job_title":"",
"location":"",
"experience":"",
"job_post_date":"",
"application_deadline":"",
"job_description_summary":"",
"application_link":""
}}
]
}}
Step 4: Smart AI-Based Matching
This is where most tools fail, but not this one.
The AI compares:
- Resume data
- Job descriptions
And filters based on:
- Skills
- Experience
- Role fit
Used prompt:
You are a Discord webhook caller. Your ONLY job is to output a valid raw JSON string and nothing else. No explanation, no markdown, no codeblocks.
Always output exactly this format:
{"content:" ""}
Keep content under 1900 characters. Format jobs as plain text like:
1. Company|Title|Location|Application_link
Step 5: Send Real-Time Alerts to Discord
Code:
from lfx.custom.custom_component.component import Component
from lfx.io import MessageTextInput, Output
from lfx.schema import Data
import urllib.request
import json
class DiscordNotifier(Component):
display_name = "Discord Notifier"
description = "Sends a message to Discord webhook"
icon = "send"
inputs = [
MessageTextInput(
name="message",
display_name="Message",
tool_mode=True,
),
]
outputs = [
Output(display_name="Result", name="result", method="send_to_discord")
]
def send_to_discord(self) -> Data:
webhook_url = "Discord_Server_Webhook_URL" #Use your server's URL
raw = str(self.message)
# Extract the content value from {"content": "..."}
try:
parsed = json.loads(raw)
text = parsed.get("content", raw)
except Exception:
text = raw
# Format each line nicely with emojis
lines = ["📋 **New Job Listings**\n"]
for line in text.strip().split("\n"):
if not line.strip():
continue
parts = line.split("|")
if len(parts) >= 4:
number_company = parts[0].strip() # "1. DivIHN Integration Inc"
title = parts[1].strip()
location = parts[2].strip()
link = parts[3].strip()
lines.append(
f"**{number_company}. {title}**\n"
f"📍 {location}\n"
f"🔗 {link}\n"
)
else:
lines.append(line)
msg = "\n".join(lines)[:1990]
payload = json.dumps({"content": msg}).encode()
req = urllib.request.Request(
webhook_url,
data=payload,
headers={
"Content-Type": "application/json",
"User-Agent": "DiscordBot (https://github.com, 1.0)"
},
method="POST"
)
urllib.request.urlopen(req)
self.status = "Sent!"
return Data(data={"status": "success"})
Once a match is found:
- It’s instantly sent to Discord
- You get notified in real time
- You can check from mobile
Step 6: Make It Accessible Online
Expose your local setup using Pinggy:
ssh -p 443 -R0:localhost:7860 -L4300:localhost:4300 \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=30 \
[Pinggy_token]@pro.pinggy.io
Now your system is:
- Live
- Accessible anywhere
- Running 24/7
Why This AI Job Search Agent Works
1. No Manual Searching
Automation handles everything.
2. Better Job Relevance
AI filters out noise.
3. Fully Customizable
You control logic and sources.
4. Privacy First
Everything runs locally.
Real Impact
Instead of spending hours daily, you receive a curated list of jobs tailored to your profile.
Perfect for:
- Freshers
- Career switchers
- Active job seekers
Extend This Beyond Job Search
This workflow pattern can be reused for:
- Lead generation
- Market research
- Content monitoring
Once you understand this, you can automate almost anything.
Resources
- GitHub Repo: https://github.com/Bidisha314/Langflo...
- Langflow: https://www.langflow.org/
- Pinggy: https://pinggy.io/
- How to Self-Host Langflow and Access It Remotely
Extend This System
This architecture isn’t limited to jobs.
You can reuse it for:
- Lead generation
- Market research
- Content monitoring
- Trend tracking
Conclusion
AI is most powerful when it removes repetitive work.
This project is a great example of practical AI automation, not just theory.
If you're serious about improving your job search, this is worth building.




Top comments (0)