An AI-powered job application assistant that scrapes job listings from Useme, uses OpenAI to evaluate and generate tailored offers, and sends them automatically — all from a single Next.js dashboard.
- Scrape job listings from Useme based on configured categories and filters
- Verify scraped jobs with AI to determine which ones are worth applying to
- Generate personalised offer texts using OpenAI
- Send offers directly to Useme through browser automation (Puppeteer)
- Dashboard — a web UI to manage the entire pipeline, view jobs, and trigger each step manually
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| UI | PrimeReact + PrimeFlex |
| Database | PostgreSQL via Prisma ORM |
| AI | OpenAI API |
| Scraping | Puppeteer |
| Language | TypeScript |
- Node.js 20+
- PostgreSQL database
- OpenAI API key
- Useme account credentials
git clone https://github.com/Brunoiooo/job-finder.git
cd job-finder
npm installCopy .env.example to .env and fill in your values:
cp .env.example .env| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
OPENAI_API_KEY |
Your OpenAI API key |
OPENAI_API_MODEL |
(optional) Model to use, defaults to gpt-3.5-turbo |
USEME_EMAIL |
Your Useme login email |
USEME_PASSWORD |
Your Useme login password |
USEME_PAYMENT |
Minimum payment threshold (PLN) for job filtering |
USEME_WORK_DAYS |
Estimated delivery days shown in offers |
DEBUG |
(optional) Set to 1 to enable verbose logging |
npx prisma migrate deploy
npx prisma generatenpm run devOpen http://localhost:3000 to access the dashboard.
The dashboard exposes four main actions:
- Scrap Useme — Crawls Useme job categories and saves new listings to the database.
- Verify Offers — Sends each unprocessed job to OpenAI to decide whether it's a good fit (based on your configured prompts).
- Generate Offers — Uses OpenAI to write a personalised application message for every verified job.
- Send Offers — Logs into Useme via Puppeteer and submits the generated offers.
You can also manage per-source prompts and ignore-list rules from the Prompts page (/prompts).
src/
├── app/ # Next.js App Router pages
│ ├── page.tsx # Main dashboard
│ └── prompts/ # Prompt management page
├── actions/ # Next.js Server Actions (one per pipeline step)
├── components/ # React UI components
├── services/
│ ├── scraper/ # Puppeteer-based Useme scraper
│ ├── generateOffer/ # OpenAI offer generation
│ ├── verifyOffer/ # OpenAI job verification
│ └── sendOffer/ # Puppeteer-based offer submission
└── lib/ # Shared utilities
prisma/
└── schema.prisma # Database schema (Job, Prompt, IgnorePrompt, …)
npm run dev # Start development server (Turbopack)
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLintThe main models are:
- Job — a scraped listing with its URL, AI-generated summary, offer text, and send/ignore status.
- Prompt — ordered prompt fragments sent to OpenAI per source (e.g. Useme).
- IgnorePrompt — prompt rules that tell the AI which jobs to skip.
- UsemeCategories — Useme category URLs to scrape.