Skip to content

Charshawn/Shaker

Repository files navigation

✈️ Flight Deal Scanner

A full-featured flight deal tracking platform with automated scanning, price alerts, and beautiful email notifications.

100% Free - Uses free tiers of Vercel, Supabase, SerpApi, and Gmail.

Platform Status Next.js TypeScript

Features

🌍 Smart Search

  • Multiple origin airports (SFO, SJC, OAK, LAX, etc.)
  • Custom date ranges ("Aug-Sep", "Jan-Mar")
  • Multiple trip lengths (weekend, week, extended)
  • Regional preferences (Europe, Asia, Latin America priority)

💰 Price Tracking

  • Historical price data storage
  • Week-over-week price comparisons
  • Price trend visualization
  • Automatic price drop alerts

📧 Email Notifications

  • Beautiful HTML weekly digests
  • Price drop alerts
  • Top 20 deals grouped by region
  • One-click booking links

🎯 Web Dashboard

  • View all past searches
  • Manual scan triggers
  • Configure preferences
  • Manage price alerts

Tech Stack

  • Frontend: Next.js 16, React 19, Tailwind CSS
  • Backend: Next.js API Routes, TypeScript
  • Database: Supabase (Postgres)
  • Flight Data: SerpApi (Google Flights)
  • Email: Gmail SMTP / Nodemailer
  • Deployment: Vercel
  • Cron: Vercel Cron Jobs

Cost Breakdown

Service Free Tier Usage Monthly Cost
Vercel Hobby Plan Hosting + Cron $0
Supabase Free Plan 500MB DB, 50MB storage $0
SerpApi 100 searches/month ~48 searches/month $0
Gmail SMTP Unlimited Email sending $0
Total $0

Setup Instructions

1. Prerequisites

  • Node.js 18+ and npm
  • GitHub account
  • Vercel account (free)
  • Supabase account (free)
  • SerpApi account (free)
  • Gmail account with 2FA enabled

2. Clone and Install

git clone <your-repo-url>
cd flight-deal-scanner
npm install

3. Set Up Supabase

  1. Go to supabase.com and create a new project

  2. Wait for the database to be provisioned

  3. Go to Settings > API and copy:

    • Project URL → NEXT_PUBLIC_SUPABASE_URL
    • anon public key → NEXT_PUBLIC_SUPABASE_ANON_KEY
    • service_role secret key → SUPABASE_SERVICE_ROLE_KEY
  4. Go to SQL Editor and run the migration:

    -- Copy and paste contents from supabase/migrations/001_initial_schema.sql
  5. Update the default email in the migration:

    -- Change 'your.email@gmail.com' to your actual email

4. Get SerpApi Key

  1. Sign up at serpapi.com
  2. Free tier includes 100 searches/month
  3. Copy your API key from the dashboard
  4. Weekly scans from 2 airports with 2 date ranges and 3 trip lengths = ~48 searches/month ✅

5. Set Up Gmail SMTP

  1. Enable 2-Step Verification:

  2. Generate App Password:

6. Configure Environment Variables

# Copy the example file
cp .env.example .env

# Edit .env with your credentials
nano .env

Add your credentials:

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...

# SerpApi
SERPAPI_KEY=your_serpapi_key_here

# Gmail
GMAIL_USER=your.email@gmail.com
GMAIL_APP_PASSWORD=abcd efgh ijkl mnop

# Cron Secret (generate random string)
CRON_SECRET=some_random_secret_string_12345

# App URL
NEXT_PUBLIC_APP_URL=http://localhost:3000

7. Test Locally

npm run dev

Open http://localhost:3000

Test the manual scan:

  1. Go to Dashboard
  2. Click "Run Manual Scan"
  3. Wait 1-2 minutes (searches take time)
  4. You should see flight deals appear

8. Deploy to Vercel

Option A: Using Vercel CLI

npm install -g vercel
vercel login
vercel

Option B: Using GitHub Integration

  1. Push code to GitHub:

    git init
    git add .
    git commit -m "Initial commit"
    git remote add origin <your-repo-url>
    git push -u origin main
  2. Go to vercel.com

  3. Click "New Project"

  4. Import your GitHub repository

  5. Add all environment variables from .env to Vercel project settings

  6. Deploy!

9. Configure Cron Job

The cron job is already configured in vercel.json:

{
  "crons": [{
    "path": "/api/cron",
    "schedule": "0 9 * * 0"
  }]
}

This runs every Sunday at 9 AM (your server time).

Important: Add the CRON_SECRET environment variable to Vercel for security.

To manually trigger the cron (for testing):

curl -X GET https://your-app.vercel.app/api/cron \
  -H "Authorization: Bearer your_cron_secret"

10. Update Preferences

  1. Go to your deployed app
  2. Navigate to Dashboard > Preferences
  3. Update:
    • Your email address
    • Origin airports
    • Max price
    • Date ranges
    • Trip lengths
    • Regional preferences
  4. Click "Save Preferences"

