railway-backend-index-FIXED

railway-backend-index-FIXED.js is a Fastify-based backend server that orchestrates real-time voice conversations using the OpenAI Realtime API and handles telephony connections via Twilio media streams. It manages user authentication, voice agent configurations, and session persistence, while performing asynchronous contact extraction and conversation summary updates in Supabase. The script serves as the core communication layer between callers, real-time AI logic, and the user management dashboard. For the general repository overview, return to the MeetGabbi Developer Documentation Hub.

Overview

This server integrates several technologies to establish a zero-latency real-time voice assistant:

  • Telephony streaming accepts raw PCM audio streams from Twilio call lines over WebSockets and forwards voice output deltas back to the caller
  • Real-time AI logic connects to OpenAI Realtime API using WebSockets to provide conversational audio with Voice Activity Detection (VAD) and interrupt handling
  • Asynchronous logging persists transcripts, call details, and AI-generated summaries into Supabase without blocking active call streams
  • Multi-user isolation isolates configurations and call histories using custom headers or query parameters for dashboard APIs

How it works

The lifecycle of an incoming call flows through the following stages:

  1. Twilio webhook receives an inbound call at /incoming-call/:agentId? and queries Supabase for the assigned user and agent configuration
  2. TwiML response instructions tell Twilio to open a WebSocket connection containing metadata to the /media-stream/:agentId/:userId? server route
  3. OpenAI session handshake initializes a WebSocket connection to wss://api.openai.com/v1/realtime with custom settings (voice model, VAD threshold, prompts, and tool configurations)
  4. Bidirectional relay pipes audio payloads between the Twilio stream and the OpenAI socket. If the user begins speaking during assistant output, the server issues a truncate command and clears the Twilio output buffer
  5. Function calling processes realtime tool outputs like end_call or save_contact
  6. Graceful cleanup triggers on connection close, prompting Fastify to update the call record and call extractContactFromTranscript() asynchronously to extract structured database entries and generate AI summary details

API

HTTP and WebSocket Endpoints

Endpoint Method Description
/ GET Health check endpoint returning uptime and database user statistics
/health GET System health check reporting uptime and counts of active users and agents
/health/supabase GET Connectivity verification querying contact records in Supabase
/health/dns GET DNS resolution check for Supabase endpoint
/api/phone-numbers GET List assigned phone numbers, agent associations, and call statistics
/api/assign-agent POST Maps a Twilio phone number to a specific agent configuration
/api/unassign-agent POST Disconnects the phone number assignment mapping
/api/update-prompt/:agentId? POST/PUT Modifies the system message prompt, greeting, and speaking order configuration
/api/current-prompt/:agentId? GET Retrieves active system messages and speaking configurations
/api/sync-prompt POST Synchronizes prompt modifications directly into memory database config
/api/update-speaking-order POST Toggles whether the agent or the caller initiates speaking
/api/agents GET/POST Fetch all agent profiles or create a new agent profile
/api/agents/:agentId GET/PUT Retrieve details or update config for a specific agent
/api/calls GET Retrieve list of completed and active calls associated with the user
/api/calls/:callId GET Fetch details and conversation transcript for a specific call ID
/api/calls/:callId/transcript GET Retrieve the text transcript of a specific call
/api/dashboard/stats GET Summary statistics of active calls, agents, and calls per agent
/api/contacts GET Paginated search of database contacts
/api/contacts/:contactId GET/PUT/DELETE Retrieve, update, or delete a specific contact profile
/api/contacts/:contactId/calls GET List historical calls associated with a contact
/incoming-call/:agentId? POST Webhook triggered by Twilio returning TwiML stream connection details
/media-stream/:agentId/:userId? GET (WS) WebSocket connection orchestrating media stream and OpenAI socket interaction

Helper Functions

