Skip to content

connyay/redballmarketglobal.us

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Red Ball Market Global (RBMG) - Hold Music Hotline

A fictional company website with an infinite hold music phone line, powered by Cloudflare Workers, D1 Database, and Twilio. Features privacy-preserving call analytics with HMAC-SHA256 hashed phone numbers.

What is this?

This is a parody project that creates a professional-looking corporate website for the fictional "Red Ball Market Global" company (based on The Chair Company on HBO). When visitors call the phone number, they're greeted with a corporate hold message and infinite hold music. The system tracks all calls with privacy-preserving analytics.

Features

  • 🎭 Fictional Corporate Website: Replica of the RBMG website with professional design
  • πŸ“ž Twilio Integration: Real phone number that plays infinite hold music
  • πŸ”’ Privacy-Preserving Analytics: Phone numbers are hashed using HMAC-SHA256 with secret key - never stored in plain text
  • πŸ“Š Call Tracking:
    • Longest single hold time
    • Most persistent caller (most calls)
    • Total time champion
    • Geographic statistics by state/city
    • Recent calls list
  • ☁️ Cloudflare Stack:
    • Workers for serverless compute
    • D1 Database for SQL storage
    • Static Assets for the website

Privacy Implementation

Phone numbers are never stored in the database. Instead:

  • Full number is hashed with HMAC-SHA256 using a secret key for unique identification
  • Rainbow table attacks are prevented by the secret key
  • Display shows area code + hash: (224) A3B4
  • Geographic data (city/state) is preserved from Twilio
  • See PRIVACY.md for full details

Tech Stack

  • Frontend: Vanilla HTML/CSS/JavaScript
  • Backend: Cloudflare Workers (TypeScript)
  • Database: Cloudflare D1 (SQLite)
  • Telephony: Twilio Voice API
  • Deployment: Cloudflare Workers Platform

Project Structure

rbmg/
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ index.html          # Main website
β”‚   β”œβ”€β”€ styles.css          # Website styling
β”‚   β”œβ”€β”€ app.js              # Frontend analytics
β”‚   └── please-hold.mp3     # Hold music file
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts            # Worker main entry point
β”‚   └── utils.ts            # Phone number hashing utilities
β”œβ”€β”€ migrations/
β”‚   └── 0001_init.sql       # Database schema
β”œβ”€β”€ DEPLOYMENT.md           # Detailed deployment guide
β”œβ”€β”€ PRIVACY.md              # Privacy implementation details
└── wrangler.json           # Cloudflare Worker config

Quick Start

Prerequisites

Local Development

  1. Install dependencies

    npm install
  2. Set up environment variables

    Create a .dev.vars file (don't commit this):

    # Generate a secret key
    openssl rand -hex 32

    Add to .dev.vars:

    PHONE_HASH_SECRET=your_generated_secret_here
    
  3. Apply database migrations locally

    npm run seedLocalD1
  4. Start local dev server

    npm run dev
  5. Visit http://localhost:8787 to see the website

Deployment

See DEPLOYMENT.md for complete deployment instructions including:

  • Deploying to Cloudflare
  • Setting up Twilio phone number
  • Configuring webhooks
  • Environment variables

Quick deploy:

# Deploy to Cloudflare
npm run deploy

# Apply migrations to production
npm run predeploy

# Set phone hash secret (REQUIRED)
openssl rand -hex 32  # Generate a secret
wrangler secret put PHONE_HASH_SECRET

# Set Twilio Auth Token for request validation (recommended)
wrangler secret put TWILIO_AUTH_TOKEN

# (Optional) Set worker URL if needed for MP3 file
wrangler secret put WORKER_URL

API Endpoints

Website

  • GET / - Main website
  • GET /please-hold.mp3 - Hold music file

Analytics API

  • GET /api/analytics - Get call analytics data

Twilio Webhooks

  • POST /twilio/voice - Incoming call webhook (returns TwiML)
  • POST /twilio/status - Call status callback (tracks call completion)

Database Schema

CREATE TABLE calls (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    call_sid TEXT UNIQUE NOT NULL,
    from_number TEXT NOT NULL,         -- HMAC-SHA256 hash
    from_number_hash TEXT,             -- HMAC-SHA256 hash (duplicate for views)
    from_number_display TEXT,          -- Display format: (224) A3B4
    from_area_code TEXT,               -- First 3 digits
    to_number TEXT,                    -- Your Twilio number
    start_time DATETIME NOT NULL,
    end_time DATETIME,
    duration_seconds INTEGER,
    status TEXT NOT NULL,
    city TEXT,                         -- From Twilio
    state TEXT,                        -- From Twilio
    country TEXT,                      -- From Twilio
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Includes pre-built views for analytics:

  • longest_single_hold - Top 10 longest hold times
  • most_calls - Most frequent callers
  • most_time_overall - Total time champions
  • geographic_stats - Calls by location

Customization

Change Hold Music

Replace public/please-hold.mp3 with your own file and redeploy.

Modify Hold Message

Edit the <Say> element in src/index.ts (handleTwilioVoiceWebhook function):

<Say voice="joey" language="en-US">
    Your custom message here
</Say>

Update Website

Edit files in public/:

  • index.html - Structure
  • styles.css - Styling
  • app.js - Frontend logic

Scripts

npm run dev          # Start local development server
npm run check        # TypeScript check + dry-run deploy
npm run deploy       # Deploy to Cloudflare
npm run predeploy    # Apply DB migrations to production
npm run seedLocalD1  # Apply DB migrations locally
npm run cf-typegen   # Generate TypeScript types

Cost Estimate

  • Cloudflare Workers: Free tier (100,000 requests/day)
  • Cloudflare D1: Free tier (5GB storage, 5M reads/day)
  • Twilio: ~$1/month for phone number + per-minute charges for calls

The twilio costs will soon bankrupt me. I gotta figure out how to make money on this. It’s simply too good.

Security & Privacy

  • Request Validation: Twilio webhook requests are validated using HMAC-SHA1 signatures (when TWILIO_AUTH_TOKEN is set)
  • Phone Number Privacy: Phone numbers are hashed with HMAC-SHA256 using a secret key before storage
  • Rainbow Table Resistant: Secret key prevents pre-computed rainbow table attacks
  • No PII: No personally identifiable information is stored in plain text
  • Geographic Data: City/state/country from Twilio is preserved for analytics
  • GDPR/CCPA: Suitable for compliance with privacy regulations
  • See PRIVACY.md for details

License

MIT - This is a parody/joke project. RBMG is a fictional company.

Acknowledgments