Vonage Api Call Function - node.js

Hey I got my code to receive calls but for some reason when I run the script it doesn’t place an out going call. I am not getting no error message or anything it just simply won’t call,But I set up everything right am I missing a trigger or something? Could someone please point me in the right direction I’ve been trying to build this api for about 4 Months.
require('dotenv').config();
const Vonage = require('#vonage/server-sdk');
const express = require('express');
const morgan = require('morgan');
const app = express();
const vonage = new Vonage({
apiKey: process.env.VONAGE_API_KEY,
apiSecret: process.env.VONAGE_API_SECRET,
applicationId: process.env.VONAGE_APPLICATION_ID,
privateKey: process.env.VONAGE_PRIVATE_KEY_PATH
});
app.use(morgan('tiny'));
app.use(express.json());
app.get('/call', (req, res) => {
vonage.calls.create({
to: [{
type: 'phone',
number: process.env.TO_NUMBER
}],
from: {
type: 'phone',
number: process.env.VONAGE_NUMBER,
},
ncco: [{
"action": "talk",
"text": "This is a text to speech call from Vonage"
}]
}, (error, response) => {
if (error) console.error(error)
if (response) console.log(response)
});
res.json('ok');
});
app.post('/event', (req, res) => {
console.log(req.body);
res.status(200).send('');
});
app.post('/answer', (req, res) => {
const number = req.body.from.split('').join(' ');
const ncco = [
{
action: 'talk',
text: 'Thank you for calling from ' + number,
language: 'en-IN',
style: '4'
},
{
action: 'stream',
streamUrl: [
'https://www.albinoblacksheep.com/audio/mp3/RickRollMarioPaint.mp3'
]
}
];
res.json(ncco);
});
app.listen(process.env.PORT, () => console.log(Running on port ${process.env.PORT}));

Related

.send() send an empty body mocha node js

I have an issue with the following code. The mocha .send() function send a body but it's empty when my api.js received it. When I do a request with PostMan it works, but when I use Mocha, it doesn't work.
api.js :
const express = require("express");
const dbConnection = require("../db/mysqlConnector.js");
const router = express();
const Validator = require('validatorjs');
// POST (Create)
router.post("/tasks", async function (req, res) {
try {
let validation = new Validator({
name: req.body.name,
description: req.body.description,
state: req.body.state,
priority: req.body.priority,
created_by: req.body.created_by
}, {
name: 'required|string',
description: 'required|string',
state: 'required|boolean',
priority: 'required|between:1,3',
created_by: 'required:number'
});
if (validation.fails()) { return res.status(400).json(); }
var con = await dbConnection();
await con.query('INSERT INTO `tasks` (name, description, state, priority, created_by) VALUES (?,?,?,?,?)',
[req.body.name, req.body.description, req.body.state, req.body.priority, req.body.created_by], function (error, results, fields) {
con.release();
res.status(201).json();
});
} catch (error) {
console.log(error);
}
});
test.js :
const chai = require("chai");
const request = require("supertest");
const expect = chai.expect;
const api = require("../routes/api.js");
const faker = require("faker");
describe("Tasks", function () {
describe("POST /tasks", function () {
it("should return 201 OK and insert a new task", async function () {
const response = await request(api)
.post("/tasks")
.send({
name: faker.vehicle.vehicle(),
description: faker.lorem.lines(3),
state: faker.datatype.boolean(),
priority: faker.datatype.number({min:1, max:3}),
created_by: faker.datatype.number({min:1, max:10})
})
.expect(201)
});
});
});
Am I missing something ?
Thanks

How to resolve 'system:error:invalid-token' In Nexmo Vonage SDK changing to a new app in the same account

I am using "#vonage/server-sdk": "2.10.7-beta-2" package on server to create users in Vonage.
To create the user, I used this API
const Vonage = require('#vonage/server-sdk');
const v = new Vonage({
apiKey: config.voipConfig.key,
apiSecret: config.voipConfig.secret,
applicationId: config.voipConfig.appId,
privateKey: config.voipConfig.privateKeyPath
};
v.users.create({
"name": payload.username,
"display_name": payload.displayName
}, (error: any, result: any) => {
});
Everything was working fine. But when I created a new application in vonage account and used new configs, it started to throw the following error
{
description: 'You did not provide a valid token. Please provide a valid token.',
code: 'system:error:invalid-token'
}
I have checked the details multiple times and not sure what is wrong.
The new credentials are from completely new account.
Any help would be much appreciated.
Looks like you are using the Vonage Conversations API to create a user. In good practice, we usually use dotenv to store our .env variables. If you are using a public github repo, remember to add *.env to your .gitignore.
npm install dotenv
// .env
API_KEY=
API_SECRET=
APPLICATION_ID=
APPLICATION_PRIVATE_KEY_PATH=
TO_NUMBER=<YOUR CELL NUMBER>
VIRTUAL_NUMBER=<VONAGE VIRTUAL NUMBER>
NGROK_URL=https://<URL>.ngrok.io
For testing purposes. Can you make an outbound call with the snippet below? That'll test your credentials.
Make sure to store the private.key in same directory as .env and outbound-call.js
// outbound-call.js
require("dotenv").config();
const API_KEY = process.env.API_KEY;
const API_SECRET = process.env.API_SECRET;
const APPLICATION_ID = process.env.APPLICATION_ID;
const APPLICATION_PRIVATE_KEY_PATH = process.env.APPLICATION_PRIVATE_KEY_PATH;
const TO_NUMBER = process.env.TO_NUMBER;
const VIRTUAL_NUMBER = process.env.VIRTUAL_NUMBER;
if (!API_KEY || !API_SECRET) {
console.log("🔥 API_KEY or API_SECRET missing");
process.exit(1);
}
if (!APPLICATION_ID || !APPLICATION_PRIVATE_KEY_PATH) {
console.log("🔥 APPLICATION_ID or APPLICATION_PRIVATE_KEY_PATH missing");
process.exit(1);
}
if (!TO_NUMBER || !VIRTUAL_NUMBER) {
console.log("🔥 TO_NUMBER or VIRTUAL_NUMBER missing");
process.exit(1);
}
const Vonage = require("#vonage/server-sdk");
const vonage = new Vonage({
apiKey: API_KEY,
apiSecret: API_SECRET,
applicationId: APPLICATION_ID,
privateKey: APPLICATION_PRIVATE_KEY_PATH,
});
vonage.calls.create({
to: [
{
type: "phone",
number: process.env.TO_NUMBER,
},
],
from: {
type: "phone",
number: process.env.VIRTUAL_NUMBER,
},
ncco: [
{
action: "talk",
text: "This is a text to speech call from Vonage",
},
],
});
To test the Conversations API, you will need to enable Voice for your Vonage Application and set the answer Webhook. I use NGROK as well, so it should look like this. https://<URL>.ngrok.io/webhooks/answer
When working with Conversations API, I usually do:
Create a Conversation
Create a User
Create a Member
and put that into the /webhooks/answer
//server.js
require('dotenv').config();
let express = require('express');
let cookieParser = require('cookie-parser');
let logger = require('morgan');
let app = express();
let port = 5001;
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static('public'));
const NGROK_URL = process.env.NGROK_URL;
const Vonage = require('#vonage/server-sdk');
const vonage = new Vonage({
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
applicationId: process.env.APPLICATION_ID,
privateKey: process.env.APPLICATION_PRIVATE_KEY_PATH
});
app.post('/webhooks/answer', async (req, res) => {
console.log('🚚 answer', req.body);
let result = req.body;
const createCallConversationPromise = (ConvName, ConvDisplayName) => new Promise((resolve, reject) => {
vonage.conversations.create({
"name": ConvName,
"display_name": ConvDisplayName,
}, (error, result) => error ? reject(error) : resolve(result));
});
const createCallUserPromise = (Name, DisplayName) => new Promise((resolve, reject) => {
vonage.users.create({
name: Name,
display_name: DisplayName,
}, (error, result) => error ? reject(error) : resolve(result));
});
const createCallMemberPromise = (ConvId, UserId) => {
vonage.conversations.members.create(ConvId, {
"action": "join",
"user_id": UserId,
"channel": {
"type": "app"
}
}, (error, result) => {
if(error) {
console.log('\n🔥 Error Creating Member', error);
}
else {
console.log('\n✅ Created Member with ConvId', ConvId, 'and UserId',UserId)
console.log(result);
}
})
};
try {
let ConvName = result.from + result.to + result.conversation_uuid;
console.log('n✅ ConvName', ConvName);
let ConvDisplayName = result.from + result.to + result.conversation_uuid;
const conversation = await createCallConversationPromise(ConvName, ConvDisplayName);
process.env.CONVERSATION_ID = conversation.id;
console.log('\n✅ CONVERSATION_ID', process.env.CONVERSATION_ID);
let Name = result.from + result.conversation_uuid;
let DisplayName = result.from;
const callUser = await createCallUserPromise(Name, DisplayName);
console.log('\n✅ UserId', callUser.id)
let ConvId = conversation.id;
let UserId = callUser.id;
const memberUser = await createCallMemberPromise(ConvId, UserId);
let ncco = [
{
action: "talk",
text: "<speak><lang xml:lang='en-GB'>Welcome to Vonage Development inbound call testing</lang></speak>",
voiceName: "Emma"
},
];
res.json(ncco);
} catch (error) {
console.log("🔥 Error", error);
let ncco = [
{
"action": "talk",
"text": "<speak><lang xml:lang='en-GB'>Error on Process Answer</lang></speak>",
"voiceName": "Emma"
}
];
res.json(ncco);
}
});

I don't understand why my api is returning unknown/undefined when I call it using app.get

