The LinkedIn bot in action - showing the Easy Apply process with IDE debugging view
- This Bot is based on my earlier LinkedIn Bot
Using only Chrome and Chromedriver (no Firefox):
- Ability to filter jobs by:
- Easy Apply, location (Worldwide, Europe, Poland, etc.), keyword (python, react, node), experience, position, job type, and date posted.
- Apply based on your salary preference (works best for U.S. job offers).
- Automatically apply to single-page jobs requiring just CV and contact.
- Automatically apply to multi-page offers using saved LinkedIn info (experience, legal rights, resume, etc.).
- Output results to data/ text files for later review.
- Print links for jobs the bot couldn't apply to due to extra requirements (for manual follow-up).
- Randomized time breaks between actions to avoid thresholds.
- Automatically runs in the background (headless mode optional).
- Chrome-only, runs based on your preferences in config.py or .env.
- Optional: follow or not follow company after successful application.
There is a tests folder to verify your setup and integration:
python3 tests/setup_tests.py
- Outputs whether Python, pip, selenium, and dotenv are installed.
python3 tests/selenium_test.py
- Verifies Selenium can retrieve data from a website.
python3 tests/LinkedinTest.py
- Tries to log into your LinkedIn account using the
CHROME_PROFILE_PATH
from.env
. - If it errors, ensure the path exists and that you have created and logged in to your LinkedIn account once.
- Tries to log into your LinkedIn account using the
- ChromeDriver
- Create a
.env
from.env.example
and adjust values, or edit config.py directly. - Outputs are written to
data/
.
There are two ways to provide credentials and applicant info.
The recommended approach is to keep secrets outside the repo in a profile directory.
cp .env.example .env
# Then open .env and set at minimum:
# Path where Chrome will store/reuse your session (choose any directory you own)
CHROME_PROFILE_PATH="$HOME/.config/LinkedIn_Apply_Profile"
# Optional if your user-data-dir has multiple sub-profiles (e.g., "Default", "Profile 1")
CHROME_PROFILE_DIR="Default"
# Headless off for visibility (optional)
HEADLESS=false
# You may put credentials here, but prefer the profile credentials file below
LINKEDIN_EMAIL=""
LINKEDIN_PASSWORD=""
- Make the directory if it does not exist and point .env to it via
CHROME_PROFILE_PATH
. - Copy the provided template and fill it in locally (do not commit secrets):
mkdir -p "$HOME/.config/LinkedIn_Apply_Profile"
cp config_forms/credentials.json "$HOME/.config/LinkedIn_Apply_Profile/credentials.json"
- Make sure you succesfully created your config ->
"$HOME/.config/LinikedIN_Apply_Profile/credentials.json
- This is how, and from where your credentials and job search settings are sourced.
- Edit
"$HOME/.config/LinkedIn_Apply_Profile/credentials.json"
and fill the fields you need (all are optional, examples shown as empty strings or booleans): - Optionally, you could code them into
config.py
. Warning, doing so may make it easier to unintentionally share your creds
credentials.json
{
"LINKEDIN_EMAIL": "",
"LINKEDIN_PASSWORD": "",
"PHONE": "",
"RESUME_PATH": "",
"CITY": "",
"STATE": "",
"ZIP": "",
"COUNTRY": "",
"ADDRESS": "",
"PORTFOLIO_URL": "",
"GITHUB_URL": "",
"WEBSITE_URL": "",
"WORK_AUTH": true,
"SPONSORSHIP": false,
"RELOCATE": false,
"EXPECTED_SALARY": "",
"START_DATE": "",
"YEARS_EXPERIENCE": "",
"HEADLESS": false,
"CHROME_PROFILE_DIR": "Default"
}
- The app loads variables in this order, with later sources overriding earlier ones:
- Project
.env
"$CHROME_PROFILE_PATH"/credentials.env
or.env
(if present)"$CHROME_PROFILE_PATH"/credentials.json
- If
CHROME_PROFILE_PATH
points to a specific sub-profile (e.g., ends with "Default" or "Profile 1"), - it is auto-detected; otherwise the default sub-profile "Default" is used, or set
CHROME_PROFILE_DIR
explicitly. - Ensure
RESUME_PATH
points to an existing file if you want automatic resume upload. - Do not commit secrets. Keep them only in your profile directory.
git clone https://github.com/LinuxUser255/LinkedIn_Apply.git
cd LinkedIn_Apply
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python3 tests/setup_tests.py
python3 tests/selenium_test.py
python3 tests/LinkedinTest.py
python3 main.py
- Download the ChromeDriver matching your Chrome version and place it in the root the of the project.
- Headless behavior can be toggled via config.headless or HEADLESS in .env.
Contributions are welcome! Please follow these guidelines:
1. Fork the repository
git clone https://github.com/YOUR_USERNAME/LinkedIn_Apply.git
cd LinkedIn_Apply
2. Create a new branch from dev
for your feature:
git checkout dev
git pull origin dev
git checkout -b feature/your-feature-name
4. Make your changes and test thoroughly & Commit with clear, descriptive messages:
git add .
git commit -m "Add feature: description"
5. Push to your fork:
git push origin feature/your-feature-name
6. Open a Pull Request against the dev
branch (not main
)
- All PRs should target the
dev
branch - The
main
branch is for stable releases only - Follow existing code style and conventions
- Test your changes before submitting
- Update documentation if needed
- Do not commit credentials, secrets, or personal information
Feel free to open an issue for bugs, feature requests, or questions.