Usage

Weekly Automated Scans

Every Sunday at 9 AM, the system will:

  1. Search flights based on your preferences
  2. Store all deals in Supabase
  3. Check for price drop alerts
  4. Send you a beautiful email digest with top 20 deals

Manual Scans

  1. Go to Dashboard
  2. Click "Run Manual Scan"
  3. Wait for results (1-2 minutes)
  4. View deals immediately

Price Alerts

  1. Go to Dashboard > Price Alerts
  2. Click "+ New Alert"
  3. Enter:
    • Origin (e.g., SFO)
    • Destination Code (e.g., CDG for Paris)
    • Alert Price (e.g., $400)
  4. Get emailed when price drops below threshold

View Search History

  1. Go to Dashboard
  2. Click on any past search in the sidebar
  3. View all flights found in that search
  4. Sorted by region and price

File Structure

flight-deal-scanner/
├── app/
│   ├── api/
│   │   ├── cron/route.ts              # Weekly automated scan
│   │   ├── manual-scan/route.ts       # Manual trigger
│   │   ├── preferences/route.ts       # Get/update preferences
│   │   ├── alerts/route.ts            # Manage price alerts
│   │   └── search-history/route.ts    # Fetch past searches
│   ├── dashboard/
│   │   ├── page.tsx                   # Main dashboard
│   │   ├── preferences/page.tsx       # Settings page
│   │   └── alerts/page.tsx            # Price alerts page
│   ├── page.tsx                       # Landing page
│   ├── layout.tsx                     # Root layout
│   └── globals.css                    # Global styles
├── lib/
│   ├── supabase.ts                    # Supabase client & types
│   ├── flight-scanner.ts              # Core search logic
│   ├── email-service.ts               # Email templates & sender
│   └── price-tracker.ts               # Price history logic
├── supabase/
│   └── migrations/
│       └── 001_initial_schema.sql     # Database schema
├── vercel.json                         # Cron job config
├── .env.example                        # Environment template
├── package.json
├── tsconfig.json
├── tailwind.config.ts
└── README.md

Database Schema

user_preferences - Search configuration

  • origin_airports: ["SFO", "SJC"]
  • date_ranges: [{start: "aug", end: "sep"}]
  • location_preferences: {europe: 1, asia: 2, ...}
  • trip_lengths: [3, 7, 14]
  • max_price: 600

search_runs - Each scan execution

  • run_date, airports_scanned, total_deals_found, status

flight_deals - All discovered flights

  • origin, destination, price, dates, airline, region, etc.

price_alerts - Route price monitoring

  • route, origin, destination_code, threshold_price, is_active

API Endpoints

  • GET /api/cron - Weekly automated scan (triggered by Vercel Cron)
  • POST /api/manual-scan - Trigger manual scan
  • GET /api/preferences - Get user preferences
  • PUT /api/preferences - Update preferences
  • GET /api/alerts - Get all price alerts
  • POST /api/alerts - Create new alert
  • PUT /api/alerts - Update alert
  • DELETE /api/alerts?id=xxx - Delete alert
  • GET /api/search-history - Get recent searches
  • GET /api/search-history?search_run_id=xxx - Get flights for specific search

Customization Ideas

  • Add SMS notifications (Twilio)
  • Support for one-way flights
  • Hotel + flight packages
  • Multi-user support with authentication
  • Price prediction with ML
  • Slack/Discord integration
  • Mobile app (React Native)

Troubleshooting

"No flights found"

  • Check that your max_price isn't too low
  • Verify origin airport codes are correct (3-letter IATA codes)
  • Try increasing date_flexibility_days
  • Check SerpApi dashboard for API usage/errors

"Email not sent"

  • Verify Gmail App Password (not your regular password)
  • Check that 2FA is enabled on Google account
  • Remove spaces from the app password in .env
  • Check Gmail "Less secure app access" is OFF (use App Password instead)

"Cron job not running"

  • Verify CRON_SECRET is set in Vercel environment variables
  • Check Vercel deployment logs for errors
  • Free tier allows only daily cron jobs (weekly is fine)
  • Test manually with curl to the /api/cron endpoint

"Supabase connection failed"

  • Check that all three Supabase env vars are set correctly
  • Verify the migration was run successfully
  • Check Supabase dashboard for connection limits
  • Make sure anon key and service role key aren't swapped

"SerpApi rate limit exceeded"

  • Free tier: 100 searches/month
  • Current usage: ~48/month with default settings
  • Reduce origin airports or date ranges if needed
  • Check usage on SerpApi dashboard

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - Feel free to use for personal or commercial projects.

Support

Acknowledgments


Happy traveling! ✈️🌍

Made with ❤️ for budget-conscious travelers

About

Website

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors