LinkedIn Job Sniper is an automated AI agent that hunts for job opportunities on LinkedIn (and other platforms), evaluates them against your resume using LLMs (GPT-4o, DeepSeek, etc.), and sends you a daily summary of the top matches directly to your inbox.
Stop doom-scrolling LinkedIn. Let the AI agent work for you 24/7.
- π΅οΈ Automated Scraping: Scrapes the latest jobs from LinkedIn using
python-jobspy(with Proxy support to avoid bans). - π§ AI-Powered Analysis: Uses LangChain and LLMs (OpenAI/DeepSeek) to semantically score jobs based on your actual resume, not just keywords.
- π§ Daily Email Digest: Sends a beautifully formatted HTML email with the Top 10 matched jobs, including an AI-generated "Reason for Match".
- βοΈ Zero Server Cost: Runs entirely on GitHub Actions (Free Tier).
- π‘οΈ Robust & Resilient: Built-in retry logic, proxy rotation, and error handling for stable operation.
- Trigger: Runs automatically every day (via Cron) or manually via GitHub Actions.
- Scrape: Fetches job listings based on your search criteria (e.g., "Software Engineer" in "Singapore").
- Evaluate: The AI Agent reads your resume and creates a relevance score (0-100) and a reason for every job found.
- Report: Filters the best jobs and emails them to you.
Before starting, you need to prepare the following accounts and information:
| Item | Description | Cost |
|---|---|---|
| GitHub Account | To run the automation | Free |
| Gmail Account | To send job reports | Free |
| AI API Key | OpenAI or DeepSeek | OpenAI ~$5/month DeepSeek ~$1/month |
| Proxy Service | To bypass LinkedIn anti-bot | ~$5 one-time for 1GB |
| Your Resume | In text format | Free |
- Open your browser and go to https://github.com
- Click "Sign up" in the top right corner
- Enter:
- Email address
- Password (at least 15 characters, or 8 characters with numbers and lowercase letters)
- Username (choose any, e.g.,
job-hunter-2026)
- Verify your email (check inbox and click verification link)
- Log in to GitHub
- Visit the original project: https://github.com/tao-991/LinkedInJobSniper
- Click the "Fork" button in the top right corner (fork icon)
- On the popup page, click the green "Create fork" button
- Wait a few seconds, the page will redirect to
YourUsername/LinkedInJobSniper - β
Confirm the top left shows
YourUsername/LinkedInJobSniper
Note: Forking means copying someone else's project completely to your account. All future operations will be on your own copy.
β οΈ Important: You cannot use your regular Gmail login password - you must generate a dedicated app password!
- Go to https://myaccount.google.com/security
- Scroll down to find the "Signing in to Google" section
- Click "2-Step Verification"
- Follow the prompts to set it up (usually using your phone number to receive verification codes)
- Return to https://myaccount.google.com/security
- In the search bar, type "App passwords"
- Click "App passwords" in the search results
- You may need to enter your Gmail password again
- Under "Select app" dropdown, choose "Mail"
- Under "Select device" dropdown, choose "Other"
- Enter a name, e.g.,
JobSniper - Click "Generate"
- π Copy the 16-character password (format like
abcd efgh ijkl mnop) - β Save this password in Notepad - you'll need it later
Tip: This password is only shown once. If you forget it, you'll need to generate a new one.
You need to choose an AI service provider. DeepSeek (cheap) or OpenAI (stable) are recommended.
- Visit https://platform.deepseek.com
- Click "Sign Up" or "Log In" in the top right
- After registration/login, click "API Keys"
- Click "Create API Key"
- Give the key a name, e.g.,
JobSniper - π Copy the generated key (format like
sk-xxxxxxxxxxxx) - Save to Notepad
- Add $5-10 USD credit (will last a long time)
Additional Configuration:
- API Base URL:
https://api.deepseek.com/v1 - Also save to Notepad
- Visit https://platform.openai.com
- Click "Sign up" or "Log in"
- After logging in, click "API keys" in the left menu
- Click "Create new secret key"
- Give the key a name, e.g.,
JobSniper - π Copy the generated key (format like
sk-proj-xxxxxxxxxxxx) - Save to Notepad
- Add $5-10 USD credit
Additional Configuration:
- API Base URL: Not needed (leave empty)
β οΈ Why do you need a proxy? LinkedIn blocks bot access. A proxy disguises your requests as coming from real users.
-
IPRoyal (https://iproyal.com/residential-proxies/)
- Price: $7 = 1GB traffic (lasts several months)
-
Smartproxy (https://smartproxy.com)
- Price: $8.5 = 1GB traffic
-
ThorData (https://thordata.com)
- Price: $1.2 = 1GB traffic
-
Click "Get Started"
-
Register an account and log in
-
Select "Pay As You Go" plan
-
Purchase 1GB traffic (about $7)
-
Go to Dashboard
-
Click "Residential Proxies"
-
Click "Generate Proxy"
-
You'll see proxy information in a format like:
Host: proxy.iproyal.com Port: 12321 Username: your_username Password: your_password -
π Assemble into complete URL (very important - format must be exact):
http://username:password@host:portReal Example:
http://john123:pass456@proxy.iproyal.com:12321 -
Save to Notepad
β οΈ Format Notes:
- Must start with
http://(nothttps://)- Colon and @ symbol positions must be correct
- No spaces allowed
- If password contains special characters like
@#, they need to be URL-encoded
- Open your resume (Word, PDF, or other format)
- Select all text and copy (Ctrl+C or Command+C)
- Paste into Notepad
- Remove all formatting, keep only plain text
- Ensure it includes:
- Your skills
- Work experience
- Education
- Projects
- Save - you'll need this later
Example Resume Format:
Name: John Smith
Email: john.smith@gmail.com
Skills: Python, JavaScript, React, Node.js
Work Experience:
- ABC Company, Software Engineer, 2020-2023
- Developed XYZ system, improved efficiency by 30%
Education:
- MIT, Computer Science BS, 2016-2020
Now tell GitHub all your keys and configuration so the program can run automatically.
- Make sure you're on your forked project page (URL should be
https://github.com/YourUsername/LinkedInJobSniper) - Click the "Settings" tab in the top navigation
- In the left menu, find "Secrets and variables"
- Click to expand, select "Actions"
Now you need to add 7 secrets. For each secret, follow these steps:
- Click the green "New repository secret" button
- In the "Name" field, enter the secret name (see table below)
- In the "Secret" field, paste the corresponding content
- Click "Add secret"
7 Secrets to Add:
| Secret Name | Content Source | Example Value | Required? |
|---|---|---|---|
API_KEY |
AI API key from Step 4 | sk-proj-abc123... |
β Required |
API_BASE |
API Base URL from Step 4 | https://api.deepseek.com/v1 |
Required if using DeepSeek Leave empty if using OpenAI |
EMAIL_SENDER |
Your Gmail address | john.smith@gmail.com |
β Required |
EMAIL_PASSWORD |
Gmail App Password from Step 3 | abcd efgh ijkl mnop |
β Required |
EMAIL_RECEIVER |
Email to receive reports (can be same as sender) | john.smith@gmail.com |
β Required |
PROXY_URL |
Proxy URL from Step 5 | http://user:pass@host:port |
β Required |
RESUME_TEXT |
Resume text from Step 6 | Paste entire resume | Recommended if you don't want to use Google Drive |
CRITERIA |
criteria for AI to score the position. You can put your position reference here | e.g., 1. No Internship Opportunity. | Optional |
GCP_CREDENTIALS_JSON |
Extract resume from Google Drive | {"type": "service_account",...) | Required if you want to extract your resume from google drive |
RESUME_FILE_ID |
Extract resume from Google Drive | text between /d/ and /view?=... in your file address on Google Drive | Required if you want to extract your resume from google drive |
After completion, you should see 7-10 secrets on the Secrets page:
- β API_KEY
- β API_BASE
- β EMAIL_SENDER
- β EMAIL_PASSWORD
- β EMAIL_RECEIVER
- β PROXY_URL
- β RESUME_TEXT (if used)
- β CRITERIA (if used)
- β GCP_CREDENTIALS_JSON (if used)
- β RESUME_FILE_ID (if used)
If you want to modify the job type and location being searched, you can edit the code file.
-
On your project homepage, click the "main.py" file
-
Click the βοΈ pencil icon in the top right (Edit this file)
-
Find these lines of code (around lines 20-30):
SEARCH_TERM = "Software Engineer" LOCATION = ["Singapore"] RESULTS_WANTED = 20
-
Modify to what you want:
SEARCH_TERM = "Product Manager" # Change to your desired position LOCATION = ["New York"] # Change to your desired city RESULTS_WANTED = 30 # Number of jobs to search per run
-
Click the green "Commit changes" button in the top right
-
In the popup, click "Commit changes" again
- On the project homepage, click the "Actions" tab at the top
- If you see a yellow notice saying "Workflows aren't being run...", click the green button "I understand my workflows, go ahead and enable them"
- In the left menu, click "LinkedIn Job Sniper"
- Click the "Enable workflow" button on the right (if present)
Before waiting for the scheduled task, run it manually once to ensure configuration is correct.
- Make sure you're on the "Actions" tab
- In the left sidebar, click "LinkedIn Job Sniper" workflow
- On the right, click the "Run workflow" dropdown
- Keep
Branch: mainunchanged - Click the green "Run workflow" button
- Refresh the page - you'll see a yellow spinning circle
- Wait 3-5 minutes, the yellow circle will turn into:
- β Green checkmark: Success! Check your email
- β Red X: Failed - need to check configuration
- Click the failed run record
- Click the "run-job-sniper" task
- Expand the red step to view error messages
- Common errors:
Authentication failed: Gmail App Password is wrong - regenerate itProxy error: Proxy URL format is wrong or proxy service is downAPI key invalid: AI API key is wrong or insufficient balance403 Forbidden: Proxy IP is blocked - try a different proxy
The project is already configured to run automatically every day at 8 AM Beijing time by default. If you want to change the time:
-
Click the ".github/workflows" folder on the project homepage
-
Click the "linkedin-job-sniper.yml" file
-
Click the βοΈ pencil icon to edit
-
Find this line:
- cron: '0 0 * * *' # Runs at 00:00 UTC daily
-
Modify to your desired time (uses UTC timezone, 8 hours behind Beijing time)
- For example, to run at 8 AM Beijing time daily, change to:
- cron: '0 0 * * *' # UTC 0:00 = Beijing 08:00
- To run at 10 PM Beijing time daily, change to:
- cron: '0 14 * * *' # UTC 14:00 = Beijing 22:00
- For example, to run at 8 AM Beijing time daily, change to:
-
Click "Commit changes" to save
Time Conversion Tip: Beijing Time - 8 hours = UTC Time
Example: Beijing 20:00 - 8 = UTC 12:00
Common UTC Times:
0 0 * * *= 8:00 AM Beijing / 12:00 AM UTC0 6 * * *= 2:00 PM Beijing / 6:00 AM UTC0 12 * * *= 8:00 PM Beijing / 12:00 PM UTC0 14 * * *= 10:00 PM Beijing / 2:00 PM UTC
If you want to test it on your local machine:
-
Clone the repository
git clone https://github.com/tao-991/LinkedInJobSniper.git cd LinkedInJobSniper -
Install Dependencies
pip install -r requirements.txt
-
Setup Environment Variables Create a
.envfile in the root directory:OPENAI_API_KEY=sk-xxxx API_BASE=https://api.deepseek.com/v1 # Optional EMAIL_SENDER=me@gmail.com EMAIL_PASSWORD=xxxx EMAIL_RECEIVER=me@gmail.com PROXY_URL=http://user:pass@host:port RESUME_TEXT="Paste your resume text here or use resumes/ folder"
-
Add Resume (Optional) Place your resume PDF in a folder named
resumes/(e.g.,resumes/my_cv.pdf). The script will prioritize the file over the environment variable. -
Run
python main.py
You can modify main.py to change search parameters:
SEARCH_TERM = "Software Engineer"
LOCATION = ["Singapore"]
RESULTS_WANTED = 20 # Number of jobs to scrape per run- Initial Release: LinkedIn Job Sniper with Gmail integration.
- Add support for users to enter their job hunting preferences. AI will also consider these preferences when scoring jobs.
- Add support for allowing users to upload their resume files directly.
- Integrate with more job platforms (Indeed, Glassdoor, etc.).
- Add support to more email providers (Outlook, Yahoo, etc.).
This tool is for educational purposes only. Web scraping may violate LinkedIn's User Agreement. Use this tool responsibly and at your own risk. The author is not responsible for any account bans or limitations.
Tao
- Powered by Python, LangChain, and Coffee β.