Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save abdulajet/4659161cb69399d0ab5dc08f4aaef520 to your computer and use it in GitHub Desktop.
Save abdulajet/4659161cb69399d0ab5dc08f4aaef520 to your computer and use it in GitHub Desktop.
import { vcr, Voice, State } from "@vonage/vcr-sdk";
import { Vonage } from "@vonage/server-sdk";
import express from "express";
import OpenAI from 'openai';
import pug from 'pug';
import fs from 'fs';
const app = express();
const port = process.env.VCR_PORT;
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
const languageData = loadLanguageData();
const languages = Object.keys(languageData);
const instanceState = vcr.getInstanceState();
const voiceListener = new Voice(vcr.getGlobalSession());
let currentLanguage = await instanceState.get('language') || "English (United States)";
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static('public'));
await voiceListener.onCall("onCall");
app.get('/_/health', async (req, res) => {
res.sendStatus(200);
});
app.get('/', async (req, res, next) => {
try {
res.send(pug.renderFile('public/index.pug', { number: process.env.VONAGE_NUMBER, languages: languages, currentLanguage: currentLanguage }));
} catch (e) {
next(e);
}
});
app.post('/language', async (req, res) => {
try {
console.log(req.body.language)
await instanceState.set('language', req.body.language);
currentLanguage = req.body.language;
res.redirect('/');
} catch (e) {
next(e);
}
});
app.post('/onCall', async (req, res, next) => {
try {
const session = vcr.createSession();
const state = new State(session);
const voice = new Voice(session);
await state.set('region', req.body.region_url);
await voice.onCallEvent({ vapiID: req.body.uuid, callback: 'onEvent' });
res.json([
{
action: 'talk',
text: languageData[currentLanguage].message,
language: languageData[currentLanguage].code
},
{
action: 'input',
type: ['speech'],
speech: {
language: languageData[currentLanguage].code,
}
}
]);
} catch (e) {
next(e);
}
});
app.post('/onEvent', async (req, res, next) => {
try {
const session = vcr.getSessionFromRequest(req);
const state = new State(session);
const regionUrl = await state.get('region');
if (req.body.hasOwnProperty('speech') && regionUrl) {
if (req.body.speech.hasOwnProperty('error')) {
res.json([
{
action: 'talk',
text: languageData[currentLanguage].error,
language: languageData[currentLanguage].code
},
{
action: 'input',
type: ['speech'],
speech: {
language: languageData[currentLanguage].code,
}
}
]);
} else if (req.body.speech.hasOwnProperty('results')) {
let text = req.body.speech.results[0].text;
if (text) {
generateGPTResponse(regionUrl, req.body.uuid, session, text, currentLanguage);
res.json([
{
action: 'talk',
text: languageData[currentLanguage].hold,
language: languageData[currentLanguage].code
},
{
action: 'stream',
streamUrl: ['https://vids.vonage.com/unifiedAgent/hold.mp3'],
loop: 0,
bargeIn: false
}
]);
}
}
} else {
console.log(req.body);
res.sendStatus(200);
}
} catch (e) {
next(e);
}
});
async function generateGPTResponse(regionUrl, callId, session, text) {
const state = new State(session);
let messages = await state.get('messages');
if (messages) {
messages.push({
role: 'user',
content: text
});
} else {
messages = [
{
role: "system",
content: `You are helpful Assistant, you will get messages in ${currentLanguage}. Only respond in that language.`
},
{
role: 'user',
content: text
}
];
}
const chatCompletion = await openai.chat.completions.create({
model: "gpt-4o",
messages: messages
});
const replyMessage = chatCompletion.choices[0].message;
await messages.push(replyMessage);
await state.set('messages', messages);
const vonage = new Vonage(
{
applicationId: process.env.API_APPLICATION_ID,
privateKey: process.env.PRIVATE_KEY
},
{
apiHost: regionUrl
}
);
await vonage.voice.transferCallWithNCCO(callId, [
{
action: 'talk',
text: `${replyMessage.content}`,
language: languageData[currentLanguage].code
},
{
action: 'input',
type: ['speech'],
speech: {
maxDuration: 60,
language: languageData[currentLanguage].code,
}
}
]);
}
function loadLanguageData() {
const data = fs.readFileSync('./lang.json');
let obj = JSON.parse(data);
return obj;
}
app.listen(port, () => {
console.log(`App listening on port ${port}`)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment