Skip to main content
Glama

Voice Call MCP Server

by popcornspace
event.service.ts3.93 kB
import { WebSocket } from 'ws'; import { CallState } from '../../types.js'; import { LOG_EVENT_TYPES, SHOW_TIMING_MATH } from '../../config/constants.js'; import { checkForGoodbye } from '../../utils/call-utils.js'; /** * Service for processing OpenAI events */ export class OpenAIEventService { private readonly callState: CallState; private readonly onEndCall: () => void; private readonly onSendAudioToTwilio: (payload: string) => void; private readonly onTruncateResponse: () => void; /** * Create a new OpenAI event processor * @param callState The state of the call * @param onEndCall Callback for ending the call * @param onSendAudioToTwilio Callback for sending audio to Twilio * @param onTruncateResponse Callback for truncating the response */ constructor( callState: CallState, onEndCall: () => void, onSendAudioToTwilio: (payload: string) => void, onTruncateResponse: () => void ) { this.callState = callState; this.onEndCall = onEndCall; this.onSendAudioToTwilio = onSendAudioToTwilio; this.onTruncateResponse = onTruncateResponse; } /** * Process an OpenAI message * @param data The message data */ public processMessage(data: WebSocket.Data): void { try { const response = JSON.parse(data.toString()); if (LOG_EVENT_TYPES.includes(response.type)) { // console.log(`Received event: ${response.type}`, response); } this.processEvent(response); } catch (error) { console.error('Error processing OpenAI message:', error, 'Raw message:', data); } } /** * Process an OpenAI event * @param response The event data */ private processEvent(response: any): void { switch (response.type) { case 'conversation.item.input_audio_transcription.completed': this.handleTranscriptionCompleted(response.transcript); break; case 'response.audio_transcript.done': this.handleAudioTranscriptDone(response.transcript); break; case 'response.audio.delta': if (response.delta) { this.handleAudioDelta(response); } break; case 'input_audio_buffer.speech_started': this.onTruncateResponse(); break; } } /** * Handle a transcription completed event * @param transcription The transcription text */ private handleTranscriptionCompleted(transcription: string): void { if (!transcription) { return; } this.callState.conversationHistory.push({ role: 'user', content: transcription }); if (checkForGoodbye(transcription)) { this.onEndCall(); } } /** * Handle an audio transcript done event * @param transcript The transcript text */ private handleAudioTranscriptDone(transcript: string): void { if (!transcript) { return; } this.callState.conversationHistory.push({ role: 'assistant', content: transcript }); } /** * Handle an audio delta event * @param response The event data */ private handleAudioDelta(response: any): void { this.onSendAudioToTwilio(response.delta); if (!this.callState.responseStartTimestampTwilio) { this.callState.responseStartTimestampTwilio = this.callState.latestMediaTimestamp; if (SHOW_TIMING_MATH) { // console.log(`Setting start timestamp for new response: ${this.callState.responseStartTimestampTwilio}ms`); } } if (response.item_id) { this.callState.lastAssistantItemId = response.item_id; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/popcornspace/voice-call-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server