Imgur API call: 443 ENOTFOUND error troubleshooting - javascript

I'm receiving the same error every time I call the following node.js code. I haven't used Authorization Headers before in node.js, so I must be doing something wrong. Help or point me towards good documentation? The code is trying to retrieve as search for 'yellow' in imgur's library. My console always prints the same ENOTFOUND error each time I try to run it.
var express = require("express");
var moment = require("moment");
var http = require("http");
var express = require("express");
var moment = require("moment");
var https = require("https");
var mongo = require('mongodb').MongoClient;
var mystatus="";
var app=express();
var imgurClientID = "<my id>";
var imgurClientSecret = "<my client secret>";
var options = {
hostname: 'https://api.imgur.com/3/gallery/search?q=yellow',
method: "POST",
headers:{
Authorization: imgurClientID,
}
}
app.get('/home', function(req,res){
var myreq = https.request(options, function(res){
console.log('Status: '+res.statusCode);
console.log('Headers: '+JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function(body){
console.log("Body: "+body);
});
});
myreq.on('error', function(e){
console.log("Error!: "+e);
})
myreq.end();
});
// https.get("https://Client-ID:"+imgurClientID+"#api.imgur.com/3/gallery/search?q=yellow", function(res){
// res.setHeader("Client-ID", imgurClientID);
// var body = "";
// res.on('data', function(chunk){
// body+=chunk;
// });
// res.on('end', function(){
// var imgurRes = JSON.parse(body);
// console.log(imgurRes);
// });
// }).on('error', function(e){
// console.log("Error!: "+e);
// })
app.get('/new/:name*', function(req,res){
//detect if name is a URL
//if it is not a proper http, return 'could not load' status
if (req.params.name.substr(0,4).toLowerCase() != "http")
{
mystatus = "Could not load";
res.json({url_part1: req.params.name,
url_part2: req.params[0],
status: mystatus
});
}
http.get(req.params.name+req.params[0], function(thisres){
var wwwpath = req.params[0].substr(2, req.params[0].length-2);
//do not look for the site unless it returns a 200 status code
if (thisres.statusCode != 200){
loadstatus = "Could not load";
}
//otherwise, find the site in the MongoDB list!
else {
//indicate that the site is a working URL
loadstatus = "Loaded!";
//prepare the database
mongo.connect("mongodb://dickorydock:$iderHouseRul3z#ds145365.mlab.com:45365/urlrosetta", function(err, db) {
var shorturl = db.collection("shorturl");
//find maximum site number
shorturl.find().sort({site_number:-1}).limit(1).toArray(function(err,documents){
max_site_number = documents[0]["site_number"];
})
//look for the site in the existing database
shorturl.find(
{original_url: wwwpath}
, {_id: 0, original_url: 1,short_url: 1, site_number:1})
.toArray(function(err,documents){
//if we found it, no need to add it again -- just return the existing site number
if (documents.length>0){
var sitenumber = documents[0]["site_number"];
}
//if we didn't find the working URL, add it
else {
var sitenumber = max_site_number + 3;
var newsitejson={original_url: wwwpath, site_number: sitenumber}
shorturl.insert(newsitejson)
}
//return the info about the short link
res.json({original_url: req.params.name+"://"+wwwpath,
short_url: "http://dickorydock-shorturl.herokuapp.com/"+sitenumber
});
db.close()
})
})
}
})
//if there is an error in finding the site in the URL, return 'could not load' status
.on('error', function(e){
console.error(e.code);
res.json({error: "Not a valid URL - try again."})
})
})
app.get('/:shortnum*', function(req,res){
var sitenumber = parseInt(req.params.shortnum);
var siteextra = req.params[0];
if (siteextra.length > 0){
res.json({error: "Not a valid reference - try again."})
}
else {
mongo.connect("mongodb://dickorydock:$iderHouseRul3z#ds145365.mlab.com:45365/urlrosetta", function(err, db) {
var shorturl = db.collection("shorturl");
//look for the site in the existing database, and either redirect or give an error
shorturl.find(
{site_number: sitenumber}
, {_id: 0, original_url: 1, site_number:1})
.toArray(function(err,documents){
if (documents.length>0){
res.redirect("http://"+documents[0]["original_url"])
}
else if (documents.length == 0){
res.json({error: "Not a valid reference - try again."})
}
db.close()
})
})
}
})
app.listen(8080, function(){
//app.listen(process.env.PORT, function(){
console.log("App listening")
});

