Skip to content

Track product prices across e-commerce sites and get alerts on price drops.

Notifications You must be signed in to change notification settings

EzraMalik/DealDrop

Repository files navigation

DealDrop - Smart Product Price Tracker

Track product prices across e-commerce sites and get alerts on price drops. Built with Next.js, Firecrawl, and Supabase.

🎯 Features

  • πŸ” Track Any Product - Works with Amazon, Zara, Walmart, and more
  • πŸ“Š Price History Charts - Interactive graphs showing price trends over time
  • πŸ” Google Authentication - Secure sign-in with Google OAuth
  • πŸ”„ Automated Daily Checks - Scheduled cron jobs check prices automatically
  • πŸ“§ Email Alerts - Get notified when prices drop via Resend

πŸ› οΈ Tech Stack

  • Next.js 16 - React framework with App Router
  • Firecrawl - Web data extraction API
    • Handles JavaScript rendering
    • Rotating proxies & anti-bot bypass
    • Structured data extraction with AI
    • Works across different e-commerce sites
  • Supabase - Backend platform
    • PostgreSQL Database
    • Google Authentication
    • Row Level Security (RLS)
    • pg_cron for scheduled jobs
  • Resend - Transactional emails
  • shadcn/ui - UI component library
  • Recharts - Interactive charts
  • Tailwind CSS - Styling

πŸ“‹ Prerequisites

Before you begin, ensure you have:

πŸš€ Setup Instructions

1. Clone and Install

git clone https://github.com/EzraMalik/DealDrop.git
cd DealDrop
npm install

2. Supabase Setup

Create Project

  1. Create a new project at supabase.com
  2. Wait for the project to be ready

Run Database Migrations

Go to SQL Editor in your Supabase dashboard and run these migrations:

Migration 1: Database Schema (supabase/migrations/001_schema.sql)

-- Enable UUID extension
create extension if not exists "uuid-ossp";

