I am sending a Postman POST to a LDAP Server. When I use the GET response for one function it works; however, when I use the POST for another function that involves client.binding. I get no response, "Could not get any response" after 1 minute of waiting. I am using http, with no proxy.
GET that works:
IAMserver.get('/account/list', function(req,res){
//list accounts for a compangy. seraches everyhting under provided compagny node.
let enterprise = req.jwtPayload.enterprise || "Enterprise";
var opts = {
//filter: 'cn='+base,
filter: '(objectclass=person)',
scope: 'sub'
};
console.log(result);
console.log('status: ' + result.status);
respondWithJSON(200, 0, "Success", res, entries);
POST that doesn't work:
IAMserver.post('/account/modify', function(req,res){
if(req.jwtPayload.entityData == null || req.jwtPayload.entityData == {}){
respondWithJSON(400, 400, "No entity data provided or data was not JSON encoded.", res);
return;
}
//Check if exists already.
aSearch(req.jwtPayload.cn).then(
//exists
function(result){
//Bind to admin account.
client.bind(adminCred, adminPass, function(err){
if(err){
respondWithJSON(500,500, err.message, res);
return;
}
});
//define modifications
let changes = new ldap.Change({
operation: 'replace',
modification: req.jwtPayload.entityData
});
//try to modify.
client.modify('cn='+req.jwtPayload.cn+',ou=Enterprise,dc=abc,dc=com', changes, function(err){
if(err){
respondWithJSON(500, 500, err.message, res);
return;
}
respondWithJSON(200, 0, "Changes executed correctly.", res);
});
},
//Doesn't exist, can't modify.
function(result){
respondWithJSON(200,1, "Failure. "+result.message, res);
});
});
Related
My res.json in my first block of code works, but in the else part of my if statement, it does not. The block that doesnt work, checks for a record in a database then im trying to return the response but im not receiving it.
I've checked and the response is a string, I thought it would have worked as the top part of the code successfully returns the string and it shows in dialogflow (where im trying to return it)
The response is successfully consoled right before the res.json but I do not receive it from the source of the request.
code:
app.post('/webhook/orderinfo', (req, res) => {
const intent = req.body.queryResult.intent.displayName;
const domain = "chatbotdemo.myshopify.com";
const order = req.body.queryResult.parameters["number-sequence"];
if (intent.includes('Order Number')) {
url = "https://test-hchat.com/api/orders/" + domain + "/" + order;
request(url)
.then(function (response) {
order_res = JSON.parse(response)
order_res["fullfillmentText"] = "Hi, Please find your order details below:";
res.json({
"fulfillmentText": JSON.stringify(order_res)
})
})
.catch(function (err) {
console.log(err)
});
// THIS PART DOESNT RETURN THE RESPONSE.
} else {
const domain = 'testStore'
db.getClientsDialog(domain, intent, (response) => {
const fullResponse = response.response
res.json({
fullResponse
})
})
}
});
The database code:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://efwefewf#wefwef.mlab.com:15799/wefwef', function (err, client) {
if (err) throw err;
var db = client.db('asdsad');
db.collection('dialog').findOne({ domain: domain, intent: intent }, function (err, doc) {
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Could it be because this second use of the res.json in the else statement, is trying to call the db first and therefore the link is lost to send the data back?
So currently the tweet bot is;
var fs = require('fs'),
path = require('path'),
Twit = require('twit'),
config = require(path.join(__dirname, 'config.js'));
var T = new Twit(config);
function pick_random_countermagic(){
var countermagic = [
'Force-of-Will.jpg',
'Cryptic-Commad.jpg',
'Counterspell.jpg',
];
return countermagic[Math.floor(Math.random() * countermagic.length)];
}
function upload_random_image(){
console.log('Opening an image...');
var image_path = path.join(__dirname, '/countermagic/' + pick_random_countermagic()),
b64content = fs.readFileSync(image_path, { encoding: 'base64' });
console.log('Uploading an image...');
T.post('media/upload', { media_data: b64content }, function (err, data, response) {
if (err){
console.log('ERROR');
console.log(err);
}
else{
console.log('Uploaded an image!');
T.post('statuses/update', {
media_ids: new Array(data.media_id_string)
},
function(err, data, response) {
if (err){
console.log('Error!');
console.log(err);
}
else{
console.log('Posted an image!');
}
}
);
}
});
}
setInterval(
upload_random_image,
10000
);
All it does currently posts, at random an image, which is what I want, but instead of just posting it I would like it to post in reply to a targeted tweet from another twitter when that bot tweets, and or when the bot is active reply to all tweets that bot has tweeted that my bot has not already replied to... if you know what I mean.
This is my first time making a twitter bot, and technically my first time really using javascript and node.js. So yeah, I am just lost. So yeah any help would be insurmountably helpful.
You can retrieve mentions using statuses/mentions_timeline API and reply them using statuses/update API by passing mention's id in in_reply_to_status_id. Here is a simple example:
function replyMentions() {
// check for mentions
// you can add parameter 'since_id' to limit returns
T.get('statuses/mentions_timeline', { count: 100 }, function(err, data, response) {
if (data) {
data.forEach(function(mention) {
// reply if mention.id_str is not yet replied
reply = '#' + mention.user.screen_name + ' thanks for reaching out!'
T.post('statuses/update', { status: reply, in_reply_to_status_id: mention.id_str }, function(err, data, response) {
console.log(data)
// mark data.id_str as replied
})
})
}
})
}
You can add some additional logic to store replied id_str in database and use them to avoid redundant replies and limiting mentions retrieval (using since_id parameter).
I'm building a twitter sentiment reader and I am running into issues when I try and send a response back to angular. Everything worked fine before I added res.send() and it logged the sentiment.
Now that I added the res.send() function, it errors out sending the data back to angular. Angular has it as an error 500 and my node console has the error saying POST /postUsername Security Handshake Failed: some library stuff Description: End of TCP Stream".
Express Route
router.post("/postUsername", function(req, res){
console.log(req.body.userName);
var client = new Twitter({
consumer_key: '',
consumer_secret: '',
access_token_key: '',
access_token_secret: ''
});// client
client.get('statuses/user_timeline', {screen_name: req.body.userName, count:20}, function(error, tweets, response) {
tweet = analyzeIt.seperateData(tweets);
var document = language.document(tweet);
if (!error) {
var parsedScore;
var parsedMagnitude;
var finalScore;
var options = {
verbose: true
}; // options
document.detectSentiment(options, function(err, score) {
if (err) {
console.log(err);
} //if err
parsedScore = score.score;
parsedMagnitude = score.magnitude;
finalScore = analyzeIt.finalScore(parsedScore, parsedMagnitude);
console.log(finalScore);
});//detect sentiment
}//if not error
});//client get statuses
res.send(finalScore);
});//router post
Angular Controller
app.controller('myController', function($scope, $http){
$scope.sendData = function() {
var data = { userName: $scope.userName };
console.log($scope.userName);
$http.post('/postUsername', data)
.success(function (data, status, headers, config) {
$scope.PostDataResponse = data;
})
.error(function (data, status, header, config) {
$scope.PostDataResponse = "Data: " + status;
});
};
});
The expected output would be something like "This user trends positive."
Any help would be appreciated!
I see a few problems. First is that you are responding immediately, without waiting for the twitter request to complete.
// Call order: #1
client.get(..., function(error, tweets, response) {
// Call order: #3
// anything in here no longer matters
});
// Call order: #2
res.send(finalScore) //because this executes before the code in the callback above
So essentially when the call is made from angular, express immediately sends back the value of finalScore which is undefined.
The other problem is you aren't really handing the error case. If there is an error with the twitter client, you should respond to the request in a meaningful way, rather than just logging to the console. This way you can see, inside angular what the problem is instead of having to scratch your head and look at your server console:
if(!error) {
//do normal stuff
}
else {
res.status(500).send("Twitter error: " + error);
}
Same goes for detectSentiment:
document.detectSentiment(options, function(err, score) {
if (err) {
console.log(err);
res.status(500).send("Error detecting sentiment: " +err);
}
});
So, to fix your issue, you need to be responding inside your callbacks, not after:
router.post("/postUsername", function(req, res){
...
client.get('statuses/user_timeline', {screen_name: req.body.userName, count:20}, function(error, tweets, response) {
...
if (!error) {
...
document.detectSentiment(options, function(err, score) {
if (err) {
console.log(err);
res.status(500).send("Error detecting sentiment: " + err);
} //if err
...
console.log(finalScore);
res.send(finalScore);
});//detect sentiment
}
else {
res.status(500).send("Twitter error: " + error);
}
});//client get statuses
});//router post
It seems a little weird, at first, that you have to nest your response so deep, but it's not at all. This is the world of javascript. There are ways to use promises and deferred objects to clean up your code, but for now it's best to write it like this so that it really sinks in how asynchronous code in javascript works.
Hello you beautiful people you.
I'm trying to create REST APIs using node.js connected to an OracleDB, but i'm pulling my hair out trying to get these stupid bind variables working.
Here's my code:
app.get('/mailsummary/:SCHEMA', function (req, res) {
"use strict";
oracledb.getConnection(connAttrs, function (err, connection) {
if (err) {
// Error connecting to DB
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error connecting to DB",
detailed_message: err.message
}));
return;
}
connection.execute("select * from :SCHEMA.event#db3", [req.params.SCHEMA], {
outFormat: oracledb.OBJECT // Return the result as Object
}, function (err, result) {
if (err || result.rows.length < 1) {
res.set('Content-Type', 'application/json');
var status = err ? 500 : 404;
res.status(status).send(JSON.stringify({
status: status,
message: err ? "Error getting vendor mailing summary." : "Vendor or DB does nto exist.",
detailed_message: err ? err.message : ""
}));
} else {
res.contentType('application/json').status(200).send(JSON.stringify(result.rows));
}
// Release the connection
connection.release(
function (err) {
if (err) {
console.error(err.message);
} else {
console.log("GET /mailsummary/" + req.params.SCHEMA + " : Connection released");
}
});
});
});
});
For some reason i'm getting the error
OracleDB : ORA-01036: illegal variable name/number
If I remove the bind variable, assign a static value and remove "req.params.SCHEMA" after the sql statement and leave the brackets blank, it works.
connection.execute("select * from peeps.event#db3", [], {
outFormat: oracledb.OBJECT // Return the result as Object
I know it's got to be something simple with the way i'm pulling in the bind variable, but i'm pulling my hair out.
Please help me Obi-Wan Kenobi... you're my only hope.
Thanks!
Bind variables are placeholders used to transfer data between database and client program. You are trying to transfer the text of the SQL statement - your usage won't work.
This bind behavior is not specific to node-oracledb; it's the way Oracle works. It helps keep data and statement text separate.
There is some general bind info at: http://docs.oracle.com/database/122/LNOCI/binding-and-defining-in-oci.htm#GUID-77A26CEA-1C41-46A2-866C-622F9FEB5482
I have a form whose submit button calls
exports.postUpdateProfile = function(req, res, next) {
User.findById(req.user.id, function(err, user) {
if (err) return next(err);
user.email = req.body.email || '';
user.profile.name = req.body.name || '';
//check req.body.rescueTimeKey by making http request,
//and parsing response to ensure the key is good
user.profile.rescueTimeKey = req.body.rescueTimeKey;
user.save(function(err) {
if (err) return next(err);
req.flash('success', { msg: 'Profile information updated.' });
res.redirect('/account');
});
});
};
I want to make sure the req.body.rescueTimeKey is valid before saving the profile, I've tried to create a module to perform that check...
//rescue-time.js module
var request = require('request');
exports.validKey = function(key){
var options = {
url: 'https://www.rescuetime.com/anapi/data?key=' + key,
json: true
};
var cb = function callback(error, response, body){
if(error || body.error){
//Key is bad, flash message and don't allow save
}
//key is good, save profile
};
request(options, cb);
}
As you might imagine I am not fully grasping the node style of using callbacks when making async calls, any help to re-organize this code is greatly appreciated.
What you will want to do is add an extra argument to your validKey function to accept a callback which is what we will use after the request.
So your rescue-time.js will look something like this:
// rescue-time.js
var request = require('request');
exports.validKey = function(key, cb) {
var options = {
url: 'https://www.rescuetime.com/anapi/data?key=' + key,
json: true
};
request(options, function (error, response, body) {
if(error || body.error){
cb(false)
}
else {
cb(true);
}
});
};``
We're returning a boolean result of true or false if the key is valid.
Inside your controller you will want something like the following:
var rescueTime = require('./path/to/rescue-time.js');
exports.postUpdateProfile = function(req, res, next) {
User.findById(req.user.id, function(err, user) {
if (err) return next(err);
user.email = req.body.email || '';
user.profile.name = req.body.name || '';
//check req.body.rescueTimeKey by making http request,
//and parsing response to ensure the key is good
user.profile.rescueTimeKey = req.body.rescueTimeKey;
// We're sending in a callback function that will have a "valid" result as a second arg
rescueTime.validKey(user.profile.rescueTimeKey, function(valid) {
// check if valid returned true or false and act accordingly
if (!valid) {
req.flash('error', 'invalid rescueTime key');
res.redirect('/account');
}
else {
user.save(function(err) {
if (err) return next(err);
req.flash('success', { msg: 'Profile information updated.' });
res.redirect('/account');
});
}
});
});
};
Keep in mind this code wasn't tested at all, but more of an example on what you need to do to obtain your desired results.