Node.js http post request with basic authentication - javascript

I can make this work with axios but as I want to do this with default http module for some reasons
Here is the code
var express = require("express");
const http = require('https');
var app = express();
app.listen(3000, function () {
var username = 'username';
var password = 'password';
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const data = JSON.stringify({
campaign_id: 'all',
start_date: '01/01/2010',
end_date: '05/31/2030',
return_type: 'caller_view',
criteria: {
phone: 98855964562
}
});
var hostName = "https://staging.crm.com";
var path = "/api/v1/caller_find";
const options = {
hostName: hostName,
path: path,
port: 3000,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
'Content-Length': data.length
}
};
const req = http.request(options, (res) => {
console.log('response is ' + res);
});
req.on('error', (error) => {
console.log('error is ' + error);
});
});
But it is throwing exception
connect ECONNREFUSED 127.0.0.1:443

It seems like you're providing the wrong options object (perhaps copied over from axios). The Node.js HTTP module takes host or hostname in options, while you're providing hostName.
Reference: https://nodejs.org/api/http.html#http_http_request_options_callback

I'm not entirely sure what you're trying to do. Any reason why you need your application to listen? I'm assuming the application you're posting to is hosted somewhere else, as you're attempting to listen to port 3000 while also making the request to an application on port 3000. If each application is on a different host, this should be fine. Nonetheless, you've at least got 3 issues here.
1) Your options object is incorrect. You're using hostName when it should be hostname. This is why you get the ECONNREFUSED 127.0.0.1:443 error; the options object for the https.request() method defaults hostname to localhost and port to 443.
2) Also, you never write your data object contents to the request stream.
3) Finally, you should listen to the data event to get the response back and write it to the console. I've updated your code as shown below:
var express = require("express");
const http = require('https');
var app = express();
app.listen(3000, function () {
var username = 'username';
var password = 'password';
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const data = JSON.stringify({
campaign_id: 'all',
start_date: '01/01/2010',
end_date: '05/31/2030',
return_type: 'caller_view',
criteria: {
phone: 98855964562
}
});
var hostName = "https://staging.crm.com";
var path = "/api/v1/caller_find";
const options = {
hostname: hostName,
path: path,
port: 3000,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
'Content-Length': Buffer.byteLength(data)
}
};
const req = http.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (error) => {
console.log('error is ' + error);
});
req.write(data);
req.end();
});

You cannot move your express application to AWS Lambda as is. There are tools such as claudia which can help you move the app to lambda and api gateway.
In your case, you can modify your code AWS Lambda as below
const http = require('https');
exports.myHandler = function (event, context, callback) {
var username = 'username';
var password = 'password';
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const data = JSON.stringify({
campaign_id: 'all',
start_date: '01/01/2010',
end_date: '05/31/2030',
return_type: 'caller_view',
criteria: {
phone: 98855964562
}
});
var hostName = "https://staging.crm.com";
var path = "/api/v1/caller_find";
const options = {
hostName: hostName,
path: path,
port: 3000,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
'Content-Length': data.length
}
};
const req = http.request(options, (res) => {
console.log('response is ' + res);
callback(null, res);
});
req.on('error', (error) => {
console.log('error is ' + error);
callback(error);
});
}
You have to invoke your lambda via API Gateway or via other AWS resources such as Alexa Skill Kit etc.
EDIT
You may try passing auth options as specified # https://github.com/request/request/blob/master/README.md#http-authentication

Related

Why am I getting the error "'request' is not defined"?