-- Products table
create table products (
  id uuid primary key default uuid_generate_v4(),
  user_id uuid references auth.users(id) on delete cascade not null,
  url text not null,
  name text not null,
  current_price numeric(10,2) not null,
  currency text not null default 'USD',
  image_url text,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

-- Price history table
create table price_history (
  id uuid primary key default uuid_generate_v4(),
  product_id uuid references products(id) on delete cascade not null,
  price numeric(10,2) not null,
  currency text not null,
  checked_at timestamp with time zone default now()
);

-- Add unique constraint for upsert functionality
ALTER TABLE products
ADD CONSTRAINT products_user_url_unique UNIQUE (user_id, url);

-- Enable Row Level Security
alter table products enable row level security;
alter table price_history enable row level security;

-- Policies for products
create policy "Users can view their own products"
  on products for select
  using (auth.uid() = user_id);

create policy "Users can insert their own products"
  on products for insert
  with check (auth.uid() = user_id);

create policy "Users can update their own products"
  on products for update
  using (auth.uid() = user_id);

create policy "Users can delete their own products"
  on products for delete
  using (auth.uid() = user_id);

-- Policies for price_history
create policy "Users can view price history for their products"
  on price_history for select
  using (
    exists (
      select 1 from products
      where products.id = price_history.product_id
      and products.user_id = auth.uid()
    )
  );

-- Indexes for performance
create index products_user_id_idx on products(user_id);
create index price_history_product_id_idx on price_history(product_id);
create index price_history_checked_at_idx on price_history(checked_at desc);

Migration 2: Setup Cron Job (supabase/migrations/002_setup_cron.sql)

-- Enable required extensions
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS pg_net;

-- Create function to trigger price check via HTTP
CREATE OR REPLACE FUNCTION trigger_price_check()
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
  PERFORM net.http_post(
    url := 'https://your-app-url.vercel.app/api/cron/check-prices',
    headers := jsonb_build_object(
      'Content-Type', 'application/json',
      'Authorization', 'Bearer YOUR_CRON_SECRET_HERE'
    )
  );
END;
$$;

-- Schedule cron job to run daily at 9 AM UTC
SELECT cron.schedule(
  'daily-price-check',
  '0 9 * * *',
  'SELECT trigger_price_check();'
);

Note: Update the URL and Authorization Bearer token in the function after deployment.

Enable Google Authentication

  1. Go to Authentication β†’ Providers in Supabase
  2. Enable Google provider
  3. Get OAuth credentials from Google Cloud Console:
    • Create a new project or select existing
    • Enable Google+ API
    • Create OAuth 2.0 credentials
    • Add authorized redirect URI: https://<your-project>.supabase.co/auth/v1/callback
  4. Copy Client ID and Client Secret to Supabase

Get API Credentials

  1. Go to Settings β†’ API
  2. Copy your Project URL
  3. Copy your anon/public key
  4. Copy your service_role key (keep this secret!)

3. Firecrawl Setup

  1. Sign up at firecrawl.dev
  2. Go to dashboard and get your API key

4. Resend Setup

  1. Sign up at resend.com
  2. Get your API key from the dashboard
  3. (Optional) Add and verify your domain for custom email addresses

5. Environment Variables

Create .env.local in the root directory:

# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key

# Firecrawl
FIRECRAWL_API_KEY=your_firecrawl_api_key

# Resend
RESEND_API_KEY=your_resend_api_key
RESEND_FROM_EMAIL=onboarding@resend.dev

# Cron Job Security (generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
CRON_SECRET=your_generated_cron_secret

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

Generate CRON_SECRET:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

6. Run Development Server

npm run dev

Open http://localhost:3000

πŸ“¦ Deployment

Deploy to Vercel

  1. Install Vercel CLI (optional)

    npm install -g vercel
  2. Deploy

    vercel --prod

    Or connect your GitHub repository to Vercel for automatic deployments.

  3. Add Environment Variables in Vercel

    Go to your project settings and add all variables from .env.local:

    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY
    • SUPABASE_SERVICE_ROLE_KEY ⚠️
    • FIRECRAWL_API_KEY
    • RESEND_API_KEY
    • RESEND_FROM_EMAIL
    • CRON_SECRET
    • NEXT_PUBLIC_APP_URL (set to your Vercel URL)
  4. Update Supabase Cron Function

    After deployment, update the cron function with your production URL:

    CREATE OR REPLACE FUNCTION trigger_price_check()
    RETURNS void
    LANGUAGE plpgsql
    SECURITY DEFINER
    AS $$
    BEGIN
      PERFORM net.http_post(
        url := 'https://your-actual-vercel-url.vercel.app/api/cron/check-prices',
        headers := jsonb_build_object(
          'Content-Type', 'application/json',
          'Authorization', 'Bearer your_actual_cron_secret'
        )
      );
    END;
    $$;
  5. Update Google OAuth Redirect URI

    Add your Vercel domain to Google Cloud Console authorized redirect URIs.

πŸ” How It Works

User Flow

  1. User adds product - Paste any e-commerce URL on the homepage
  2. Firecrawl scrapes - Instantly extracts product name, price, currency, and image
  3. Data stored - Product saved to Supabase with Row Level Security
  4. View tracking - See current price and interactive price history chart

Automated Price Checking

  1. Supabase pg_cron - Runs daily at 9 AM UTC
  2. Triggers API endpoint - Makes secure POST request to /api/cron/check-prices
  3. Firecrawl scrapes all products - Updates prices for all tracked products
  4. Updates database - Saves new prices and adds to history if changed
  5. Sends email alerts - Notifies users via Resend when prices drop

Why Firecrawl?

Firecrawl solves the hard problems of web scraping:

  • βœ… JavaScript Rendering - Handles dynamic content loaded via JS
  • βœ… Anti-bot Bypass - Built-in mechanisms to avoid detection
  • βœ… Rotating Proxies - Prevents IP blocking
  • βœ… AI-Powered Extraction - Uses prompts to extract structured data
  • βœ… Multi-site Support - Same code works across different e-commerce platforms
  • βœ… Fast & Reliable - Built for production use

No need to maintain brittle, site-specific scrapers!

πŸ“ Project Structure

dealdrop/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ page.js                         # Landing page with product input
β”‚   β”œβ”€β”€ actions.js                      # Server actions for DB operations
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   └── callback/
β”‚   β”‚       └── route.js                # OAuth callback handler
β”‚   └── api/
β”‚       └── cron/
β”‚           └── check-prices/
β”‚               └── route.js            # Cron endpoint for price checks
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ ui/                             # shadcn/ui components
β”‚   β”œβ”€β”€ AddProductForm.js               # Product URL input with auth modal
β”‚   β”œβ”€β”€ ProductCard.js                  # Product display with chart toggle
β”‚   β”œβ”€β”€ PriceChart.js                   # Recharts price history
β”‚   └── AuthModal.js                    # Google sign-in modal
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ firecrawl.js                    # Firecrawl API integration
β”‚   β”œβ”€β”€ email.js                        # Resend email templates
β”‚   └── utils.js                        # Utility functions
β”œβ”€β”€ utils/
β”‚   └── supabase/
β”‚       β”œβ”€β”€ client.js                   # Browser Supabase client
β”‚       β”œβ”€β”€ server.js                   # Server Supabase client
β”‚       └── middleware.js               # Session refresh middleware
β”œβ”€β”€ supabase/
β”‚   └── migrations/
β”‚       β”œβ”€β”€ 001_schema.sql              # Database tables & RLS
β”‚       └── 002_setup_cron.sql          # Cron job setup
β”œβ”€β”€ proxy.ts                            # Next.js 15 proxy (replaces middleware)
└── .env.local                          # Environment variables

Email Template

Customize the email template in lib/email.js - modify HTML, styling, or content.

Add More Product Data

Update the Firecrawl prompt in lib/firecrawl.js to extract additional fields:

prompt: "Extract product name, price, currency, image URL, brand, rating, and availability";

Built with ❀️ by Abdul using Next.js, Firecrawl, and Supabase

About

Track product prices across e-commerce sites and get alerts on price drops.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published