Send professional referral-request emails in controlled batches using Gmail SMTP + App Password, with:
- CSV-driven outreach (
Name, Email, Title, Company) - Resume attachment (PDF/DOCX)
- Daily cap (defaults to 50% of personal Gmail daily sending limit)
sent_log.csvto avoid re-sending the same recipient- Template selection (3 variants) + centralized variables (TITLE, LinkedIn, Portfolio, etc.)
This project uses SMTP App Passwords (no OAuth / no Gmail API
credentials.json).
gmail-referral-automation/
├─ src/
│ └─ send_referrals.py
├─ samples/
│ └─ prospects_sample.csv
├─ .gitignore
├─ requirements.txt
└─ README.md
- Python 3.9+
- A Gmail account with 2-Step Verification enabled
- A Gmail App Password (16 characters)
Install dependencies:
pip install -r requirements.txtNavigate to Google Account Security and enable 2-Step Verification:
Create a new app password here:
- In the App name field enter:
Colab SMTP - Copy the 16-character code and store it safely.
- It is a one-time view password.
- If you lose it, you must create a new App Password.
Modify all your personal details in the template section (Template Choice / Title / Name / LinkedIn / Portfolio), otherwise you will be helping me get referrals ✊.
- Personal Gmail commonly has a daily send limit (example: 500 emails/day).
- This project sends 50% by default (example: 250/day) for safety.
Important: Every new day you run the script, attach/keep the same sent_log.csv (or keep it in the repo folder locally) so the same person does not receive multiple emails.
Your CSV must include these columns:
NameEmailTitleCompany
Example file: samples/prospects_sample.csv
Provide a file path to your resume:
resume.pdforresume.docx
The script attaches this resume to every email.
Inside src/send_referrals.py, you can edit:
TITLE(the role you want referral for)YOUR_NAMELINKEDINPORTFOLIOTEMPLATE_CHOICE(1/2/3)SKILLS_LINE,STACK_LINE,IMPACT_LINE
These variables control subject/body formatting.
Key controls:
ACCOUNT_TYPE→"gmail"/"workspace_paid"/"workspace_trial"TARGET_FRACTION→ default0.5DRY_RUN→Trueto test without sendingSLEEP_EACH+JITTER→ reduces burst behavior
python src/send_referrals.py --csv samples/prospects_sample.csv --resume ./resume.pdf --from_email yourgmail@gmail.compython src/send_referrals.py --csv samples/prospects_sample.csv --resume ./resume.pdf --from_email yourgmail@gmail.com --dry_run- The script writes/updates
sent_log.csvto track:sentfaileddry_run
It only skips recipients that have status = sent in the log, so dry_run entries won’t block future sending.
✅ DO:
- Keep
sent_log.csvlocal or private - Use App Password (never your regular password)
- Use
.gitignoreto avoid committing sensitive files
❌ DON’T:
- Commit real prospect lists
- Commit your resume
- Commit App Passwords / tokens
These email lists and code are explicitly for improving the chances of getting into a job or getting a referral. Do not misuse anything and do not spam anyone - respect their privacy and opt-out requests.