I'm trying to create an app with the Spotify API, but can't seem to get it to work. The error I'm getting is that 'request' is undefined and I've replaced it with JQuery too and that doesn't work either. Can anyone tell me why I might be getting that error and how to fix it? Should I be running it inside node.js in cmd?
var client_id = '?';
var client_secret = '?';
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
form: {
grant_type: 'client_credentials'
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var token = body.access_token;
}
else {
console.log(JSON.stringify(error))
}
});
The spotify documentation is out of date, as request is deprecated, and should no longer be used.
Instead, you can make a request with built-in Node.js libraries, as mentioned in the documentation.
It should be run with node.js, i.e. node <filename>
const https = require('https')
const client_id = 'CLIENT_ID'
const client_secret = 'CLIENT_SECRET'
const reqBody = JSON.stringify({
grant_type: 'client_credentials'
})
const authOptions = {
hostname: 'accounts.spotify.com',
port: 443,
path: '/api/token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64')),
'Content-Type': 'application/json',
'Content-Length': reqBody.length
}
}
const req = https.request(authOptions, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.write(reqBody);
req.end();

MissingProperty error in Microsoft Bot Framework Request

I am working on an app that uses the Microsoft Bot Framework. My app is written in Node. At this time, I am trying to POST an activity using the following code:
var https = require('https');
var token = '[receivedToken]';
var conversationId = '[conversationId]';
var options = {
host: 'directline.botframework.com',
port: 443,
headers: {
'Authorization': 'Bearer ' + token'
},
path: '/v3/directline/conversations/' + conversationId + '/activities',
method: 'POST'
};
var request = https.request(options, (res) => {
console.log(res.statusCode);
var body = [];
res.on('data', (d) => {
body.push(d);
});
res.on('end', () => {
var result = JSON.parse(Buffer.concat(body).toString());
console.log(result);
});
});
var info = {
type: 'message',
text: 'test',
from: { id: 'user_' + conversationId }
};
request.write(querystring.stringify(info));
request.end();
request.on('error', (err) => {
console.log(err);
});
When this code is ran, I receive an error. It's an error of status code 400 which has the following:
{
error: {
code: 'MissingProperty',
message: 'Invalid or missing activities in HTTP body'
}
}
I don't understand what property is missing though. Everything looks correct.
You missed Content-Type and Content-Length in your request headers.
Please consider the following code snippet:
var https = require('https');
var token = '[receivedToken]';
var conversationId = '[conversationId]';
var info = JSON.stringify({
type: 'message',
text: 'test',
from: { id: 'user_' + conversationId }
})
var options = {
host: 'directline.botframework.com',
port: 443,
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(info)
},
path: '/v3/directline/conversations/' + conversationId + '/activities',
method: 'POST'
};
var request = https.request(options, (res) => {
console.log(res.statusCode);
var body = [];
res.on('data', (d) => {
body.push(d);
});
res.on('end', () => {
var result = JSON.parse(Buffer.concat(body).toString());
console.log(result);
});
});
request.write(info);
request.end();
request.on('error', (err) => {
console.log(err);
});

node JS HTTP request does nothing using http request

I'm trying to send http post request using native node js http request.
I'm using the following code but nothing happens:
var http = require('http');
var options = {
hostname: '192.168.1.134',
port: '8082',
path: '/api',
method: 'POST',
headers: {'content-type': 'application/json',
'cache-control': 'no-cache'}
};
callback = function(response)
{
var result = [];
response.on('data', function (chunk)
{
result.push(chunk);
});
response.on('end', function ()
{
console.log("LOCAL END" + result);
});
}
var req = http.request(options, callback);
req.write(JSON.stringify(
{
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
}), 'utf8' ,
function(data)
{
console.log('flushed: ' + data);
});
req.end();
console.log(" - trying to post to example - done" );
But if i'm adding the following dummy calls i'm getting an answer from my local server as expected:
var options1 = {
hostname: 'www.google.com',
port: '80',
path: '/',
headers: {'cache-control': 'no-cache'}
};
callback1 = function(response1) {
var str = ''
response1.on('data', function (chunk) {
str += chunk;
});
response1.on('end', function () {
console.log("GOOGLE END" + str);
});
}
var req1 = http.request(options1, callback1);
req1.end();
console.log("sent to google - done");
What am i doing wrong?
Make sure 192.168.1.134:8082 is reachable and responding (using a browser, curl or wget) then try adding a content-length header:
var http = require('http');
var payload = JSON.stringify({
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
});
var options = {
hostname: '192.168.1.134',
port: 8082,
path: '/api',
method: 'POST',
headers: {
'content-length': Buffer.byteLength(payload), // <== here
'content-type': 'application/json',
'cache-control': 'no-cache'
}
};
var req = http.request(options, function(response) {
var result = [];
response.on('data', function(chunk) {
result.push(chunk);
});
response.on('end', function () {
console.log('LOCAL END' + result);
});
});
req.write(payload);
req.end();
Eventually, I discovered that the problem was with the device itself which had some kind of problem..
When sent http request to a direct ip address nothing happened but when sent to an address that need dns server it is working...
Unfortunately, I don't have any additional info about this bug...

node.js http and bing search api