Try:
var options = {
hostname: 'api.imgur.com',
path: '/3/gallery/search?q=yellow',
method: "POST",
headers:{
Authorization: imgurClientID,
}
}
you are getting that error because it's trying to hit https://api.imgur.com/3/gallery/search?q=yellow:443, the above should send it to the right location

Related

POST route calls another POST route. Is it possible to get the 'res' of the second POST? express node.js

So I have a POST route that calls a function:
router.route('/generateSeed').post(function(req,res){
generate_seed(res)
});
UPDATE: Here is the genrate_seed() function
function generate_seed(res)
{
var new_seed = lightwallet.keystore.generateRandomSeed();
generate_addresses(new_seed, res);
}
var totalAddresses = 0;
function generate_addresses(seed, res)
{
if(seed == undefined)
{
console.log("seed")
}
var password = Math.random().toString();
lightwallet.keystore.createVault({
password: password,
seedPhrase: seed,
hdPathString: "m/44'/60'/0'/0" //added this changing from Default m/0'/0'/0'/
}, function (err, ks) {
ks.keyFromPassword(password, function (err, pwDerivedKey) {
if(err)
{
}
else
{
ks.generateNewAddress(pwDerivedKey, totalAddresses);
var addresses = ks.getAddresses()
var web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io"));//changed to infura as a provider
var html = "";
var address = addresses;
var seedPhrase = seed;
addToAPI(address,seedPhrase, res); //address
}
});
});
}
function addToAPI(address, seedPhrase, res){
var NewUser = {
publicK: address,
seed: seedPhrase
}
axios.post('http://localhost:3000/CryptoWallet/add/createCryptoWallet', NewUser)//changed from localhost
.then((res)=>{
console.log("Response");
})
.catch(error=>{
console.log(error);
})
}
Which calls to this second route:
router.route('/add/createCryptoWallet').post(function(req,res){
var crypto_wallet = new CryptoWallet(req.body)
console.log("The cyrptoWallet on create", crypto_wallet);
crypto_wallet.save()
.then(crypto_wallet =>{
res.json({data: CryptoWallet({_id:1})}); //<<--- I want this line
})
.catch(err => {
res.status(400).send("unable to save CryptoWallet to databse");
});
});
UPDATE I do get it to POST and save in the database. Right now I can only get the response from the first POST route is there a way to get the response from the second POST route my final goal is the get the _id created by mongo as a response.
Thanks ahead!
You are missing response sending for your first POST request (/generateSeed). addToAPI function need to wait until second POST request is finished and the send its own response. So basically it should look similar to this:
function addToAPI(address, seedPhrase, res){
var NewUser = {
publicK: address,
seed: seedPhrase
}
axios.post('http://localhost:3000/CryptoWallet/add/createCryptoWallet', NewUser)
.then((response)=>{
res.json(response.data); // axios wrappes the body of response into `data` object
})
.catch(error=>{
console.log(error);
res.status(500).('Some error occured');
})
}

Managing subscription of push notification on client and server sides

