I'm writing a program in node js that does the following.
Get the Access token(a jwt)
Get the user firstName from that token
Pass this token and firstName to another method to post.
print the result.
My program is as below.
function getUserDetailsFromAccessToken(session) {
var token = session.user.accessToken;
try {
// parse this and get user attributes
var decoded = jwt.decode(token);
getTheUserProfile(decoded.firstname, token, session);
} catch (err) {
console.log(err);
}
}
var hostUrl= "myUrlToGetResult";
function getTheUserProfile(nameFromSession, token, session) {
console.log("Incomung values " + nameFromSession);
console.log("Inside getUsersProfile Block");
var jsonToPass = {
"accesstoken": token,
"domain": "DomainName",
"lanid": nameFromSession
};
console.log("json to pass " + JSON.stringify(jsonToPass));
var options = {
uri: hostUrl+ "/api/admin/GetUserInfo",
method: "POST",
json: jsonToPass
};
request(options, function (error, resp, body) {
console.log("resp code is " + resp.statusCode);
if (!error && resp.statusCode == 200) {
if (body) {
console.log("Insode B1");
console.log(body.firstName);
} else {
console.log("I am unable to authenticate you. please disable the skill and re link your account");
}
} else {
console.log(error);
}
});
}
when I run this program, I'm able to print only till console.log("json to pass " + JSON.stringify(jsonToPass));, after that I'm unable to get any result from request() block.
please let me know where am I going wrong and how can I fix it.
Related
I'm making a Messenger bot in NodeJS. I want users be able to request all their trains. The problem is that we want to execute a query before NodeJS sends a message to the user.
I searched for asynchronous functions
function handlePostback(sender_psid, received_postback) {
let response;
// Get the payload for the postback
let payload = received_postback.payload;
// Set the response based on the postback payload
switch(payload){
case "yes" :
let data = null
axios.get('http://api.irail.be/connections/?from=Mechelen&to=Puurs&date=010219&time=1650×el=departure&format=json&lang=en&fast=false&typeOfTransport=trains&alerts=false&resul1=1')
.then(function (response) {
// handle success
data = data.response;
})
response = {
"text": data.connections.arrival.name
}
break;
}
callSendAPI(sender_psid, response);
}
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
// Send the HTTP request to the Messenger Platform
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": PAGE_ACCESS_TOKEN },
"method": "POST",
"json": request_body
}, (err, res, body) => {
if (!err) {
console.log('message sent!')
} else {
console.error("Unable to send message:" + err);
}
});
}
So as you can see, the script will already sending the message to the user on Messenger before the query is executed.
There are some unneccessary variables and problems in your code (data = data.response should probably be data = response.data, for example), this would be a modern version with async/await and arrow functions. You do not need a callback function in that case, callSendAPI will be called after the AJAX request. I have also removed the switch, because a simple if is sufficient:
const handlePostback = async (sender_psid, received_postback) => {
// Get the payload for the postback
const payload = received_postback.payload;
// Set the response based on the postback payload
if (payload === 'yes') {
try {
const response = await axios.get('http://api.irail.be/connections/?from=Mechelen&to=Puurs&date=010219&time=1650×el=departure&format=json&lang=en&fast=false&typeOfTransport=trains&alerts=false&resul1=1');
callSendAPI(sender_psid, {
'text': response.data.connections.arrival.name
});
} catch (err) {
console.log(err);
}
}
};
Side note: I would not use 2 different ways to do http requests, assuming you are using superagent too? Because http.request would be a possibility with Node.js, but request looks like superagent ;)
Put callSendAPI() in your Axios callback
function handlePostback(sender_psid, received_postback) {
let response;
// Get the payload for the postback
let payload = received_postback.payload;
// Set the response based on the postback payload
switch (payload) {
case "yes":
let data = null
axios.get('http://api.irail.be/connections/?from=Mechelen&to=Puurs&date=010219&time=1650×el=departure&format=json&lang=en&fast=false&typeOfTransport=trains&alerts=false&resul1=1')
.then(function(response) {
// handle success
data = data.response;
})
response = {
"text": data.connections.arrival.name
}
callSendAPI(sender_psid, response);
break;
}
}
everybody! I'm trying to build a Google Pagespeed client in nodejs.
I get a json file with syntax errors for any url. For example: url: http://www.bbc.com/ , error: enter image description here
json file:enter image description here
I need only the property "ruleGroups". I tried to extract it so jsonpath.query(d, '$.ruleGroups') -
did not work out.
Help please understand, sorry if the issue is dilettian.
let key = 'key';
let url = 'http://www.bbc.com/';
let strategy = 'desktop';
https.get({
host: 'www.googleapis.com',
path: '/pagespeedonline/v4/runPagespeed?url=' + encodeURIComponent(url) +
'&key='+key+'&strategy='+strategy
}, function (res) {
console.log ("statusCode:", res.statusCode);
console.log ("headers: ", res.headers);
res.on ('data', function (d) {
let json = JSON.parse(d);
fs.appendFile('log.txt', json);
});
}). on ('error', function (e) {
console.error (e);
});
You may need to accumulate all the data, then parse in the “end” event:
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
More information: https://nodejs.org/api/http.html#http_http_get_options_callback
So I have a nodejs server and I am trying to make comparisons to the req values. Firstly, here is my code:
app.post('/', function(req, res) {
firstName = req.body.firstName;
lastName = req.body.lastName;
message = req.body.message;
token = req.body.token;
user = {name: firstName + " " + lastName, token: token};
selectedUser = req.body.selectedUser;
users.push(user);
console.log(user.name);
if (req.body.isAndroid === true) {
sendToAndroid(); //add message parameter
} else {
sendToios(); //add message parameter
}
});
app.listen(8080, function() {
console.log('running on port 8080');
});
//GCM
function sendToAndroid() {
var message = new gcm.Message();
var tokenLocation;
//API Server Key
var sender = new gcm.Sender('AIzaSyD-B3EG1xpMh6YhwBKfLMyw0GIQKWfGgZM');
//console.log(message);
// Value the payload data to send...
message.addData({
title: 'Hello',
body: 'Message From: ' + user.name + ': ' + message,
msgcnt: 1,
timeToLive: 3000
});
// At least one reg id required
if (registrationToken.indexOf(token) == -1) {
registrationToken.push(token);
tokenLocation = registrationToken.indexOf(token);
} else {
tokenLocation = registrationToken.indexOf(token);
}
if (users.indexOf(user.name) == -1) {
console.log("user destination not found");
} else {
var userTokenArray = [];
userTokenArray.push(user.token);
sender.send(message, { registrationTokens: userTokenArray } , function (err, response) {
if(err) console.error(err);
else console.log(response);
});
userTokenArray.pop();
}
}
And here is my problem when outputting to see what the value is:
running on port 8080
undefined undefined
user destination not found
What I am trying to do is put the registered users into an array of users that each element has a full name and token. Then in the Android function, it will check to see what value value is selected and then push a notification to the selectedUser via their token. I am so confused on how to compare the "strings" or whatever they are. I am using nodejs express with body-parser.
I'M trying to get data from embed.ly via node.js.
Everything looks ok but it puts an "undefined" in front of the data:
Maybe it has something to do with setEncoding('utf8) ?
The results looks like this:
undefined[{ validjson }]
The function:
function loadDataFromEmbedLy( params, queue ){
try {
var body;
var options = {
host: 'api.embed.ly',
port: 80,
path: '/1/oembed?wmode=opaque&key=key&urls='+params,
method: 'GET',
headers: {'user-agent': ''}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('end', function() {
if( typeof body != 'undefined' ){
console.log( body );
}
});
res.on('data', function ( chunk ) {
if( typeof chunk != 'undefined' ){
body += chunk;
}
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
} catch(e) { console.log("error " + e); }
}
It's because body is initially undefined. When you append to it using +=, it will append it to the string "undefined". I hope that makes sense.
Solution: declare body as the empty string: var body = "";
Second: I really recommend checking out Mikeal Rogers' request.
Edit: request is a little easier than the basic http api. Your example:
function loadDataFromEmbedLy (params) {
var options = {
url: 'http://api.embed.ly/1/oembed',
qs: {
wmode: 'opaque',
urls: params
},
json: true
};
request(options, function (err, res, body) {
console.log(body);
});
}
When getting a json from a URL I only want to work with it, when the data is valid.
my approach so far by using JSON:
$http.get(
'data/mydata.json'
+ "?rand=" + Math.random() * 10000,
{cache: false}
)
.then(function (result) {
try {
var jsonObject = JSON.parse(JSON.stringify(result.data)); // verify that json is valid
console.log(jsonObject)
}
catch (e) {
console.log(e) // gets called when parse didn't work
}
})
However before I can do the parsing, angular already fails itself
SyntaxError: Unexpected token {
at Object.parse (native)
at fromJson (http://code.angularjs.org/1.2.0-rc.2/angular.js:908:14)
at $HttpProvider.defaults.defaults.transformResponse (http://code.angularjs.org/1.2.0-rc.2/angular.js:5735:18)
at http://code.angularjs.org/1.2.0-rc.2/angular.js:5710:12
at Array.forEach (native)
at forEach (http://code.angularjs.org/1.2.0-rc.2/angular.js:224:11)
at transformData (http://code.angularjs.org/1.2.0-rc.2/angular.js:5709:3)
at transformResponse (http://code.angularjs.org/1.2.0-rc.2/angular.js:6328:17)
at wrappedCallback (http://code.angularjs.org/1.2.0-rc.2/angular.js:9106:81)
at http://code.angularjs.org/1.2.0-rc.2/angular.js:9192:26 angular.js:7861
How can I prevent angular from throwing this error or how else should I handle verifying the JSON ?
UPDATE: Solution:
$http.get(
// url:
'data/mydata.json'
+ "?rand=" + Math.random() * 10000
,
// config:
{
cache: false,
transformResponse: function (data, headersGetter) {
try {
var jsonObject = JSON.parse(data); // verify that json is valid
return jsonObject;
}
catch (e) {
console.log("did not receive a valid Json: " + e)
}
return {};
}
}
)
You can override transformResponse in $http. Check this other answer.
I was looking for the same thing, and transformResponse does the job, BUT, I dont like using transformResponse everytime i use $http.get() or even overriding it because some $http.get() will be json and some not.
So, here is my solution:
myApp.factory('httpHandler', function($http, $q) {
function createValidJsonRequest(httpRequest) {
return {
errorMessage: function (errorMessage) {
var deferred = $q.defer();
httpRequest
.success(function (response) {
if (response != undefined && typeof response == "object"){
deferred.resolve(response);
} else {
alert(errorMessage + ": Result is not JSON type");
}
})
.error(function(data) {
deferred.reject(data);
alert(errorMessage + ": Server Error");
});
return deferred.promise;
}
};
}
return {
getJSON: function() {
return createValidJsonRequest($http.get.apply(null, arguments));
},
postJSON: function() {
return createValidJsonRequest($http.post.apply(null, arguments));
}
}
});
myApp.controller('MainCtrl', function($scope, httpHandler) {
// Option 1
httpHandler.getJSON(URL_USERS)
.errorMessage("MainCtrl -> Users")
.then(function(response) {
$scope.users = response.users;
});
// Option 2 with catch
httpHandler.getJSON(URL_NEWS)
.errorMessage("MainCtrl -> News")
.then(function(response) {
$scope.news = response.news;
})
.catch(function(result){
// do something in case of error
});
// Option 3 with POST and data
httpHandler.postJSON(URL_SAVE_NEWS, { ... })
.errorMessage("MainCtrl -> addNews")
.then(function(response) {
$scope.news.push(response.new);
});
});