api call to sinch as promise - node.js

I've tested the interface and made some changes to use with my sailsjs (version 11) on the backend. In this case I use a sails service and things seem fine but I always get back a pending status.
```
SinchService.js
var sinchAuth = require('sinch-auth');
var request = require('request');
var sinchMessaging = {};
var Promise = require('bluebird');
//sinchMessaging.sendMessage = function (phoneNumber, message) {
//exports.sendMessage = function (phoneNumber, message) {
module.exports = {
sendMessage: function (phoneNumber, message) {
var auth = sinchAuth();
if (!auth) {
throw new Error("No Authorization was provided");
}
var options = {
method: 'POST',
url: "https://messagingApi.sinch.com/v1/sms/" + phoneNumber,
headers: {
"Content-Type": "application/json",
"Authorization": auth
},
body: "{\"Message\":\"" + message + "\"}"
// body: {"Message" : message }
};
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
sails.log("Finished with call");
if (error) {
sails.log(error);
throw error;
}
else {
sails.log("Finished with body ", body);//.MessageId
return resolve(response.body);
}
});
})
},
getStatus: function (messageId) {
var auth = sinchAuth();
if (!auth) {
throw new Error("No Authorization was provided");
}
var options = {
method: 'GET',
url: "https://messagingApi.sinch.com/v1/sms/" + messageId,
headers: {
"Content-Type": "application/json",
"Authorization": auth
}
};
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
sails.log("Finished with call");
if (error) {
sails.log(error);
throw error;
}
else {
return resolve(response.body);
}
});
})
}
};
```
agendaService.js
var jsonObjS;
SinchService.sendMessage(phoneNumber, message).then(function (results) {
var jsonObj = JSON.parse(results);
console.log('results sendMessage ', jsonObj.messageId);
if (jsonObj.messageId!==undefined){
SinchService.getStatus(jsonObj.messageId).then(function (results_s) {
jsonObjS = JSON.parse(results_s);
console.log('results getStatusS ', jsonObjS.status);
SinchService.getStatus(jsonObjS.messageId).then(function (results_s) {
var jsonObjS = JSON.parse(results_s);
console.log('results getStatusS ', jsonObjS.status);
});
});
```

Pending will always be the first status, query again after some time to see the status of of the message.

Related

How can i use promise method in node

I was trying out the promise function for the REST API instead of using axios method. so I can wait for the result and if there is any error. can anyone help me change this code to promise in node.js so I can do a fetch using promise method. thank you
this is my code
const email = "xxx#xxxx.com"
function isUserExists(email, kc_accessToken) {
let url = `${path}/users?email=${email}`;
return axios_instance.get(url,
{
headers: {
"content-type": "application/json",
"authorization": `Bearer ${kc_accessToken}`
}
}).then(function (response) {
if (response.data.length > 0) {
return true;
} else {
return false;
}
})
.catch(function (error) {
console.log("some error occured");
});
}
Method call
http.createServer(function Test() {
getAccessToken().then(function (response) {
kc_accessToken = response.data.access_token;
IsUserExists(email, kc_accessToken).then((resp) => {
console.log(resp)
if(resp) {
console.log("Do Not Create")
} else if (!resp) {
console.log("Creat a new User")
}
})
}).catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});;
}).listen(8081);
I think you need something like that :
const email = "xxx#xxxx.com"
const request = require('request');
function isUserExists(email, kc_accessToken) {
let url = `${path}/users?email=${email}`;
return new Promise(function(resolve, reject){
request({
url: url,
headers: {
"content-type": "application/json",
"authorization": `Bearer ${kc_accessToken}`
}
}, function (error, response, body) {
if (error) {
console.log("some error occured");
}
if (response.data.length > 0) {
return resolve();
}
return reject();
});
});
}

NodeJs amazon-cognito-identity-js signUp succeeding without returning a result

I have imported node-fetch amazon-cognito-identitiy-js from npm and am trying to deploy a custom sign up lambda function.
global.fetch = require('node-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const poolData = {
UserPoolId: "ap-southeast-1_******",
ClientId: "***********"
}
module.exports.router = (event, context, callback) => {
return createUser(event, context, callback);
};
function createUser(event, context, callback) {
let postBody = JSON.parse(event.body);
/*cognito test*/
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var attributeList = [];
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({Name:"email",Value:postBody.email}));
var cognitoResult = null;
userPool.signUp(postBody.email, 'ke$2kelmDj123', attributeList, null, function(err, result){
if (err) {
cognitoResult = err;
} else {
cognitoResult = result;
}
});
const response = {
statusCode: 201,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({ message: "register account", special: postBody["name"], cognito: cognitoResult })
};
callback(null, response);
}
For some reason cognitoResult will only return null, even though the user is being created in my user pool in AWS.
That is because this piece of code
userPool.signUp(postBody.email, 'ke$2kelmDj123', attributeList, null, function(err, result){
if (err) {
cognitoResult = err;
} else {
cognitoResult = result;
}
});
is asynchronous and you are not waiting for the result. You just return the response while this has not yet been resolved. It resolves eventually (which you can observe by the user being created) but you have already returned from the Lambda function by then.
You can solve it by embedding the response in the else block.
userPool.signUp(postBody.email, 'ke$2kelmDj123', attributeList, null, function(err, result){
if (err) {
cognitoResult = err;
// place error response here
} else {
cognitoResult = result;
const response = {
statusCode: 201,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({ message: "register account", special: postBody["name"], cognito: cognitoResult })
};
callback(null, response);
}
});
Note that you should also create an error response.

how to get data outside request

I have a scenario where i need to take response (body) of request method outside request. How can i do it?
request.post({
url: 'http://localhost/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
I need this tmsg outside for next processing, Actual scenario is as below.
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
if (mediaCount == 0) {
//var twiml = getResponse(message);
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
}else {
//dosomething which outputs tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});
The problem is you are trying to assign value to a global variable in request.post's callback() which is only called after request.post is executed by Asynchronous logic(API calls are all async), so a better way would be to promisify request.post and await the request.post to make it seem synchronous.
const requestPromisified = requestObject =>
new Promise((resolve, reject) => {
request.post(requestObject, function(err, httpResponse, body) {
if (err) {
reject(err);
}
resolve(body);
});
});
const body = await requestPromisified({
method: "POST",
url: "http://localhost/api/messages",
form: { key: message }
});
You only can do something with tmsg when you made the request so you need to rearrange your code like this:
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
console.log(tmsg);
if (mediaCount === 0) {
//do something with tmsg
} else {
//do something else with tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});
});
Otherwise tmsg will be null because there was no request made to fill that variable.

node.js sending by request module

I need to send a lot of messages. I use external api and request module:
email.js
var request = require('request');
module.exports = function(subject, email){
var message = ... ;
var options = {
method: 'POST',
url: 'https://api.emails.net.com/api/sendmail',
form: {
smtp_account: smtp,
to: {},
subject: subject,
html: message,
from: 'myapp#email.com',
from_name: 'Myapp'
},
headers: {
'Authorization': ' ... '
}
};
request(options, function (error, response) {
if (!error && response.statusCode === 200) return true;
return false;
});
};
And in another place:
var sendEmail = require('../email');
...
for( ... ){
if(sendEmail(subject, email)){
//do something
}
}
After success i want to do something but request return nothing. Is any way to check if post was success and do something in place where I require email module? I'm sending emails in loop and i must check one by one.
You can do something like this
var request = require('request');
var Promise = require('bluebird');
var email = function () {
return {
send: function (subject, email) {
var message = "test";
var options = {
method: 'POST',
url: 'https://api.emails.net.com/api/sendmail',
form: {
smtp_account: "smtp",
to: {},
subject: subject,
html: message,
from: 'myapp#email.com',
from_name: 'Myapp'
},
headers: {
'Authorization': ""
}
};
return new Promise(function (resolve, reject) {
request(options, function (error, response) {
if (!error && response.statusCode === 200) {
resolve(true);
} else {
reject(err);
}
});
})
}
}
};
module.exports = email();
And then you can consume this as below
for (var i = 0; i < 10; i++) {
console.log(i);
email
.send("test", "test#gmail.com")
.then(function (status) {
///Do what ever u want to do
})
.catch(function (err) {
console.log(err);
});
}

Auto append unwanted character in nodejs put request

I have an api to file upload on Bluemix Object Storage by using request module. All are good but there is some unwanted character which append automatically.
example:
--38oi85df-b5d1-4d42-81ce-c547c860b512 //this is unwanted character
Email
abc#gmail.com
hsl#gmsl.com
pjeyjle#cse.com
--38oi85df-b5d1-4d42-81ce-c547c860b512-- // this is unwanted character
Here is my code:-
import request from 'request';
exports.putObjectStorageFile = function(authToken, file, csv, cb) {
var s = new stream.Readable();
s._read = function noop() {};
s.push(csv); //csv is string
s.push(null);
var options = {
url: 'https://xxxx.objectstorage.open.xxxx.com/v1/AUTH_' + config.objectStorage.projectId + '/xxxx/' + file,
method: 'PUT',
preambleCRLF: true,
postambleCRLF: true,
encoding: 'utf-8',
headers: {
'Content-Type': 'text/html; charset=UTF-8',
'Content-Length': 1,
'X-Auth-Token': authToken
},
multipart: {
chunked: false,
data: [
{ body: s }
]
} };
function callback(error, response) {
if (error) cb(error);
if (!error && response.statusCode == 201) {
cb(null);
}
}
request(options, callback);
You are sending a multipart message with a preambleCRLF and postambleCRLF in your request which is causing those lines.
You should use the pkgcloud library for uploading data to Object Storage:
https://github.com/pkgcloud/pkgcloud
Below is a sample of using pkgcloud with the Object Storage service on Bluemix (credentials from VCAP).
(function (module) {
var pkgcloud = require('pkgcloud'),
fs = require('fs');
function ObjectStorage(container, credentials) {
this.container = container;
this.config = {
provider: 'openstack',
useServiceCatalog: true,
useInternal: false,
keystoneAuthVersion: 'v3',
authUrl: credentials.auth_url,
tenantId: credentials.projectId,
domainId: credentials.domainId,
username: credentials.username,
password: credentials.password,
region: credentials.region
};
this.client = pkgcloud.storage.createClient(this.config);
}
ObjectStorage.prototype.validate = function () {
return new Promise(function (resolve, reject) {
this.client.auth(function (error) {
if (error) {
return reject(error);
}
resolve();
});
}.bind(this));
};
ObjectStorage.prototype.makeContainer = function () {
return new Promise(function (resolve, reject) {
this.client.createContainer({name: this.container}, function (error) {
if (error) {
return reject(error);
}
return resolve();
});
}.bind(this));
};
ObjectStorage.prototype.uploadFile = function (path, name) {
return new Promise(function (resolve, reject) {
var myPicture = fs.createReadStream(path);
var upload = this.client.upload({
container: this.container,
remote: name
});
upload.on('error', function (error) {
reject(error);
});
upload.on('success', function (file) {
resolve(file);
});
myPicture.pipe(upload);
}.bind(this));
};
module.exports = ObjectStorage;
})(module);
I got that lines due to sending data with multipart. I found a solution by adding just content-type,content-lenght and send data in body i.e,
var options = {
url: 'https://dal.objectstorage.open.softlayer.com/v1/AUTH_' + config.objectStorage.projectId + '/nrich-storage/' + file,
method: 'PUT',
headers: {
'Content-Type': 'text/csv',
'Content-Length': csv.length,
'X-Auth-Token': authToken
},
body:csv
};
function callback(error, response) {
if (error) cb(error);
if (!error && response.statusCode == 201) {
cb(null);
}
}
request(options, callback);

Resources