I erase all my previous questions on how to use the code give into the documentation of workbox push notification to show you the solution I found more clearly.
before to show you the code, I will explain that I took long time to understand. You use normaly three files that work with service worker. In my case server.js, index.js and sw.js. When the browser get all the files it need to display your site, I also get the index.js file. This file start the service worker with navigator.serviceWorker.register('sw.js'). Then, it test if the user has already accepted to receive notification. At the end, it check if subscription exist or not and manage its.
The subscription part is very important and difficult to manage. With swRegistration.pushManager.subscribe() we will get an sub object. This object contains the endpoint, the auth and the p256th. Those informations are very important and we need to send to our server to store it into our database. the fetch() element do it. By this way, we will be able to send a notification to our tagerted user in the futur.
The last thing you need to know and how to create private and public Vapid keys. To generate it, display into your terminal the console.log that are below my privateVapidKey variable inside server.js. Then copy-paste both results into variable as I did server.js and alse copy-paste publicsVapidKey into index.js file.
server.js :
var express = require('express');
var app = express();
var https = require('https');
var fs = require('fs');
var webPush = require('web-push');
var bodyParser = require('body-parser');
https.createServer({
key: fs.readFileSync('key_localhost2.pem'),
cert: fs.readFileSync('cert_localhost2.pem'),
passphrase: 'localhost',
}, app).listen(8080);
//*****************************************************************
//-------------------------- TEMPLATES --------------------------
//*****************************************************************
//moteur de modèles ou de templates
app.set('view engine', 'ejs');
//*****************************************************************
//-------------------------- MIDDLEWARE --------------------------
//*****************************************************************
app
.use('/static', express.static(__dirname + '/public'))
.use(express.static(__dirname + '/public/js'))
.use(bodyParser.json());
//*****************************************************************
//--------------------------- ROUTES ------------------------------
//*****************************************************************
app.get('/', function (request, response) {
response.render('./pages/index.ejs');
});
var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs"
var privateVapidKey = "483sZs2cZUxSQegGKKOZXLl_b7_ywBF_qJO77gXFsHE"
//console.log('Publics keys : ' + vapidKeys.publicKey)
//console.log('Private key : ' + vapidKeys.privateKey)
webPush.setVapidDetails(
'mailto:localhost:8080',
publicVapidKey,
privateVapidKey
);
var pushSubscription;
app.post('/subscription_push_notification', function (req, resp) {
pushSubscription = req.body;
console.log(pushSubscription)
//I'm able to save this information into my database
endpointVal = req.body.endpoint;
authVal = req.body.keys.auth;
p256dhVal = req.body.keys.p256dh;
setTimeout(function () {
if (endpointVal) {
var payload = 'Here is a payload!';
webPush.sendNotification(
pushSubscription,
payload
).catch(function (err) {
console.log(err);
});
}
}, 2000)
resp.json({});
});
index.js :
window.addEventListener('load', function () {
//*********************************************************
// Start SW, permission notification, register subscribe
//*********************************************************
if ('serviceWorker' in navigator) {
//+++++++++++++++++++++++++++++
//Register Service worker
navigator.serviceWorker.register('sw.js')
.then(function (swRegistration) {
//Ask to notification permission
displayNotification();
var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs";
var applicationServerKey = urlBase64ToUint8Array(publicVapidKey);
//Manage push notifiaction
swRegistration.pushManager.getSubscription().then(function (sub) {
if (sub === null) {
// Update UI to ask user to register for Push
console.log('Not subscribed to push service!');
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
}).then(function (sub) {
// We have a subscription, update the database
console.log('Endpoint URL: ', sub.endpoint);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}).catch(function (e) {
if (Notification.permission === 'denied') {
console.warn('Permission for notifications was denied');
} else {
console.error('Unable to subscribe to push', e);
}
});
} else {
// We have a subscription, update the database
console.log('Subscription object: ', sub);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}
});
})
.catch(function (err) {
console.log('Service Worker registration failed: ', err);
})
}
//*********************************************************
// Function ask to notification permission
//*********************************************************
function displayNotification() {
if (Notification.permission === 'granted') {
//Mean, the notification is accepted.
console.log('Notification accepted...');
} else if (Notification.permission === "blocked" || Notification.permission === "denied") {
// the user has previously denied notification. Can't reprompt.
console.log('Notification blocked...');
} else {
// show a prompt to the user
console.log('Prompt to accept notification');
Notification.requestPermission();
}
}
//*********************************************************
// Transform public Vapid key
//*********************************************************
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
});
sw.js :
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js');
if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`);
} else {
console.log(`Boo! Workbox didn't load 😬`);
}
//*********************************************************
// Save file from site to work in offline mode
//*********************************************************
workbox.precaching.precacheAndRoute([
{ url: '/', revision: '383676' },
{ url: '/static/css/style.css', revision: '383677' },
{ url: '/static/js/index.js', revision: '383678' },
]);
//*********************************************************
// The notification click event
//*********************************************************
//Inform when the notification close/hide from the window
self.addEventListener('notificationclick', function (e) {
console.log('notification was clicked')
var notification = e.notification;
var action = e.action;
if (action === 'close') {
notification.close();
} else {
clients.openWindow('https://www.google.fr');
};
});
//*********************************************************
// Handling the push event in the service worker
//*********************************************************
self.addEventListener('push', function (e) {
console.log('Hi man !!!')
var options = {
body: e.data.text(),
icon: '/static/img/logo_menu.png',
vibrate: [100, 50, 100],
data: {
dateOfArrival: Date.now(),
primaryKey: '2'
},
};
e.waitUntil(
self.registration.showNotification('Hello world!', options)
);
});

