26 KiB

CloseBot SMS — Definitive Build Plan

Unified app: Twilio native SMS + CloseBot AI bots. One dashboard to rule them all.


1. TECH STACK

Layer Technology Why
Frontend Next.js 14 (App Router) + Tailwind CSS + shadcn/ui Dark-mode-first, server components, fast
Backend Next.js API routes (Edge-compatible) Same deployment, zero CORS
Database SQLite via better-sqlite3 (dev) → Turso/LibSQL (prod) State tracking, conversation history, routing config
Real-time Server-Sent Events (SSE) Live conversation updates on dashboard
SMS Twilio Node SDK (twilio) Send/receive SMS, delivery status
AI Bots CloseBot API (direct HTTP) Webhook Source for inbound, API for bots/leads/metrics
Auth NextAuth.js with credentials provider Simple login, protect all routes
Deploy Railway / Fly.io / Vercel Needs persistent process for webhooks

2. SYSTEM ARCHITECTURE

┌─────────────┐     ┌──────────────────────────┐     ┌─────────────┐
│   Customer   │────>│     Twilio (SMS)          │────>│  CloseBot   │
│   Phone      │<────│                          │<────│  SMS App    │
└─────────────┘     └──────────────────────────┘     └──────┬──────┘
                                                            │
                    ┌──────────────────────────┐            │
                    │   CloseBot API           │<───────────┘
                    │   (Webhook Source)        │────────────┐
                    └──────────────────────────┘            │
                                                            v
                                                    ┌──────────────┐
                                                    │   SQLite DB   │
                                                    │  (state/logs) │
                                                    └──────────────┘

Message Flow — Inbound:

  1. Customer sends SMS to Twilio number
  2. Twilio POSTs to POST /api/webhooks/twilio/inbound
  3. App looks up routing: which Twilio number → which CloseBot bot/source
  4. App sends inbound event to CloseBot via POST /webhook/event/{sourceId} with:
    • type: "message"
    • contactId (phone number as unique identifier)
    • message (SMS body)
    • state (JSON: { twilioNumber, phoneFrom, messageSid })
  5. CloseBot processes through bot flow
  6. CloseBot POSTs response to our webhook retrieval URL: POST /api/webhooks/closebot/response
  7. App receives response, extracts state to get the Twilio number + customer phone
  8. App sends SMS via Twilio API
  9. App logs everything to SQLite + broadcasts via SSE for live dashboard

Message Flow — Manual Override (from Conversations view):

  1. User types message in the conversation UI
  2. App sends SMS directly via Twilio (bypassing CloseBot)
  3. Logs to SQLite with source: "manual" flag

3. DATABASE SCHEMA

