diff --git a/voiceai-server.js b/voiceai-server.js index d3f2e3f..67d9bb4 100644 --- a/voiceai-server.js +++ b/voiceai-server.js @@ -9,6 +9,7 @@ const AI_NODE = 'http://10.10.0.67:8765'; const AI_KEY = 'b1ca95570932bd14ae75426095f436912bb88e6b217712f0811e6501c68df465'; const AI_MODEL = 'deepseek-r1:latest'; const conversations = {}; +const pending = {}; const PROPS = {'+12133547300':{name:'broadcastbeat',greeting:'Thank you for calling Broadcast Beat. How can I help you today?',system:'You are the AI receptionist for Broadcast Beat. Be professional. Under 40 words.'},'+12134182600':{name:'pinkpulse',greeting:'Hey gorgeous! You have reached The Pink Pulse. How can I help you today?',system:'You are the AI receptionist for The Pink Pulse, an LGBTQ+ publication. Be warm and fabulous. Under 40 words.'},'+12136529233':{name:'avbeat',greeting:'Thank you for calling AV Beat. How can I help you today?',system:'You are the AI receptionist for AV Beat. Be professional. Under 40 words.'},'+12132977880':{name:'onsethost',greeting:'Thank you for calling OnSetHost. How can I help you today?',system:'You are the AI receptionist for OnSetHost, web hosting for production professionals. Under 40 words.'}}; async function askAI(prompt) { try { @@ -40,18 +41,42 @@ app.post('/respond',async(req,res)=>{ const sess=conversations[sid]||{prop:PROPS['+12132977880'],history:[]}; console.log('Speech:',speech); sess.history.push({role:'user',content:speech}); + conversations[sid]=sess; const hist=sess.history.map(m=>(m.role==='user'?'Caller':'Assistant')+': '+m.content).join('\n'); const prompt=sess.prop.system+'\n\nConversation:\n'+hist+'\n\nRespond as AI receptionist. Under 40 words. No markdown.'; - let reply=await askAI(prompt); - if(!reply)reply='I apologize for the difficulty. Please try again shortly.'; - sess.history.push({role:'assistant',content:reply}); - conversations[sid]=sess; - console.log('Reply:',reply); + pending[sid]=null; + askAI(prompt).then(reply=>{ + pending[sid]=reply||'I apologize for the difficulty. Please try again shortly.'; + console.log('Reply ready for',sid,':',pending[sid]); + }); const t=new twilio.twiml.VoiceResponse(); - const g=t.gather({input:'speech',action:'https://voice.onsethost.com/respond',method:'POST',speechTimeout:'auto',language:'en-US'}); - g.say({voice:'Polly.Joanna-Neural'},reply); - t.say({voice:'Polly.Joanna-Neural'},'Thank you for calling. Goodbye!'); - t.hangup(); + t.say({voice:'Polly.Joanna-Neural'},'One moment please.'); + t.pause({length:2}); + t.redirect({method:'POST'},'https://voice.onsethost.com/check?sid='+sid+'&attempt=0'); + res.type('text/xml');res.send(t.toString()); +}); +app.post('/check',async(req,res)=>{ + const sid=req.query.sid; + const attempt=parseInt(req.query.attempt)||0; + console.log('Check for',sid,'attempt',attempt,'ready:',pending[sid]!==null&&pending[sid]!==undefined); + const t=new twilio.twiml.VoiceResponse(); + if(pending[sid]){ + const reply=pending[sid]; + const sess=conversations[sid]||{prop:PROPS['+12132977880'],history:[]}; + sess.history.push({role:'assistant',content:reply}); + conversations[sid]=sess; + delete pending[sid]; + const g=t.gather({input:'speech',action:'https://voice.onsethost.com/respond',method:'POST',speechTimeout:'auto',language:'en-US'}); + g.say({voice:'Polly.Joanna-Neural'},reply); + t.say({voice:'Polly.Joanna-Neural'},'Thank you for calling. Goodbye!'); + t.hangup(); + } else if(attempt<20){ + t.pause({length:2}); + t.redirect({method:'POST'},'https://voice.onsethost.com/check?sid='+sid+'&attempt='+(attempt+1)); + } else { + t.say({voice:'Polly.Joanna-Neural'},'I apologize for the delay. Please call back shortly.'); + t.hangup(); + } res.type('text/xml');res.send(t.toString()); }); app.get('/health',(req,res)=>res.json({status:'online',service:'VoiceAI'}));