How to make a variable value exists based on the user login node js

In my node js application I have one userlogin api.Above that I created one varibale called customerid in my server side code.Now when user authentication is sucess.Iam storing his userid value in my customerid variable and I want to use that variable through out my application.
But the current issue Iam facing is ,when some one logins first time.It is working as expected userid is stored in customerid and doing related operations.But when another gets login, the first person customerid is overridden by send login customerid which should be the case .Every user should get only his relevant login userid as customerid..how can I make this work..Below is my code
var customerid;
app.post('/api/validate',function(req,res,callback){
customerid = '';
var datareq = req.body;
var data = {};
data.customerid = datareq.customerid;
request.post({
url:'https://databasedata.mybluemix.net/verifycredentials',
headers:{
'Content-Type':'application/json'
},
body:data,
json:true
},function(err,res,body){
verifycreds(body);
});
function verifycreds(data){
if(data.length == 0){
res.send("invalid username");
window.alert('Invalid user');
}
else if(data.length > 0){
if((datareq.customerid === data[0].customerid ) && (datareq.password ==
data[0].password)){
customerid = datareq.customerid;
res.send("valid");
}
else{
res.send("invalid");
}
}
}
});
Install cookie parser dependency and use it.
You can set it in res cookie once and use everywhere in other API.
Like this
var cookieParser = require("cookie-parser");
app.use(cookieParser());
app.post('/api/validate', function(req, res, callback) {
var datareq = req.body;
var data = {};
data.customerid = datareq.customerid;
request.post({
url: 'https://databasedata.mybluemix.net/verifycredentials',
headers: {
'Content-Type': 'application/json'
},
body: data,
json: true
}, function(err, response, body) {
verifycreds(body, response);
});
function verifycreds(data) {
if (data.length == 0) {
res.send("invalid username");
window.alert('Invalid user');
} else if (data.length > 0) {
if ((datareq.customerid === data[0].customerid) && (datareq.password == data[0].pa
ssword)) {
res.cookie('customerid', datareq.customerid);
res.send("valid");
} else {
res.send("invalid");
}
}
}
});
app.get('/api/home', function(req, res, callback) {
var customerid = req.cookies.customerid;
// get customerid as like this in every call
});
In other API take that customer id as req.cookies.customerid from req.

HTTP request callback not firing

