@loop/call-booking — Video Call Scheduling Service
Lightweight Hono-based service managing video consultation scheduling, Stream.io integration, and expert call coordination. Handles Calendly webhooks and provides API endpoints for call management.
Purpose
The call-booking service orchestrates video consultations between Loop customers and experts:
Core Functions
- Calendly Integration: Process booking webhooks and sync appointments
- Stream.io Setup: Generate video tokens and configure call rooms
- Expert Coordination: Match customers with appropriate experts
- Call State Management: Track call lifecycle (scheduled, in-progress, completed)
- Recording Management: Store and retrieve consultation recordings
Use Cases
- Customer books consultation via Calendly → webhook creates call record
- Customer joins call → service generates Stream.io token
- Expert views upcoming calls → service returns schedule with customer context
- Call ends → service processes recording and updates call state
Decouples video consultation logic from main apps, allowing independent scaling and deployment.
Architecture
Route Structure
API Routes (src/routes/)
POST /api/v1/calls— Create call record (from Calendly webhook)GET /api/v1/calls/:id— Get call detailsPOST /api/v1/calls/:id/token— Generate Stream.io token for participantGET /api/v1/calls/upcoming— List upcoming calls for expertPOST /api/v1/calls/:id/complete— Mark call as completedGET /api/v1/experts— List available experts and availabilityGET /api/health— Health check endpoint
Webhook Routes (src/webhooks/)
POST /webhooks/calendly— Process Calendly booking eventsPOST /webhooks/stream— Process Stream.io call lifecycle events
Key Components
Call Manager (src/services/call-manager.ts)
- Create and update call records
- Match customers with experts
- Query call history and upcoming calls
Token Generator (src/services/token-generator.ts)
- Generate Stream.io video tokens
- Configure call room permissions
- Set up call recording options
Calendly Handler (src/webhooks/calendly-handler.ts)
- Verify Calendly webhook signatures
- Parse booking event data
- Create call records in database
Stream.io Client (src/clients/stream-io.ts)
- Initialize Stream.io Video SDK
- Manage call rooms and participants
- Retrieve call recordings
Key Features
Calendly Integration
- Webhook Processing: Real-time booking event handling
- Event Types: New booking, rescheduled, cancelled
- Custom Questions: Extract customer context from booking form
- Signature Verification: HMAC validation for webhook security
Stream.io Video
- Token Generation: Scoped tokens for call participants
- Call Permissions: Configure host/guest permissions
- Recording: Automatic call recording and storage
- Screen Sharing: Enable screen sharing for experts
- Chat: In-call messaging support
Expert Scheduling
- Availability Management: Expert calendar sync
- Smart Matching: Route customers to appropriate experts
- Load Balancing: Distribute calls across available experts
- Timezone Handling: Automatic timezone conversion
Call Lifecycle
- Pre-Call: Reminder emails, preparation instructions
- In-Call: Token generation, connection monitoring
- Post-Call: Recording processing, follow-up scheduling
- Analytics: Call duration, quality metrics, no-show tracking
Tech Stack
- Framework: Hono (lightweight web framework)
- Runtime: Node.js 20+ or Cloudflare Workers
- Database: Supabase PostgreSQL (
calls.*tables) - Video: Stream.io Video SDK
- Scheduling: Calendly API
- Validation: Zod 3.x
- Auth: Clerk JWT verification
Package Dependencies
@loop/core— Result type, error handling, logging, circuit breakers@loop/shared— Zod schemas, types, constants@loop/database— Supabase repositories for calls data@loop/auth— Clerk authentication helpers@loop/hono— Shared Hono middleware (auth, errors, CORS)
Development
Local Setup
# Install dependencies
pnpm install
# Set environment variables
cp apps/call-booking/.env.example apps/call-booking/.env
# Run development server
pnpm --filter @loop/call-booking dev
# Access service at http://localhost:3003Required Environment Variables
# Database
DATABASE_URL=postgresql://...
SUPABASE_URL=https://okjpxbiipeghfhwksoit.supabase.co
SUPABASE_SERVICE_KEY=eyJhbGc...
# Clerk Auth
CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
# Stream.io
STREAM_API_KEY=...
STREAM_SECRET_KEY=...
# Calendly
CALENDLY_API_KEY=...
CALENDLY_WEBHOOK_SECRET=...
# External Services
TRIGGER_DEV_API_KEY=...Testing Webhooks Locally
Use ngrok to expose local server for webhook testing:
# Start ngrok tunnel
ngrok http 3003
# Configure Calendly webhook URL
https://<your-ngrok-id>.ngrok.io/webhooks/calendlyCommands
pnpm dev # Start dev server (port 3003)
pnpm build # Production build
pnpm start # Start production server
pnpm typecheck # Type check
pnpm lint # Lint code
pnpm test # Run testsDeployment
- Platform: Cloudflare Workers (production) or Vercel (fallback)
- Environments:
- Production:
mainbranch → call-booking.loop.health - Staging:
stagingbranch → staging-call-booking.loop.health - Development:
developbranch → dev-call-booking.loop.health
- Production:
- Database: Shared Supabase project (
callsschema) - Edge Runtime: Runs on Cloudflare’s global network
- Auto-Deploy: Push to branch triggers deployment
Webhook Configuration
After deployment, configure webhooks in external services:
Calendly: https://call-booking.loop.health/webhooks/calendly
Stream.io: https://call-booking.loop.health/webhooks/stream
Monitoring
- Health Check:
GET /api/healthreturns service status - Metrics: Call volume, duration, quality scores
- Alerts: Failed webhook processing, token generation errors
- Logs: Structured logs via
@loop/corelogger