Automate personalized job application emails with resume attachments, status tracking, and analytics — completely free and open source.
- Overview
- Features
- Quick Start
- Setup Guide
- Configuration
- Project Structure
- Deployment
- Security
- Contributing
- License
Job Application Email Automation is a self-hosted tool designed to eliminate the repetitive work of sending job application emails. It allows you to manage a list of recruiter contacts in Excel, attach role-specific resumes, and dispatch personalized emails in bulk — all from a clean web interface or the command line.
No subscriptions. No data sent to third parties. Everything runs on your own machine.
| Category | Capability |
|---|---|
| Email Delivery | Bulk sending with per-recipient personalization |
| Attachments | Role-based resume selection per row |
| Contact Management | Excel-driven workflow with auto status updates |
| Deliverability | Built-in rate limiting to avoid spam filters |
| Templates | Professional, Casual, Formal, and Creative presets |
| Scheduling | Send emails at a configured time |
| Tracking | Timestamped logs for all sent emails |
| Validation | Email address validation before dispatch |
| Analytics | Interactive dashboard for send performance |
| Interface | Web UI with Three.js animations, plus CLI support |
Hosted version (no setup required) https://deepdn.github.io/Job-application-email-automation-/
Docker
git clone https://github.com/DeepDN/Job-application-email-automation-.git
cd Job-application-email-automation-
cp .env.example .env
# Configure credentials in .env
docker-compose up -dOpen http://localhost:5000 in your browser.
This tool uses Gmail App Passwords for secure authentication.
- Enable 2-Step Verification on your Google account
- Navigate to Google Account → Security → App Passwords
- Create a new app password under the "Mail" category
- Copy the generated 16-character password — you will need it in the next step
Your main Google account password is never used or stored.
Create an .xlsx file with the following columns:
| Column | Required | Description |
|---|---|---|
Name |
Yes | Recruiter or HR contact name |
Email |
Yes | Recipient email address |
Company |
Yes | Company name for personalization |
Role |
Yes | Job title being applied for |
Resume |
Yes | PDF filename from the resumes/ folder |
Status |
No | Leave blank — auto-filled as "Sent" |
Example:
| Name | Company | Role | Resume | Status | |
|---|---|---|---|---|---|
| John Smith | john@techcorp.com | TechCorp | DevOps Engineer | resume_devops.pdf | |
| Sarah Lee | sarah@startup.io | StartupIO | Frontend Developer | resume_frontend.pdf |
Place all resume PDFs inside the resumes/ directory. File names must match exactly what is listed in the Excel sheet.
resumes/
├── resume_devops.pdf
├── resume_frontend.pdf
└── resume_data_science.pdf
Edit templates/email_template.html to write your application message. The template supports dynamic variables for name, company, and role.
Copy the example file and fill in your credentials:
cp .env.example .envSECRET_KEY=your-secret-key-change-in-production
GMAIL_EMAIL=your-email@gmail.com
GMAIL_APP_PASSWORD=your-16-character-app-password
DATABASE_URL=postgresql://jobapp:password@db:5432/jobapp_dbclass Config:
SECRET_KEY = 'your-secret-key'
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB upload limitJob-application-email-automation-/
├── app.py # Flask web application
├── email_sender.py # Email sending logic
├── config.py # Configuration settings
├── send_emails.py # Original CLI script
├── build_static.py # Static site generator
├── requirements.txt # Python dependencies
├── templates/
│ ├── index.html # Web interface
│ └── email_template.html # Email template
├── static/
│ └── template.xlsx # Excel template download
├── resumes/ # Your resume files
├── data/ # Excel data files
├── logs/ # Email logs
├── uploads/ # Uploaded files (web)
└── .github/
└── workflows/
└── deploy.yml # GitHub Actions
# Build and start all services
docker-compose up --build -d
# Stream application logs
docker-compose logs -f app
# Stop all services
docker-compose downDatabase management:
# Backup
docker-compose exec db pg_dump -U jobapp jobapp_db > backup.sql
# Restore
docker-compose exec -T db psql -U jobapp jobapp_db < backup.sqlVerify Database:
Check stored data:
docker compose exec db psql -U jobapp -d jobapp_db -c "SELECT * FROM email_log;"Persistent volumes:
| Volume | Purpose |
|---|---|
./uploads |
Uploaded Excel contact files |
./resumes |
Resume PDF files |
./logs |
Application and send logs |
postgres_data |
PostgreSQL database data |
git clone https://github.com/DeepDN/Job-application-email-automation-.git
cd Job-application-email-automation-
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # Configure your credentials
python app.py# After completing local installation above:
# Add your credentials directly in send_emails.py
python send_emails.py| Aspect | Implementation |
|---|---|
| Credential storage | No passwords or emails are ever persisted |
| Data processing | All operations run locally on your machine |
| Authentication | Gmail App Passwords (isolated from your main password) |
| Spam prevention | Configurable rate limiting between sends |
| Transparency | Full source code available for audit |
Pull requests are welcome. For significant changes, please open an issue first to discuss the proposed approach.
Getting started:
git clone +git clone https://github.com/DeepDN/Job-application-email-automation-.git
cd Job-application-email-automation-
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python -m pytest- Fork the repository
- Create a branch:
git checkout -b feature/your-feature-name - Commit your changes with clear messages
- Open a pull request against
main
| Type | Link |
|---|---|
| Bug Reports | GitHub Issues |
| Feature Requests | GitHub Discussions |
Distributed under the MIT License. See LICENSE for full terms.
Developed and maintained by Deepak Nemade (DN)