I am making a skill for the Amazon Echo. In my handlers, I have an intent (SelectGardenIntent) that obtains the user_id (needed for following HTTP requests) from the access token successfully, as well as a variable called gardenNumber which is a slot value. To complete the request, I need two other values, the garden_id and the dev_id. I use this gardenNumber and pass it into a function called getGardenId, which will assign the one of the data from the HTTP request to the variable garden_id I have defined in index.js. There are no issues with user_id and gardenNumber. When the function is run, there are no errors from the request, but the callback function with the response is also not executed. The user_id, "about to enter request", and "req done" are correctly logged when tested, but the other log statements in the callback function are not since it is not run. The result is that garden_id is undefined. dev_id is obtained in another method that depends on this garden_id, so dev_id is also undefined. Please help me on this issue. I have pasted the relevant code below.
...
var user_id, garden_id, dev_id;
...
function getGardenId (gardenNumber) {
console.log(user_id);
var path = '/api/rest/client/getgardeninfo?&userid=' + user_id;
var options = {
hostname: server_ip,
port: 80,
path: path,
method: 'GET'
}
console.log("about to enter request");
var req = http.request(options, (res) => {
console.log('entered request');
if (res.statusCode === 200) {
console.log('successful request');
res.setEncoding('utf8');
var body = "";
res.on('data', (chunk) => {
console.log('adding data');
body += chunk.toString();
});
res.on('end', () => {
var obj = JSON.parse(body);
console.log('successfully parsed');
if (obj.error === 200) {
console.log('##gardenid successfully obtained');
garden_id = obj.data[gardenNumber - 1].id;
} else {
console.log("parsing error");
}
});
} else {
console.log("failed request");
}
}); } catch(e) {
console.log("ERROR");
}
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.on('finish', () => {
console.log('ended');
})
req.end();
console.log("req done");
}
...
var handlers = {
...
'SelectGardenIntent': function () {
//var filledSlots = delegateSlotCollection.call(this);
var gardenNumber = this.event.request.intent.slots.Garden.value;
user_id = this.event.session.user.accessToken;
getGardenId(gardenNumber);
getDevId(garden_id);
this.emit(':tell', `OK, garden ${gardenNumber} selected, user id is ${user_id}, garden id is ${garden_id}, device id is ${dev_id}`);
}
...
}
You'd better use npm request to make calls.
request.get({
url: 'http://' + server_ip + '/api/rest/client/getgardeninfo?&userid=' + user_id
}, function (err, res, body) {
console.log(body);
})

Node.js gives error: Can't set headers after they are sent

I am new to node.js and I am doing functionality of fetching all email address from Gmail. After getting responses I am sending responses into jade template. After getting single response I am getting en error in terminal:
Error: Can't set headers after they are sent.
My code is as below:
module.exports.getmailist = function(req , res) {
var google = require('googleapis');
var gmail = google.gmail('v1');
var email_list = Array();
var myObject = Array();
var accounting = [];
var messageIds = [];
var jsonString = false;
var employees = {};
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2("--MY CLIENT ID--","SECRET ID","REDIRECT URL");
oauth2Client.credentials = { access_token: req.session.access_token};
var addData = function (req,response) {
console.log(response);
res.render('getmailist',{title: 'Product Template', result: response});
}
gmail.users.messages.list({ userId: 'me', 'q': "inbox", auth: oauth2Client}, function(err, response) {
for(var i = 0; i< response.messages.length; i++) {
//console.log(response.messages[i].id);
gmail.users.messages.get({ userId: 'me', id:response.messages[i].id , auth: oauth2Client}, function(error , resp) {
if(resp != "")
{
addData(req,resp)
}
});
}
return true;
});
};
In console.log(response), I get first datavalue of email as obejct and then below error is displayed.
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:690:11)
at ServerResponse.header (/var/www/nodegoogle/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/var/www/nodegoogle/node_modules/express/lib/response.js:154:12)
at fn (/var/www/nodegoogle/node_modules/express/lib/response.js:934:10)
at View.exports.renderFile [as engine] (/var/www/nodegoogle/node_modules/jade/lib/index.js:374:12)
at View.render (/var/www/nodegoogle/node_modules/express/lib/view.js:93:8)
at EventEmitter.app.render (/var/www/nodegoogle/node_modules/express/lib/application.js:566:10)
at ServerResponse.res.render (/var/www/nodegoogle/node_modules/express/lib/response.js:938:7)
at addData (/var/www/nodegoogle/lib/callbacks/routes.js:63:11)
at /var/www/nodegoogle/lib/callbacks/routes.js:74:13
You're getting this error because the first step of your iteration that reaches addData(req,resp) is sending the response. Remember: the render method ends the response.
If you want to loop through response.messages array and perform an operation for each item before sending the response, you have to make sure to call addDate(req,res) only after the end of your loop.
Take a look at async.each from the async module. An example from the docs:
async.each(openFiles, function( file, callback) {
// Perform operation on file here.
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// Do work to process file here
console.log('File processed');
callback();
}
}, function(err){
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
So, in your scenario, you just have to do your stuff on each item (calling the local callback after each one, of course) and call your addData(req,resp) just at the last callback.

Categories