JobFinder is a Spring Boot application designed to automatically fetch new developer job postings from online job boards and deliver them directly to your WhatsApp.
This project was built to:
- Save time β±οΈ β no more manually checking job boards every day.
- Stay updated π² β receive job alerts instantly via WhatsApp.
- Experiment with AI π€ β integrate OpenAI through Spring AI for summarizing job posts or extracting key info.
- Practice enterprise integration π οΈ β connecting multiple technologies (Spring, Twilio, WhatsApp API, Postgres).
This project also serves as a real-world example of combining AI + messaging + databases in a clean, production-grade setup.
flowchart TB
%% Application entry
Application["JobfinderApplication"]:::config
click Application "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/JobfinderApplication.java"
%% Presentation Layer
subgraph "Presentation Layer"
Controller["JobController"]:::controller
click Controller "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/controller/JobController.java"
end
%% Business Layer
subgraph "Business Layer"
FinderService["JobFinderService"]:::service
click FinderService "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/service/JobFinderService.java"
ScrapingService["WebScrapingService"]:::service
click ScrapingService "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/service/WebScrapingService.java"
AnalysisService["JobAnalysisService"]:::service
click AnalysisService "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/service/JobAnalysisService.java"
WhatsAppService["WhatsAppService"]:::service
click WhatsAppService "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/service/WhatsAppService.java"
end
%% Data Access Layer
subgraph "Data Access Layer"
Repository["JobRepository"]:::repository
click Repository "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/repository/JobRepository.java"
Entity["Job"]:::entity
click Entity "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/entity/Job.java"
DB[(PostgreSQL)]:::db
end
%% Integration Layer
subgraph "Integration Layer"
ChatClient["ChatClient"]:::ai
click ChatClient "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/ai/ChatClient.java"
Prompt["Prompt"]:::ai
click Prompt "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/ai/Prompt.java"
Response["ChatResponse"]:::ai
click Response "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/ai/ChatResponse.java"
Config["OpenApiConfig"]:::config
click Config "https://github.com/seadmustafa/jobfinder/blob/master/src/main/java/com/ai/finder/config/OpenApiConfig.java"
Props["application.properties"]:::config
click Props "https://github.com/seadmustafa/jobfinder/blob/master/src/main/resources/application.properties"
end
%% External Systems
JobBoards["Job Boards"]:::external
OpenAI["OpenAI API"]:::external
TwilioAPI["Twilio WhatsApp API"]:::external
UserWhatsApp["User WhatsApp Client"]:::external
%% Relationships
Application -->|starts| Controller
Controller -->|trigger| FinderService
FinderService -->|scrape| ScrapingService
ScrapingService -->|data| Repository
Repository -->|save/read| DB
FinderService -->|raw data| AnalysisService
AnalysisService -->|build prompt| Prompt
AnalysisService -->|send request| ChatClient
ChatClient -->|call API| OpenAI
OpenAI -->|response| ChatClient
ChatClient -->|return summary| Response
FinderService -->|summary| WhatsAppService
WhatsAppService -->|send message| TwilioAPI
TwilioAPI -->|deliver| UserWhatsApp
Controller -->|docs| Config
%% External connections
ScrapingService -->|fetch| JobBoards
%% Styles
classDef controller fill:#ADD8E6,stroke:#333,stroke-width:1px
classDef service fill:#87CEFA,stroke:#333,stroke-width:1px
classDef repository fill:#FFD580,stroke:#333,stroke-width:1px
classDef entity fill:#FFE4B5,stroke:#333,stroke-width:1px
classDef ai fill:#D8BFD8,stroke:#333,stroke-width:1px
classDef config fill:#D3D3D3,stroke:#333,stroke-width:1px
classDef db fill:#FFA500,stroke:#333,stroke-width:1px,shape:cylinder
classDef external fill:#98FB98,stroke:#333,stroke-width:1px
- Java 17 β Core language
- Spring Boot β Application framework
- Spring AI β OpenAI integration
- Twilio WhatsApp API β WhatsApp messaging
- PostgreSQL β Persistent database for storing job posts
- Maven β Dependency and build management
git clone https://github.com/your-username/jobfinder.git
cd jobfinderCreate a .env file (or export variables in your shell):
# Database
DB_URL=jdbc:postgresql://localhost:5432/jobfinder
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_pass
# OpenAI
OPENAI_API_KEY=sk-xxxx
# Twilio / WhatsApp
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxx
TWILIO_WHATSAPP_FROM=whatsapp:+14155238886
TWILIO_WHATSAPP_TO=whatsapp:+1234567890mvn clean installmvn spring-boot:runThe application will start on http://localhost:8080 .
Make sure Postgres is running and you have a database created:
CREATE DATABASE jobfinder;
Flyway or Hibernate will validate schema on startup.
Secrets are not hardcoded, only injected via environment variables.
.gitignore excludes IDE, build, and secret files (.idea/, target/, .env).
Use ddl-auto=validate in production with migrations via Flyway/Liquibase.
Contributions are welcome! Fork the repo, create a feature branch, and open a pull request.
