import Fastify from 'fastify'; import dotenv from 'dotenv'; import fastifyFormBody from '@fastify/formbody'; import fastifyWs from '@fastify/websocket'; import { RealtimeAgent, RealtimeSession } from '@openai/agents/realtime'; import { TwilioRealtimeTransportLayer } from '@openai/agents-extensions'; // Load environment variables from .env file dotenv.config(); // Retrieve the OpenAI API key from environment variables. You must have OpenAI Realtime API access. const { OPENAI_API_KEY } = process.env; if (!OPENAI_API_KEY) { console.error('Missing OpenAI API key. Please set it in the .env file.'); process.exit(1); } const PORT = +(process.env.PORT || 5050); // Initialize Fastify const fastify = Fastify(); fastify.register(fastifyFormBody); fastify.register(fastifyWs); const agent = new RealtimeAgent({ name: 'Triage Agent', instructions: 'You are a helpful assistant that starts every conversation with a creative greeting.', }); // Root Route fastify.get('/', async (request, reply) => { reply.send({ message: 'Twilio Media Stream Server is running!' }); }); // Route for Twilio to handle incoming and outgoing calls // punctuation to improve text-to-speech translation fastify.all('/incoming-call', async (request, reply) => { const twimlResponse = ` O.K. you can start talking! `.trim(); reply.type('text/xml').send(twimlResponse); }); // WebSocket route for media-stream fastify.register(async (fastify) => { fastify.get('/media-stream', { websocket: true }, async (connection) => { const twilioTransportLayer = new TwilioRealtimeTransportLayer({ twilioWebSocket: connection, }); const session = new RealtimeSession(agent, { transport: twilioTransportLayer, }); await session.connect({ apiKey: OPENAI_API_KEY, }); console.log('Connected to the OpenAI Realtime API'); }); }); fastify.listen({ port: PORT }, (err) => { if (err) { console.error(err); process.exit(1); } console.log(`Server is listening on port ${PORT}`); }); process.on('SIGINT', () => { fastify.close(); process.exit(0); });