I'm learning backend and here is an exercise regarding api/express/node.js
The problem is app.get("/api/persons/:person"... I'm console logging personName, which is fine, and persons, which is also fine. But when I do persons[personName], it returns undefined.
The result should be returning an individual json object of the person's information.
const express = require("express");
const app = express();
const cors = require("cors");
const PORT = process.env.PORT || 3001;
app.use(cors());
let persons = {
"Arto Hellas": {
id: 1,
name: "Arto Hellas",
number: "040-123456",
},
"Ada Lovelace": {
id: 2,
name: "Ada Lovelace",
number: "39-44-5323523",
},
"Dan Abramov": {
id: 3,
name: "Dan Abramov",
number: "12-43-234345",
},
"Mary Poppendieck": {
id: 4,
name: "Mary Poppendieck",
number: "39-23-6423122",
},
"unknown": {
id: "unknown",
name: "unknown",
number: "unknown"
}
};
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.get("/api/persons", (req, res) => {
res.json(persons);
});
app.get("/api/persons/:person", (req, res) => { // <-- here is the problem
const personName = req.params.person.toLowerCase();
console.log(personName);
console.log(persons);
console.log(persons[personName]);
if (persons[personName]) {
res.json(persons[personName]);
} else {
res.json(persons["unknown"]);
}
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
personName is converted to lower case, while the keys in persons are not in lower case. Either change the keys in persons to be lower case, or remove the toLowerCase() call when extracting the personName and call your API with the proper case for the names.

Socket hang up when using axios

I'm having an error "Error: socket hang up" and I don't know what causes this but it saves the data in database.
here's my code:
dataschema.js
const mongoose = require("mongoose");
const DataSchema = new mongoose.Schema({
data1: {
type: String
},
data2: {
type: String
},
data3: {
type: String
},
data4: {
type: String
},
});
const DataModel = mongoose.model("TEST123", DataSchema);
module.exports = DataModel;
routes.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const DataModel = require('./models/dataschema');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
mongoose.connect(
"mongodb://localhost:27017/stocksmonitor?readPreference=primary&appname=MongoDB%20Compass%20Community&ssl=false",
{ useNewUrlParser: true }
);
app.post('/insert', (req, res) => {
const stock = new DataModel({
data1: req.body[0],
data2: req.body[1],
data3: req.body[2],
data4: req.body[3],
})
stock.save();
})
app.listen(3001, () => {
console.log("You are connected");
})
savedata.js
const axios = require('axios');
SaveInfo = () => {
const testdata = ["a", "b", "c", "d"]
axios({
method: 'post',
url: 'http://localhost:3001/insert',
data: testdata
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
SaveInfo();
I inspected the code and found that you did not return response for your controller. In the code below after the save add res.send() or res.json(). So express can return a proper response. Otherwise request will timed out, because it did not resolve and Express will cut the connection. Therefore axios is throwing Error: Socket hang up unexpectedly.
app.post('/insert', (req, res) => {
const stock = new DataModel({
data1: req.body[0],
data2: req.body[1],
data3: req.body[2],
data4: req.body[3],
})
stock.save();
})

How to use routes in seneca-web for rest api?

I want to create rest API with seneca-web (express). I could not find any (full) documentation for a routes file used in it. I base one these examples. Let's assume i have a resource called Task. I want to have these http methods:
GET /tasks
GET /tasks/:taskId
POST /tasks
Here is routes.js:
module.exports = [
{
prefix: '/tasks',
pin: 'role:api,path:*',
map: {
all: {
GET: true,
prefix: ''
},
':taskId': {
GET: true
}
}
},
{
pin: 'role:api,path:*',
map: {
tasks: {
POST: true
}
}
}
]
and my seneca plugin for handling:
module.exports = function task (options) {
this.add({role: 'api', path: 'all'}, function (msg, respond) {
console.log(msg)
this.act('role:task,cmd:all', respond)
respond(null, [{name: 'First Task', description: 'Description of the First Task'}])
})
this.add({role: 'api', path: '*'}, function (msg, respond) {
console.log(msg)
this.act('role:task,cmd:single', {taskId: msg.args.params.taskId}, respond)
})
}
I am not sure how to separate POST and GET actions here.
I found also problematic the fact that keys in map object of routes are taken as a part of a path, eg. GET /tasks/all instead of GET /tasks.
Thanks for any help.
here is example of seneca-web with routes
=========index.js=======
const seneca = require('seneca')()
const express = require('express')()
const web = require('seneca-web')
const cors = require('cors')
var Routes = [{
prefix: '/products',
pin: 'area:product,action:*',
map: {list: {GET: true}}
}]
express.use(cors())
var config = {
routes: Routes,
adapter: require('seneca-web-adapter-express'),
context: express,
options: {parseBody: true}
}
seneca.client()
.use(web, config)
.ready(() => {
var server = seneca.export('web/context')()
server.listen('8082', () => {
console.log('server started on: 8082')
})
})
seneca.add({area: 'product', action: 'list'}, function (args, done) {
try {
done(null, {response: 'Product List'})
} catch (err) {
done(err, null)
}
})
start app using command :
node index.js
open link in your browser
http://localhost:8082/products/list

Resources