I am trying to use the Bing Search API to return a JSON string. I first tried using the following url as per Azure's explore website (https://datamarket.azure.com/dataset/explore/5BA839F1-12CE-4CCE-BF57-A49D98D29A44):
'https://api.datamarket.azure.com/Bing/Search/v1/Composite?Sources=%27web%27&Query=%27NGI%20SPA%27&Market=%27en-US%27'
After, I found a SO thread Using the new Bing API (nodejs) which suggested I use a url of the form:
https://user:<YourDefaultAccountKey>#api.datamarket.azure.com/Bing/SearchWeb/Web?Query=%27leo%20fender%27&Market=%27en-US%27&$top=50&$format=JSON
Both of these return status 401 (Authentication Failure):
STATUS: 401
HEADERS: {"content-type":"application/json; charset=utf-8","server":"Microsoft-IIS/8.0","jsonerror":"true","x-powered-by":"ASP.NET","access-control-allow-origin":"*","access-control-allow-credentials":"false","access-control-allow-headers":"Authorization, DataServiceVersion, MaxDataServiceVersion","access-control-expose-headers":"DataServiceVersion, MaxDataServiceVersion","access-control-allow-methods":"GET, POST, OPTIONS","access-control-max-age":"604800","date":"Wed, 02 Jul 2014 17:23:29 GMT","content-length":"91"}
BODY: {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}
I have also tried other various combinations of URLs to no avail. My code is below:
var url = require('url');
var http = require('http');
var serviceRootURL = 'https://api.datamarket.azure.com/Bing/Search/v1/Composite?Sources=%27web%27&Query=%27NGI%20SPA%27&Market=%27en-US%27'
var params = 'hi';
var dataURL = url.parse(serviceRootURL);
var post_options = {
hostname: dataURL.hostname,
port: dataURL.port || 80,
path: dataURL.path,
method: 'GET',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': params.length
}
};
var req = http.request(post_options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
Any idea why I am getting an authentication failure?
You can use this module that encapsulates the requests, so you can use it
like:
var Bing = require('node-bing-api')({ accKey: "your-account-key" });
Bing.web("leo fender", function(error, res, body){
console.log(body);
},
{
top: 50,
market: 'en-US'
});
It works with the Azure version. You only have to replace your account key.
Got it working with request...weird
var request = require('request');
var _ = require('underscore');
var searchURL = 'https://user:<TIPE YOUR KEE HEER>#api.datamarket.azure.com/Bing/SearchWeb/v1/Web?Query=%27xbox%27&$top=10&$format=JSON';
var http = request( searchURL, function(err, resp, body)
{
if ( err )
{
throw err;
}
var a = JSON.parse(body);
console.log(a.d.results);
});
you can use jsearch module. install ;
npm install jsearch
usage;
js.bing('queryStringYouWant',10,function(response){
console.log(response) // for Bing results
})

How to pass response paramaters including body from POST http.request in NodeJS

I am trying to write a basic REST Post client to work with node.js and because of the REST API I have to work with I have to get details from the responses including cookies to maintain the state of my REST session with the server. My Question is what is the best way to pull the json objects from the response when res.on triggers with all the data in the PRINTME variable and return it to the test.js console.log().
test.js file
var rest = require('./rest');
rest.request('http','google.com','/upload','data\n');
console.log('PRINTME='JSON.stringify(res.PRINTME));
rest.js module
exports.request = function (protocol, host, path, data, cookie){
var protocalTypes = {
http: {
module: require('http')
, port: '80'
}
, https: {
module: require('https')
, port: '443'
}
};
var protocolModule = protocalTypes[protocol].module;
var options = {
host: host,
port: protocalTypes[protocol].port,
path: path,
method: 'POST',
headers: {
'Content-Type': 'text/xml'
, 'Content-Length': Buffer.byteLength(data)
, 'Cookie': cookie||''
}
};
console.log('cookies sent= '+options.headers.Cookie)
var req = protocolModule.request(options, function(res) {
var PRINTME = res;
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
PRINTME.body = chunk;
console.log('BODY: ' + chunk);
});
res.on('close', function () {res.emit('end')});
});
req.on('error', function(e) {
console.error('Request Failure: ' + e.message);
});
req.write(data);
req.end();
};
Using a package like request will help you simplify your code.
The following would be rest.js
var request = require('request');
module.exports = function(protocol, host, path, data, cookie, done) {
var options = {
host: host,
port: protocalTypes[protocol].port,
path: path,
method: 'POST',
headers: {
'Content-Type': 'text/xml',
'Content-Length': Buffer.byteLength(data)
},
jar: true
};
request(options, function(err, resp, body) {
if (err) return done(err);
// call done, with first value being null to specify no errors occured
return done(null, resp, body);
});
}
Setting jar to true will remember cookies for future use.
See this link for more information on the available options
https://github.com/mikeal/request#requestoptions-callback
To use this function in another file
var rest = require('./rest');
rest(... , function(err, resp, body){
...
});

Categories

Resources