From 46500af21bbc2e780d8e20f2fe309173813657f6 Mon Sep 17 00:00:00 2001 From: localadministrator Date: Mon, 13 Apr 2026 02:14:52 +0000 Subject: [PATCH] Update voiceai-server.js --- voiceai-server.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/voiceai-server.js b/voiceai-server.js index e69de29..bbcf57d 100644 --- a/voiceai-server.js +++ b/voiceai-server.js @@ -0,0 +1,60 @@ +cat > /tmp/server.js << 'ENDOFFILE' +const express = require('express'); +const twilio = require('twilio'); +const axios = require('axios'); +const app = express(); +app.use(express.urlencoded({ extended: true })); +app.use(express.json()); +const PORT = process.env.PORT || 3000; +const AI_NODE = 'http://10.10.0.67:8765'; +const AI_KEY = 'b1ca95570932bd14ae75426095f436912bb88e6b217712f0811e6501c68df465'; +const AI_MODEL = 'llama3.1:70b'; +const conversations = {}; +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 { + const r = await axios.post(AI_NODE+'/queue/add',{prompt,model:AI_MODEL,site:'voiceai',job_type:'text'},{headers:{'x-api-key':AI_KEY},timeout:5000}); + const jobId = r.data.job_id; + console.log('Job submitted:',jobId); + for(let i=0;i<30;i++){ + await new Promise(r=>setTimeout(r,500)); + const j = await axios.get(AI_NODE+'/jobs',{headers:{'x-api-key':AI_KEY},timeout:3000}); + const job = (j.data.jobs||[]).find(x=>x.job_id===jobId); + if(job&&job.status==='done'&&job.result){console.log('AI:',job.result.substring(0,80));return job.result.replace(/```json|```/g,'').trim();} + } + } catch(e){console.error('AI error:',e.message);} + return null; +} +app.post('/voice',async(req,res)=>{ + const sid=req.body.CallSid,to=req.body.To; + const prop=PROPS[to]||PROPS['+12132977880']; + conversations[sid]={prop,history:[]}; + console.log('Call to',to,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'},prop.greeting); + t.hangup(); + res.type('text/xml');res.send(t.toString()); +}); +app.post('/respond',async(req,res)=>{ + const sid=req.body.CallSid,speech=req.body.SpeechResult||''; + const sess=conversations[sid]||{prop:PROPS['+12132977880'],history:[]}; + console.log('Speech:',speech); + sess.history.push({role:'user',content:speech}); + 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); + 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(); + res.type('text/xml');res.send(t.toString()); +}); +app.get('/health',(req,res)=>res.json({status:'online',service:'VoiceAI'})); +app.listen(PORT,'0.0.0.0',()=>console.log('VoiceAI running on port '+PORT)); +ENDOFFILE \ No newline at end of file