I Automated My Job Search and Here's What Happened
As a developer looking for freelance work, I got tired of manually checking 20+ job boards every day. So I built a system to do it for me.
The Problem
I'm a solo developer who does:
- Freelance writing ($80-$150/article)
- Web development ($500-$3000/project)
- Automation consulting ($75/hour)
Finding clients means checking:
- Reddit (r/slavelance, r/forhire, r/hireawriter)
- Twitter (search queries)
- Dev.to (job board)
- LinkedIn (if I had premium)
- Various Slack/Discord communities
- Cold email outreach lists
Time spent daily: 2-3 hours just LOOKING for work.
That's not sustainable. I needed automation.
The System I Built
Architecture
┌─────────────────────────────────────┐
│ Job Aggregator Bot │
│ │
│ ┌──────────┐ ┌────────────────┐ │
│ │ Sources │ │ Parser & │ │
│ │ │──▶│ Normalizer │ │
│ │ • Reddit │ │ │ │
│ │ • Twitter│ │ → Title │ │
│ │ • Dev.to │ │ → Company │ │
│ │ • RSS │ │ → Pay range │ │
│ └──────────┘ │ → Tags │ │
│ └───────┬────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ Scoring Engine│ │
│ │ (relevance × │ │
│ │ pay × recency)│ │
│ └───────┬────────┘ │
│ │ │
│ ┌──────────┼────────┐ │
│ ▼ ▼ ▼ │
│ [Top 10] [Log File] [Alert]│
└─────────────────────────────────────┘
Step 1: Data Collection
Reddit (the hardest part):
// Reddit blocks server IPs, so I use RSS bridges
const REDDIT_RSS = [
'https://rsslounge.com/r/slavelance/.rss',
'https://rsslounge.com/r/forhire/.rss',
'https://rsslounge.com/r/hireawriter/.rss',
];
async function fetchRedditJobs() {
const jobs = [];
for (const url of REDDIT_RSS) {
const feed = await parseRSS(url);
feed.items.forEach(item => {
jobs.push({
source: 'reddit',
title: item.title,
url: item.link,
published: new Date(item.pubDate),
// Extract pay from title if mentioned
pay: extractPay(item.title),
});
});
}
return jobs;
}
Pro tip: Reddit's official API requires OAuth. RSS bridges are a workaround but can be unreliable. The most reliable method? Check Reddit via browser automation during off-peak hours.
Dev.to (much easier):
// Dev.to has a public API, no auth needed for reading
const DEVTO_API = 'https://dev.to/api/articles?tag=hiring&per_page=20';
async function fetchDevToJobs() {
const res = await fetch(DEVTO_API);
const articles = await res.json();
return articles.map(a => ({
source: 'devto',
title: a.title,
url: a.url,
published: a.published_at,
tags: a.tag_list,
}));
}
RSS Feeds (the most reliable):
// Many job boards publish RSS feeds
const RSS_SOURCES = {
'RemoteOK': 'https://remoteok.com/remote-jobs.rss',
'HackerNews': 'https://hnrss.org/frontpage?points=100', // filter by points
'StackOverflow': 'https://stackoverflow.com/jobs/feed',
};
Step 2: Scoring & Ranking
Not all gigs are worth my time. I score each opportunity:
function scoreJob(job) {
let score = 0;
// Relevance to my skills (0-40)
const mySkills = ['nodejs', 'python', 'react', 'writing', 'automation'];
const jobText = (job.title + ' ' + (job.tags || '')).toLowerCase();
mySkills.forEach(skill => {
if (jobText.includes(skill)) score += 8;
});
// Pay estimate (0-30)
if (job.pay >= 100) score += 30; // Good pay
else if (job.pay >= 50) score += 20; // Decent
else if (job.pay > 0) score += 10; // Low but exists
// Recency (0-20)
const hoursOld = (Date.now() - new Date(job.published).getTime()) / 3600000;
if (hoursOld < 2) score += 20;
else if (hoursOld < 6) score += 15;
else if (hoursOld < 24) score += 10;
else if (hoursOld < 48) score += 5;
// Quality signals (0-10)
if (job.title.includes('senior')) score += 3;
if (!job.title.includes('entry') && !job.title.includes('junior')) score += 2;
if (job.source === 'devto') score += 3; // Usually higher quality
return Math.min(score, 100); // Cap at 100
}
Step 3: Delivery
Daily digest email:
async function sendDigest(topJobs) {
const body = topJobs.map((job, i) =>
`${i+1}. **${job.title}** (${job.score}/100)\n` +
` ${job.url}\n` +
` Posted ${getRelativeTime(job.published)}\n` +
` Source: ${job.source}${job.pay ? ' | ~$' + job.pay : ''}`
).join('\n\n');
await resend.emails.send({
from: 'Job Bot <noreply@agentvote.cc>',
to: 'contact@agentvote.cc',
subject: `${topJobs.length} relevant gigs found — ${new Date().toLocaleDateString()}`,
html: markdownToHtml(body),
});
}
Instant alerts for high-value opportunities:
// If something scores >80, alert immediately
if (job.score > 80) {
await sendUrgentAlert(`🔥 HOT GIG: ${job.title}\n${job.url}`);
}
The Results After 30 Days
Numbers:
| Metric | Before | After |
|---|---|---|
| Time spent searching/day | 2-3 hours | 15 minutes |
| Applications sent/week | 3-5 | 12-15 |
| Response rate | 8% | 22% |
| Jobs found total | ~20/week | ~80/week (after filtering: ~10 good ones) |
| Clients landed | 0-1/month | 2/month |
What Changed:
1. Volume → Selectivity
Before automation: I applied to everything because finding gigs was hard.
After automation: I only apply to scored >60 gigs because I know more will come tomorrow.
2. Speed = Advantage
The #1 predictor of getting hired is HOW FAST you apply.
- Manual: See gig → think about it → draft response → apply (2-4 hours later)
- Automated: See gig → alert → apply immediately (within minutes)
I've gotten responses saying "Wow, fast response!" multiple times. Speed signals enthusiasm.
3. Consistency
Some days I don't feel like job hunting. The bot doesn't care. It runs every morning at 7 AM regardless.
What It Can't Do (Yet)
- Write custom cover letters — I still do this myself
- Assess if a client is legit — Some postings are scams
- Negotiate rates — Still a human skill
- Follow up — Working on automated follow-up sequences
The Code
The full system is about 400 lines of Node.js:
- 150 lines: Data collection (RSS, APIs, scraping)
- 100 lines: Scoring engine
- 80 lines: Email delivery
- 70 lines: Scheduling and logging
Runs as a cron job every 6 hours. Costs $0 to operate (uses free tiers of everything).
Setup Your Own
If you want to build something similar:
- Start with ONE source (RSS is easiest)
- Add simple keyword filtering (regex match against your skills)
- Email yourself the results (Resend free tier = 3000 emails/month)
- Iterate: Add sources, improve scoring, add alerts
Don't build the perfect system first. Build a janky one that works, then improve it.
Are you still manually scrolling through job boards? Stop. Automate the boring stuff so you can focus on what actually gets you paid: doing great work.
Follow @armorbreak for more developer productivity content.
Top comments (0)