Function Description
safeSupabaseOperation(operation, operationName, retries) Executes a Supabase database query with retry attempts and exponential backoff
endTwilioCall(callSid, reason) Communicates with the Twilio API client to terminate the active call line
initializeUser(userId) Sets up memory placeholders for new user profiles and agent configurations
getUserAgent(userId, agentId) Fetches the active system prompt and profile details for an agent
updateUserAgent(userId, agentId, updates) Applies updates to agent memory structures and updates timestamp
requireUser(req, reply, next) Fastify pre-handler verifying user identity headers
generateCallId() Computes a unique string prefix used to track call events
calculateConfidence(logprobs) Calculates confidence metric for transcriptions
extractContactFromTranscript(callId, userId, callerNumber) Calls OpenAI Completions API to parse contact details from call logs and saves them
generateCallSummaryForContact(contactId, transcript, extractedInfo, callerNumber, callId) Fires request to Supabase edge function to update contact summaries
createOrUpdateContact(userId, phoneNumber, callId, agentId, metadata) Direct insert or update query handler for contact records
createCallRecord(callId, streamSid, agentId, callerNumber, userId) Commits active call metadata locally and database records asynchronously
updateCallRecord(callId, updates) Marks local call logs complete and updates database entries
saveTranscriptEntry(callId, entry) Logs text dialogue increments into memory storage arrays
calculateDuration(startTime, endTime) Formats duration differences into readable string indicators
reconnectConversationWs(attempt, maxAttempts) Preserves active call context and tries to re-establish dropped OpenAI Realtime WebSocket

Configuration

The server relies on the following environment variables:

Option Type Default Description
PORT number 3000 Port on which Fastify listens
OPENAI_API_KEY string Required API key required to establish connection to OpenAI Realtime endpoints
SUPABASE_URL string Required Base connection URL for database operations
SUPABASE_ANON_KEY string Required Public anonymous key used for Supabase Edge Functions
SUPABASE_SERVICE_ROLE_KEY string Required Secret credentials used for elevated DB privileges
TWILIO_ACCOUNT_SID string Required Identifies Twilio account access permissions
TWILIO_AUTH_TOKEN string Required Authorization key for Twilio API actions
SHOW_TIMING_MATH boolean false Activates verbose logs reporting internal audio latency

Where skills live

This server configuration maps across the following workspace files:

Location Scope
railway-backend-index-FIXED.js Core server implementation containing routes, event handlers, and socket relays
.env Environment configuration container

Usage

Start the Fastify backend server locally:

node railway-backend-index-FIXED.js

Example request to sync a prompt configuration:

const response = await fetch('http://localhost:3000/api/sync-prompt', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    userId: 'user_12345',
    agentId: 'default',
    prompt: 'You are a friendly agent helping with appointment scheduling.',
    speaksFirst: true,
    voice: 'marin'
  })
});
const data = await response.json();
console.log(data.success);

Dependencies

  • fastify — core framework used to listen to HTTP calls and manage API routing
  • ws — creates connections to OpenAI WebSocket endpoints and handles standard socket actions
  • dotenv — parses local file properties into node environment context variables
  • @fastify/formbody — middleware translating form urlencoded inputs from Twilio
  • @fastify/websocket — adds WebSocket routing structures inside Fastify
  • @fastify/cors — controls resource permissions across differing origin requests
  • @supabase/supabase-js — client used to interface with Supabase databases
  • twilio — telephony client utilized to trigger call state closures

Best practices

  • Use safe database wrappers always encapsulate Supabase queries with safeSupabaseOperation retry logic to ensure server errors do not disconnect live voice streams
  • Asynchronous workflow processing defer tasks like transcript database syncs and OpenAI contact parsing until after connections close or run them in parallel without awaiting
  • Resilient socket management handle potential OpenAI WebSocket dropouts by checking states and initiating reconnectConversationWs while preserving state indices
  • Enforce isolated user scopes require authorization headers or query parameters to ensure caller data and configuration details do not overlap
Copied to clipboard!