-- Routes: Twilio number → CloseBot bot mapping
CREATE TABLE routes (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  twilio_number TEXT NOT NULL UNIQUE,
  twilio_number_sid TEXT,
  closebot_source_id TEXT NOT NULL,
  closebot_bot_id TEXT,
  bot_name TEXT,
  greeting_message TEXT,
  after_hours_reply TEXT,
  business_hours_json TEXT, -- {"mon": {"start": "09:00", "end": "17:00"}, ...}
  max_concurrent INTEGER DEFAULT 50,
  active BOOLEAN DEFAULT TRUE,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Contacts: phone numbers we've interacted with
CREATE TABLE contacts (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  phone TEXT NOT NULL UNIQUE,
  name TEXT,
  email TEXT,
  status TEXT DEFAULT 'new', -- new, active, qualified, booked, closed, cold
  closebot_lead_id TEXT,
  assigned_bot_id TEXT,
  assigned_route_id TEXT REFERENCES routes(id),
  tags TEXT, -- JSON array
  fields_json TEXT, -- collected fields from CloseBot
  first_contact DATETIME DEFAULT CURRENT_TIMESTAMP,
  last_contact DATETIME DEFAULT CURRENT_TIMESTAMP,
  message_count INTEGER DEFAULT 0
);

-- Messages: every SMS in/out
CREATE TABLE messages (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  contact_id TEXT REFERENCES contacts(id),
  route_id TEXT REFERENCES routes(id),
  direction TEXT NOT NULL, -- 'inbound' | 'outbound'
  source TEXT NOT NULL, -- 'customer' | 'bot' | 'manual'
  body TEXT NOT NULL,
  twilio_sid TEXT,
  twilio_status TEXT, -- queued, sent, delivered, failed, undelivered
  closebot_message_id TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Settings: app-wide config
CREATE TABLE settings (
  key TEXT PRIMARY KEY,
  value TEXT NOT NULL,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Events: activity log for dashboard feed
CREATE TABLE events (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  type TEXT NOT NULL, -- 'message_in', 'message_out', 'booking', 'new_lead', 'status_change'
  contact_id TEXT REFERENCES contacts(id),
  route_id TEXT REFERENCES routes(id),
  data_json TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

4. API ROUTES

Webhook Endpoints (public, Twilio/CloseBot call these)

Route Method Purpose
/api/webhooks/twilio/inbound POST Receive inbound SMS from Twilio
/api/webhooks/twilio/status POST Receive delivery status updates
/api/webhooks/closebot/response POST Receive CloseBot bot responses

Internal API (authenticated, frontend calls these)

Route Method Purpose
/api/dashboard/stats GET Active convos, messages today, bookings, response rate
/api/dashboard/activity GET Recent activity feed (SSE endpoint)
/api/conversations GET List conversations with pagination/filters
/api/conversations/[contactId] GET Get single conversation with messages
/api/conversations/[contactId]/send POST Send manual SMS message
/api/bots GET List CloseBot bots (proxied from CloseBot API)
/api/bots/[id] GET Get bot details + metrics
/api/contacts GET List/search contacts with filters
/api/contacts/[id] GET/PUT/DELETE Contact CRUD
/api/contacts/export GET Export CSV
/api/analytics/overview GET Summary metrics with date range
/api/analytics/messages GET Message volume time series
/api/analytics/bots GET Per-bot conversation counts
/api/analytics/outcomes GET Outcome distribution
/api/analytics/leaderboard GET Top performing bots
/api/routes GET/POST List routes, create new route
/api/routes/[id] GET/PUT/DELETE Route CRUD
/api/settings GET/PUT App settings (Twilio creds, CloseBot key)
/api/settings/test-connection POST Test Twilio + CloseBot connections

5. PAGE-BY-PAGE UI SPEC

5A. DASHBOARD (/)

Matches mockup: closebot-sms-dashboard.png

Layout:

  • Left sidebar (240px): Logo "CloseBot SMS" + 6 nav items with icons
  • Top bar: Global search input
  • Main content area

Components:

  1. Stat Cards Row — 4 cards in a grid

    • Active Conversations (chat bubble icon, count from DB)
    • Messages Today (envelope icon, count from DB where date = today)
    • Bookings Made (calendar icon, from CloseBot metrics API)
    • Response Rate (trending icon, calculated: bot_responses / inbound_messages * 100)
    • Each card: dark glass-morphism background (bg-slate-800/50 backdrop-blur), cyan border glow, icon top-left, label + big number
  2. Real-time Activity Table

    • Columns: SMS (phone number), Bot Name, Badges (status pill), Timestamp
    • Status pills: active (green), pending (yellow), closed (gray)
    • Auto-updates via SSE — new rows slide in at top
    • Click row → navigate to conversation

Data sources:

  • Stats: GET /api/dashboard/stats → queries SQLite counts
  • Activity: GET /api/dashboard/activity → SSE stream from events table

5B. CONVERSATIONS (/conversations)

Matches mockup: closebot-sms-conversations.png

Layout: Two-panel split (left 380px list, right flexible chat)

Left Panel — Conversation List:

  • Search bar with filter icon + settings icon
  • "All Filters" dropdown (by status, bot, date range)
  • Conversation rows: avatar (generated from initials), name, phone, last message preview (truncated), timestamp, unread badge (cyan circle with count)
  • Selected conversation highlighted with left cyan border
  • Sorted by most recent message

Right Panel — Chat Thread:

  • Header: avatar, name, phone number, "CloseBot SMS AI" badge, status dot + "Active" label
  • Message bubbles:
    • Inbound (customer): dark gray background (bg-slate-700), left-aligned with avatar
    • Outbound (bot): cyan/blue gradient background, right-aligned
    • Each bubble shows text, no timestamps on individual messages (clean look)
  • Bottom: text input "Type a message..." with cyan send button
    • Sending from here = manual override, bypasses CloseBot

Data sources:

  • List: GET /api/conversations?search=&status=&bot=&page=
  • Messages: GET /api/conversations/[contactId]
  • Send: POST /api/conversations/[contactId]/send
  • Live updates: SSE for new messages appended to thread

5C. BOTS (/bots)

Matches mockup: closebot-sms-bots.png

Layout: Grid of bot cards (3 columns on desktop)

Top Bar:

  • "Bot Management" heading
  • Search bots input + filter icon + sort icon
  • "+ Create New Bot" button (cyan, calls CloseBot create_bot_with_ai)

Bot Cards:

  • Card header: bot name in bold, gradient top border (different colors per bot)
  • Fields: Status toggle (Active/Inactive), Twilio # (from route mapping), Messages count, Conversion % (from CloseBot metrics), Last Active
  • Inactive bots appear dimmed/grayed
  • Click expand chevron → expanded card shows:
    • Connected Sources list
    • Recent Performance sparkline (mini chart, last 7 days)
    • "Edit Flow" button (opens CloseBot dashboard in new tab)

Data sources:

  • Bots list: GET /api/bots → proxies CloseBot GET /bot + merges route data from SQLite
  • Metrics: CloseBot GET /botMetric/agencySummary
  • Toggle active: PUT /api/routes/[id] to enable/disable route

5D. CONTACTS (/contacts)

Matches mockup: closebot-sms-contacts.png

Layout: Full-width data table with optional slide-out detail panel

Top Bar:

  • Search input
  • Filter dropdowns: "Filter by Status" (hot/warm/cold/new), "Filter by Bot", date range picker
  • "Import Contacts" button (cyan outline) + "Export CSV" button (cyan outline)

Table Columns:

  • Name (bold)
  • Phone Number
  • Assigned Bot
  • Status (colored dot: red=Hot Lead, orange=Warm, gray=Cold + text label)
  • Messages Exchanged (number)
  • Last Contact (relative time: "2 hours ago", "Yesterday")
  • Tags (colored pills)

Slide-out Detail Panel (on row click):

  • Contact name (large, bold)
  • Phone, Email, Company fields
  • "Conversation Summary" section — AI-generated from CloseBot
    • Bullet points: "Product Interest", "Budget Discussion", etc.
  • "Field Values Collected" — mini table of CloseBot-collected fields (Company Size, Industry, Priority)
  • Action buttons: "View Full History" + "Send Message" (cyan)

Data sources:

  • Table: GET /api/contacts?search=&status=&bot=&dateFrom=&dateTo=&page=&limit=
  • Detail: GET /api/contacts/[id]
  • Export: GET /api/contacts/export → CSV download
  • Import: POST /api/contacts/import (CSV upload, creates contacts + optionally sends first message)

5E. ANALYTICS (/analytics)

Matches mockup: closebot-sms-analytics.png

Layout: Scrollable dashboard with multiple chart sections

Top Bar:

  • "Analytics" heading
  • Tab navigation: Dashboard, Conversations, Bots, Contacts, Settings
  • Date range picker dropdown (top right): "Last 30 Days (Oct 1 - Oct 30, 2024)"

Section 1 — Stat Cards (4 across):

  • Total Conversations (large number + sparkline + % change vs last period)
  • Booking Rate (percentage + sparkline + change)
  • Avg Response Time (duration format "1m 45s" + sparkline + change)
  • Customer Satisfaction (rating "4.8/5" + sparkline + change)
  • Each card has colored gradient background (red→pink, green, blue, purple)

Section 2 — Messages Over Time (full width):

  • Line chart with dual lines: Inbound (blue) vs Outbound (green)
  • X-axis: dates over selected range
  • Y-axis: message count
  • Tooltip on hover showing exact values
  • Chart library: Recharts (React-native, works with Next.js)

Section 3 — Two charts side by side:

  • Left: "Conversations by Bot" — horizontal bar chart with colored bars per bot
  • Right: "Outcome Distribution" — donut chart with segments (Booked 40%, Qualified 30%, Dropped 18%, Pending 12%), total in center

Section 4 — Top Performing Bots:

  • Mini leaderboard table: Rank, Bot Name (with icon), Conversations, Booking Rate, CSAT Score
  • Sorted by booking rate descending

Data sources:

  • Stats: GET /api/analytics/overview?start=&end=
  • Messages chart: GET /api/analytics/messages?start=&end=&resolution=daily
  • By bot: GET /api/analytics/bots?start=&end=
  • Outcomes: GET /api/analytics/outcomes?start=&end=
  • Leaderboard: GET /api/analytics/leaderboard?start=&end=
  • All backed by SQLite queries (message counts, conversation outcomes) + CloseBot metrics API for bookings/CSAT

5F. ROUTING (/routing)

Matches mockup: closebot-sms-routing.png

Layout: Three-column visual routing display

Top Bar:

  • Breadcrumb: "Routing / Phone Number Routing"
  • Top nav tabs: Dashboard, Routing, Bots, Analytics, Settings
  • "+ Add New Route" button (top right)
  • Search bar + filter icon

Three Columns:

  • Left: Twilio Phone Numbers — list of phone number cards with phone icon
  • Center: Routing — animated connection lines (CSS/SVG) linking numbers to bots
  • Right: CloseBot Bots & Sources — bot cards with: name, source badge (WEB_LEAD, EMAIL_INQUIRY, etc.), Active/Paused toggle, message count badge, "Configure" button

Expanded Route Configuration (on Configure click):

  • Modal/drawer overlaying the route:
    • Greeting Message Override (textarea, optional)
    • After-Hours Auto-Reply Text (textarea)
    • Business Hours Schedule — day-of-week toggle grid (Mon-Sun), time range "Mon-Fri: 9:00 AM - 5:00 PM", "Add Exception" link
    • Max Concurrent Conversations — slider (1-100) with current value displayed
    • Save + Close Configuration buttons

Data sources:

  • Routes: GET /api/routes → SQLite routes table
  • Twilio numbers: fetched from Twilio API on settings save, cached
  • Bots: GET /api/bots → CloseBot API
  • Update: PUT /api/routes/[id] with config JSON

5G. SETTINGS (/settings)

Matches mockup: closebot-sms-settings.png

Layout: Two-column card layout

Cards:

  1. Twilio Connection — Account SID input (masked), Auth Token input (masked), "Connection Status" indicator (green dot + "Connected")
  2. CloseBot Connection — API Key input (masked), Webhook Source ID (display), "Connection Status" indicator
  3. Phone Numbers — list of Twilio numbers with assigned bot + toggle switch
  4. Notifications — toggles: Email Alerts, SMS Delivery Failures, New Lead Alerts
  5. Webhook URLs — read-only display of:
    • Inbound URL (the URL you give to Twilio)
    • Response URL (the URL you give to CloseBot Webhook Source)
    • Copy buttons next to each

Data sources:

  • Settings: GET/PUT /api/settings
  • Test: POST /api/settings/test-connection → pings both APIs

6. FILE STRUCTURE

closebot-sms/
├── package.json
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
├── .env.local.example
├── BUILD_PLAN.md
├── README.md
├── prisma/ (or drizzle/)
│   └── schema.sql
├── src/
│   ├── app/
│   │   ├── layout.tsx              # Root layout with sidebar
│   │   ├── page.tsx                # Dashboard
│   │   ├── conversations/
│   │   │   └── page.tsx            # Conversations split view
│   │   ├── bots/
│   │   │   └── page.tsx            # Bot grid
│   │   ├── contacts/
│   │   │   └── page.tsx            # Contacts table
│   │   ├── analytics/
│   │   │   └── page.tsx            # Analytics dashboard
│   │   ├── routing/
│   │   │   └── page.tsx            # Phone number routing
│   │   ├── settings/
│   │   │   └── page.tsx            # Settings/config
│   │   └── api/
│   │       ├── webhooks/
│   │       │   ├── twilio/
│   │       │   │   ├── inbound/route.ts
│   │       │   │   └── status/route.ts
│   │       │   └── closebot/
│   │       │       └── response/route.ts
│   │       ├── dashboard/
│   │       │   ├── stats/route.ts
│   │       │   └── activity/route.ts  # SSE
│   │       ├── conversations/
│   │       │   ├── route.ts
│   │       │   └── [contactId]/
│   │       │       ├── route.ts
│   │       │       └── send/route.ts
│   │       ├── bots/
│   │       │   ├── route.ts
│   │       │   └── [id]/route.ts
│   │       ├── contacts/
│   │       │   ├── route.ts
│   │       │   ├── export/route.ts
│   │       │   └── [id]/route.ts
│   │       ├── analytics/
│   │       │   ├── overview/route.ts
│   │       │   ├── messages/route.ts
│   │       │   ├── bots/route.ts
│   │       │   ├── outcomes/route.ts
│   │       │   └── leaderboard/route.ts
│   │       ├── routes/
│   │       │   ├── route.ts
│   │       │   └── [id]/route.ts
│   │       └── settings/
│   │           ├── route.ts
│   │           └── test-connection/route.ts
│   ├── components/
│   │   ├── layout/
│   │   │   ├── sidebar.tsx
│   │   │   ├── topbar.tsx
│   │   │   └── nav-item.tsx
│   │   ├── dashboard/
│   │   │   ├── stat-card.tsx
│   │   │   └── activity-feed.tsx
│   │   ├── conversations/
│   │   │   ├── conversation-list.tsx
│   │   │   ├── conversation-item.tsx
│   │   │   ├── chat-thread.tsx
│   │   │   ├── message-bubble.tsx
│   │   │   └── chat-input.tsx
│   │   ├── bots/
│   │   │   ├── bot-grid.tsx
│   │   │   └── bot-card.tsx
│   │   ├── contacts/
│   │   │   ├── contacts-table.tsx
│   │   │   ├── contact-detail-panel.tsx
│   │   │   └── contact-filters.tsx
│   │   ├── analytics/
│   │   │   ├── stat-card-sparkline.tsx
│   │   │   ├── messages-chart.tsx
│   │   │   ├── bots-bar-chart.tsx
│   │   │   ├── outcome-donut.tsx
│   │   │   └── bot-leaderboard.tsx
│   │   ├── routing/
│   │   │   ├── routing-view.tsx
│   │   │   ├── phone-number-card.tsx
│   │   │   ├── bot-route-card.tsx
│   │   │   ├── connection-lines.tsx  # SVG animated lines
│   │   │   └── route-config-modal.tsx
│   │   └── settings/
│   │       ├── twilio-card.tsx
│   │       ├── closebot-card.tsx
│   │       ├── phone-numbers-card.tsx
│   │       ├── notifications-card.tsx
│   │       └── webhook-urls-card.tsx
│   ├── lib/
│   │   ├── db.ts                  # SQLite connection + queries
│   │   ├── twilio.ts              # Twilio client wrapper
│   │   ├── closebot.ts            # CloseBot API client (reuse from MCP server)
│   │   ├── sse.ts                 # SSE broadcast utility
│   │   └── utils.ts               # Formatters, helpers
│   └── styles/
│       └── globals.css            # Tailwind base + custom dark theme

7. DESIGN SYSTEM

Colors (from mockups):

--bg-primary: #0f1729;       /* deepest navy */
--bg-secondary: #1a2332;     /* card backgrounds */
--bg-tertiary: #1e293b;      /* elevated surfaces */
--bg-hover: #2d3748;         /* table row hover */
--text-primary: #e2e8f0;     /* main text */
--text-secondary: #94a3b8;   /* muted text */
--text-muted: #64748b;       /* timestamps, labels */
--accent-cyan: #22d3ee;      /* primary accent */
--accent-blue: #3b82f6;      /* secondary accent */
--accent-green: #22c55e;     /* success, active */
--accent-yellow: #eab308;    /* warning, pending */
--accent-red: #ef4444;       /* error, hot lead */
--accent-orange: #f97316;    /* warm */
--accent-purple: #a855f7;    /* bot cards */
--border: #334155;           /* subtle borders */
--border-glow: rgba(34, 211, 238, 0.2); /* cyan card glow */

Typography:

  • Font: Inter (system-ui fallback)
  • Headings: 600-700 weight
  • Body: 400 weight
  • Monospace numbers: font-variant-numeric: tabular-nums

Card Style:

.card {
  background: rgba(30, 41, 59, 0.5);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(51, 65, 85, 0.5);
  border-radius: 12px;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
}

Status Badges:

  • Active: bg-green-500/20 text-green-400 border-green-500/30
  • Pending: bg-yellow-500/20 text-yellow-400 border-yellow-500/30
  • Closed: bg-gray-500/20 text-gray-400 border-gray-500/30

8. BUILD PHASES

Phase 1 — Foundation (Day 1)

  • Next.js project scaffold with Tailwind + shadcn/ui
  • SQLite schema + db.ts with all queries
  • Global layout with sidebar navigation (matches dashboard mockup)
  • Dark theme CSS variables
  • Environment config (.env.local)
  • Twilio client wrapper
  • CloseBot API client (port from closebot-mcp)

Phase 2 — Core Webhook Bridge (Day 1-2)

  • POST /api/webhooks/twilio/inbound — receive SMS, forward to CloseBot
  • POST /api/webhooks/closebot/response — receive bot reply, send via Twilio
  • POST /api/webhooks/twilio/status — delivery status updates
  • Contact auto-creation on first inbound
  • Message logging to SQLite
  • Route lookup logic (Twilio number → CloseBot source)
  • Business hours check + after-hours auto-reply
  • State passthrough (phone + route info in CloseBot state field)

Phase 3 — Dashboard + Real-time (Day 2)

  • Dashboard page with 4 stat cards
  • Real-time activity feed (SSE)
  • Activity table with status badges
  • Auto-refresh stats

Phase 4 — Conversations (Day 2-3)

  • Conversation list with search/filter
  • Chat thread with message bubbles
  • Manual message send
  • Unread badges
  • Live message updates via SSE

Phase 5 — Bots + Contacts (Day 3)

  • Bot grid with cards from CloseBot API
  • Bot status toggle (enable/disable route)
  • Contacts table with all filters
  • Slide-out detail panel
  • CSV export

Phase 6 — Analytics (Day 3-4)

  • Stat cards with sparklines
  • Messages over time chart (Recharts)
  • Conversations by bot bar chart
  • Outcome distribution donut chart
  • Bot leaderboard table
  • Date range picker

Phase 7 — Routing + Settings (Day 4)

  • Phone number routing view with visual connections
  • Route config modal (business hours, greeting, max concurrent)
  • Settings page with credential cards
  • Connection testing
  • Webhook URL display with copy

Phase 8 — Polish (Day 4-5)

  • Loading states + skeletons
  • Error handling + toast notifications
  • Mobile responsive adjustments
  • Auth gate (simple login)
  • README with deploy instructions

9. EXTERNAL DEPENDENCIES

npm packages:

{
  "dependencies": {
    "next": "^14.2",
    "react": "^18.3",
    "twilio": "^5.0",
    "better-sqlite3": "^11.0",
    "recharts": "^2.12",
    "lucide-react": "^0.400",
    "@radix-ui/react-dialog": "^1.0",
    "@radix-ui/react-dropdown-menu": "^2.0",
    "@radix-ui/react-toggle": "^1.0",
    "@radix-ui/react-slider": "^1.0",
    "class-variance-authority": "^0.7",
    "clsx": "^2.1",
    "tailwind-merge": "^2.3",
    "next-auth": "^4.24"
  }
}

Environment Variables:

# Twilio
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# CloseBot
CLOSEBOT_API_KEY=cb_xxxxxxxxxxxxxxxx

# App
NEXTAUTH_SECRET=random-secret-here
NEXTAUTH_URL=https://your-domain.com
APP_URL=https://your-domain.com  # Used to construct webhook URLs

# Database
DATABASE_PATH=./data/closebot-sms.db

10. WHAT MAKES THIS DIFFERENT

  1. No GHL required — CloseBot's Webhook Source is the channel, Twilio is the pipe
  2. Multi-tenant ready — one app, many Twilio numbers, many bots
  3. Human takeover — click into any convo and type a manual reply
  4. Business hours built-in — auto-reply after hours, resume bot in morning
  5. Full audit trail — every message logged with direction, source, status
  6. Real-time everything — SSE for live dashboard, no polling
  7. CloseBot metrics integrated — booking rates, leaderboards, CSAT from their API
  8. $0.0079/SMS — Twilio pricing, no GHL middleman markup

Plan version: 1.0 | Last updated: 2026-02-06