Twitter API streaming request returning 401 - javascript

I am using Twitter for Node.js to make requests to the Twitter API, but I keep getting 401 Error which according to Twitter Docs means that there was an issue authenticating the request.
I am using the example from the twitter npm page:
const Twitter = require('twitter');
function twitter() {
var TwitterClient = new Twitter({
consumer_key: 'MY_KEY',
consumer_secret: 'MY_SECRET',
bearer_token: 'MY_TOKEN'
});
try {
TwitterClient.stream('statuses/filter', {
track: 'javascript'
}, function(stream) {
stream.on('data', function(event) {
console.log(event && event.text);
});
stream.on('error', function(error) {
try {
throw error;
}
catch (err) {
console.log(err);
}
});
});
} catch(e) {}
}
I get the following error in console:
Failed to load resource: the server responded with a status of 401 ()
Doing the GET request from the twitter npm page works fine:
var params = {screen_name: 'nodejs'};
TwitterClient.get('statuses/user_timeline', params, function(error, tweets, response) {
if (!error) {
console.log(tweets);
}
});
What I've tried:
Regenerated new tokens and double-checked them
Checked for updated system hour
Added access tokens and access secret to authentication
Thank you for your help

Related

Twitter api statuses/update throws an error of authorization

I am building a bot on twitter with javascript to send a post from my own twitter account. But I am getting the following error:
{
code: 220,
message: 'Your credentials do not allow access to this resource.'
}
I am not using OAuth since I will be the only user of this bot, I just want to send a twitter post inside a certain listener that watches for some event. Here is the inside of my function to send a post on twitter:
const Twitter = require('twitter')
const client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
bearer_token: process.env.TWITTER_BEARER_TOKEN
})
async function sendTwitterPost() {
try {
const response = await client.post('statuses/update', {
status: 'Event occured!',
})
console.log(response)
console.log("Success")
}
catch(err){
console.log(err)
console.log("ERROR WHILE SENDING TWITTER POST!")
}
}

How to consume a REST api that needs username/password authentication in node.js

I want to consume a REST api that needs a username/password authentication in node.js. The code that consumes the api is as follows:
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/'
request.get(url,{'auth': {'user': 'test35','pass': 'mypassword','sendImmediately': false}},function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
console.log('Post successful! Server responded with:', body);
});
With the above code, the error I get is:
{
"status": "error",
"message": "API endpoint does not exist"
}
The api is written in meteor restivus and you can see it in the following question's answer here
In the API, when I remove the api's authRequired: true, i.e, remove
{
routeOptions: {
authRequired: true
}
}
and in the code that consumes the API above, change url from
'http://localhost:3000/api/v1/login/
to:
http://localhost:3000/api/v1/articles/
and run "node accessRESTapi.js", I am able to consume the REST api! What I am not able to do correctly is the authentication when "authRequired: true" is set as per above! Please help
EDIT: Updated based on info from comments
The style of request is quite different between logging in to get a token and the subsequent requests:
For login
The docs specify that login actions must be done with a POST request to /api/login/ with a body that contains username or email and password as url-encoded params
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/'
var user = 'test35';
var pass = 'mypassword';
// Save these for future requests
var userId;
var authToken;
// Use POST instead of GET
request.post(
{
uri: url,
// I'm using form because it matches the urlEncoding behaviour expected by `restivus`
form: { username: user, password: pass }
},
function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
var json = JSON.parse(body);
authToken = json.data.authToken;
userId = json.data.userId;
console.log('Post successful! Server responded with:', body);
}
);
For future requests
Now you need to set the correct headers with the previously saved userId and authToken
According to the docs, that means X-User-Id and X-Auth-Token headers on all subsequent requests
var request = require('request');
var url = 'http://localhost:3000/api/v1/articles/'
request.get({
uri: url,
headers: {
'X-User-Id': userId,
'X-Auth-Token': authToken
}
}, function(err, httpResponse, body) {
if (err) {
return console.error('get failed:', err);
}
console.log('Get successful! Server responded with:', body);
});
Putting it together:
We want to make sure we get the authToken before making any further requests.
This means making the second request in the callback of the first function like so:
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/';
var user = 'test35';
var pass = 'mypassword';
// Save these for future requests
var userId;
var authToken;
// Use POST instead of GET
request.post(
{
uri: url,
// I'm using form because it matches the urlEncoding behaviour expected by `restivus`
form: { username: user, password: pass }
},
function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
var json = JSON.parse(body);
authToken = json.data.authToken;
userId = json.data.userId;
console.log('Post successful! Server responded with:', body);
// And now we make the second request
// Welcome to callback hell
var articlesUrl = 'http://localhost:3000/api/v1/articles/';
request.get({
uri: articlesUrl,
headers: {
'X-User-Id': userId,
'X-Auth-Token': authToken
}
}, function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
console.log('Get successful! Server responded with:', body);
});
}
);

transform $.get to node.js request

i'm using geolocation, i was handling everything on client side, now I wat to handle this from
Currently using it as;
var url = "youtube.com",
options = {
key: API_KEY,
video: "vid_id"
};
$.get(url, options, function(data) {
console.log(data)
})
I want to use it with nodeJS HTTPS, so i tried;
var https = require("https"),
url = "youtube.com",
options = {
key: API_KEY,
video: "vid_id"
};
https.get(url, options, function(data) {
console.log(data)
})
but i cant get it work I hope someone can convert this.
Try using the request module for node.js. Install it by running:
npm install request.
var request = require('request');
request(`youtube.com/?key=${key}&video=${video_id}`, function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('body:', body); // Print body of the response.
});

MYSQL + Node.JS Post Request Confusion

I am very new to networking and I have this code which, when I use a REST API like Postman, does exactly what I want it to do:
router.post('/', function(req,res,next){
var reqObj = req.body;
console.log(reqObj);
req.getConnection(function(err, conn){
if(err)
{
console.error('SQL Connection error: ', err);
return next(err);
}
else
{
var query = conn.query("INSERT INTO coordinates (id,lat,lon) VALUES(3,2,1);");
if(err)
{
console.error('SQL error: ', err);
return next(err);
}
res.json("Coordinates sent.");
}
})
} );
That is, it sends the query request to the MYSQL database. My question is, how do I do this without using Postman to send the POST request?
Thank you.
You can't unless you make a post request from within your application or something. If you don't intend on sending data, you can just make it a GET request by changing
router.post('/', function(req,res,next){
to
router.get('/', function(req,res,next){
Then you can just go to the relevant URL from your browser. If you're using chrome and you just wanna see the JSON data, I'd also recommend installing the JSONView chrome extension.
EDIT
Here's the example request using request-promise
var request = require('request-promise');
var objectData = {
name: 'Bruce',
alias: 'Batman'
};
var options = {
method: 'POST',
uri: 'http://your.api/endpoint/',
body: objectData,
json: true // Automatically stringifies the body to JSON
};
request(options).then(function(response){
// handle success response
}, function(error){
// handle error response
})

jsonp GET request 404 Error

I'm using Nodejs, Socket.io, and Angular to build a web app taking advantage of the Instagram Real-Time API. I'm running into an issue when I fire off GET requests to the Instagram API.
I get this error every time I send a GET request:
"Failed to load resource: the server responded with a status of 404 (NOT FOUND)"
The error details reveal:
https://api.instagram.com/v1/geographies/[object%20Object]/media/recent?client_id=MY_CLIENT_ID
Obviously that [object%20Object] is where the error lies. As my code below shows, that should be the 'geo_id' which I'm passing in as an argument. Geo_id is actually the 'object_id' of the Instagram real-time subscription.
Below is my code. Any idea where I'm going wrong?
Socket.io server side code:
io.sockets.on('connection', function(socket) {
// log user connections
console.log("user connected");
// receive the Instagram handshake for real-time subscriptions
app.get('/callback', function(req, res){
var handshake = Instagram.subscriptions.handshake(req, res);
});
// for each new post Instagram sends us the data
app.post('/callback', function(req, res) {
var data = req.body;
// grab the object_id (as geo_id) of the subscription and send as an argument to the client side
data.forEach(function(data) {
var geo_id = data.object_id;
sendUpdate(geo_id);
});
res.end();
});
// send the url with the geo_id to the client side
// to do the ajax call
function sendUpdate(geo_id) {
io.sockets.emit('newImage', { geo_id: geo_id });
}
// log user disconnections
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
relevant angular controller code:
socket.on('newImage', function(geo_id) {
// pass geo_id into Instagram API call
Instagram.get(geo_id).success(function(response) {
instagramSuccess(response.geo_id, response);
});
// Instagram API callback
var instagramSuccess = function(scope,res) {
if (res.meta.code !== 200) {
scope.error = res.meta.error_type + ' | ' + res.meta.error_message;
return;
}
if (res.data.length > 0) {
$scope.items = res.data;
} else {
scope.error = "This location has returned no results";
}
};
});
Instagram angular factory code:
angular.module('InstaFactory', []).factory('Instagram', function($http) {
var base = "https://api.instagram.com/v1";
var client_id = 'MY_CLIENT_ID';
return {
'get': function(geo_id) {
var request = '/geographies/' + geo_id + '/media/recent?client_id=' + client_id;
var url = base + request;
var config = {
'params': {
'callback': 'JSON_CALLBACK'
}
};
return $http.jsonp(url, config);
}
};
});

Categories