How to stream tweets from specific accounts - javascript

I'm using the twitter npm package in an attempt to stream tweets from specified accounts.
I'm having trouble navigating the twitter api docs, so I'm a little confused.
I can hit the REST endpoint to get the specified user tweets info with:
var client = new Twitter({});
client.get('statuses/user_timeline', { screen_name: user }, function(error, tweets) {
if(error) throw error;
console.log(tweets);
});
How do I stream the tweets? Is it even possible? If not, how else could I accomplish this? I would like this to be as responsive and immediate as possible.

Figured it out...
var stream = client.stream('statuses/filter', { follow: userId });
stream.on('data', function(event) {
console.log(event && event.text);
});
This will client stream reader will display the tweets as they are made automatically.
Unfortunately, the screen_name of the user cannot be used, so you'll have to find that out beforehand.

I wrote the code below and was able to get last 20 tweets of a user and save them in a file log.txt.
var Twitter = require('twitter');
var fs = require("fs");
//Your keys go inside {}
var client = new Twitter({});
//These are the parameters for the API call
var params = {
screen_name: 'damiengold', //use damiengold instead of #damiengold
count: 20
};
//Perform the API call and return data
client.get('statuses/user_timeline.json', params, function(error, tweets, response) {
var dataToFile;
if (!error) {
for (var i = 0; i < tweets.length; i++) {
console.log(tweets[i].created_at + " " + tweets[i].text);
console.log("-------------------------------");
dataToFile = tweets[i].created_at + " " + tweets[i].text + "\n-----------\n";
//This block of code will append tweets to the file called "log.txt".
fs.appendFile("log.txt", dataToFile, function(err) {
// If the code experiences any errors it will log the error to the console.
if (err) {
return console.log(err);
}
})
}
}
console.log("Last 20 tweets are now displayed on the screen and saved in log.txt.");
});

Related

Problems with web scraping phantom js?

I am trying to scrape html from a webpage using phantom.js but then I am getting this strange error. When I run the script once, I am getting the correct response, but then when I try again, I am getting no response.
It looks like its loading forever. I don't want to call phantom.exit() as it stops the server. So, what could I be doing wrong?
var page = require('webpage').create(),
server = require('webserver').create();
var service = server.listen(8003, function (request, response) {
console.log('Request received at ' + new Date());
// TODO: parse `request` and determine where to go
page.open('https://www.sportpesa.co.ke/?sportId=1&league=76080&leagueName=la%20liga&top=0',function() {
setTimeout(function() {
var test = page.plainText
console.log(page.plainText);
response.write(page.plainText)
response.close();
page.close();
})
})
});
I think your problem is you are closing the page after the first time and then attempting to reuse it again. Per the docs, you should not do this
Close the page and releases the memory heap associated with it. Do not use the page instance after calling this.
Try recreating the page object upon each request, like so:
var webpage = require('webpage'),
server = require('webserver').create();
var service = server.listen(8003, function (request, response) {
console.log('Request received at ' + new Date());
let page = webpage.create()
// TODO: parse `request` and determine where to go
page.open('https://www.sportpesa.co.ke/?sportId=1&league=76080&leagueName=la%20liga&top=0',function() {
setTimeout(function() {
var test = page.plainText
console.log(page.plainText);
response.write(page.plainText)
response.close();
page.close();
})
})
});

Attaching base64 encoded file nodejs

I am trying to send a soap request with an attachment. Everything works fine except that the attachment i send is always of zero bytes. The soap server accepts a Base64 encoded file and i had achieved to do it in Java using the code
OutputStream outputStream = new ByteArrayOutputStream()
outputStream.writeTo(fileOutputStream);
Base64.encode(outputStream.toByteArray())//argument passed to the function which sends this to the SOAP API
I want to replicate the same with node but i am unable to do so. Below is the function i am using to achieve this. I am reading some files from the client and trying to send it to the SOAP API. I have marked the place in the code responsible to read and append the data the rest is just for reference.
function createSoapEntryWithAtt(req,response){
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
let filesArr = []
for(objkeys in files){
filesArr.push(files[objkeys])
}
return Promise.all(filesArr.map(item => {
return new Promise((res,rej) => {
var oldpath = item.path;
var newpath = 'C:/user/' + item.name;
**var data = fs.readFileSync(oldpath).toString('base64');
let result = []
for (var i = 0; i < data.length; i += 2)// trying to create a 64bit byte array
result.push('0x' + data[i] + '' + data[i + 1])**
console.log(result)
if(data)
res({ [`${item.name}`]: result })
rej("Error occured")
})
})).then(data => {
let url = config.url
var credentials = {
AuthenticationInfo: {
userName: "user",
password: "passwd"
}
}
let args = {
Notes: "Testing From Node App",
}
let count = 0
for (index in data) {
if (count <= 3) {
**for(keys in data[index]){
//console.log(data[index][keys])
args[`Attachment${++count}_Name`] = keys
args[`Attachment${++count}_Data`] = data[index][keys]//Attaching the file read
}
}**
}
soap.createClient(url, function (err, client) {
client.addSoapHeader(credentials)
client.CreateWorkInfo(args, function (err, res) {
if (err) {
console.log("Error is ----->" + err)
} else {
console.log("Response is -----> " + res)
response.end();
}
})
})
})
});
}
Please ignore this question .... and thanks and sorry if anyone wasted time on this question. The error was a careless mistake from my side in the line args["Attachment${++count}_Name"] = keys
args["Attachment${++count}_Data"] = data[index][keys]. Here as i am incrementing the count in both lines there is a mismatch in the sense that Attachment name will be 1 and then in the second line Attachment data will be 02 and hence the name does not contain any data.

My twitter bots are posting for each other, and I checked the code. It doesn't make sense

I made a twitter bot for my personal Twitter account last night, which turned out perfectly. I even deployed it to Heroku and it worked fine. However, today I built one for my business too, and when I deployed it on Heroku, the two bots started tweeting the same thing.
Here's my code for my personal bot:
console.log('bot is starting');
var Twit = require('twit');
var config = require('./businessconfig');
var T = new Twit(config);
//Setting up stream
var stream = T.stream('user');
//Anytime someone follows me
stream.on('follow', followed);
function followed(event) {
console.log('Follow event initiated');
var name = event.source.name;
var screenName = event.source.screen_name;
tweetIt('#' + screenName + ' , thanks for following! #twitterbot');
}
function tweetIt(txt) {
var tweet = {
status: txt
}
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response){
if (err) {
console.log(err);
}
else {
console.log("Your tweet was posted!");
}
}
}
This is in a file titled "business bot.js." The "businessconfig file is my Twitter API key stuff. Here's my personal bot code:
console.log('bot is starting');
var Twit = require('twit');
var config = require('./myconfig');
var T = new Twit(config);
//Setting up stream
var stream = T.stream('user');
//Anytime someone follows me
stream.on('follow', followed);
function followed(event) {
console.log('Follow event initiated');
var name = event.source.name;
var screenName = event.source.screen_name;
tweetIt('#' + screenName + ' , thanks for following! #twitterbot');
}
function tweetIt(txt) {
var tweet = {
status: txt
}
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response){
if (err) {
console.log(err);
}
else {
console.log("Your tweet was posted!");
}
}
}
It is the same code as the business bot, but they are in different folders and have different package.json files. When I run the node processes, they begin to post with each other. Why do they have a relationship? For instance, if someone follows my personal account, the personal account and business account both tweet "#... Thanks for following! #twitterbot." It doesn't make sense since I made them separately and even changed the file names multiple times. I checked the API keys and they are different. Why do they talk together? Thanks.

NodeJs Assertion failed on HTTP call (Mac)

var client = require('http');
var endpoint = apiEndpoint;
var request = client.get(endpoint, function(responseFromApi) {
var responseString = '';
responseFromApi.setEncoding('utf-8');
responseFromApi.on('data', function(data) {
responseString += data;
});
// To reformat the string response into Json...
responseFromApi.on('end', function() {
var jsonResponse = JSON.parse(responseString);
callback(jsonResponse);
});
});
I am making API calls using the method above, however on random instances my call fails due to the Assertion fail like below. Anyone has any idea how to fix this?
Assertion failed: (handle->type == UV_TCP || handle->type == UV_TTY || handle->type == UV_NAMED_PIPE), function uv___stream_fd, file ../deps/uv/src/unix/stream.c, line 1568.
Environment: Mac, Nodejs
Note: I have tested the same code on an AWS lambda server and never faced this issue. I am guessing this is a Mac only instance. Lord Google informed me that it is a Mac desync issue.
Same is true if trying to get data from a dynamoDB sitting on Amazon server using the code below...
// To get userID.
var userId = getUserIdFromContext(this);
if (!userId) {
callback('userId is not set.');
}
// To get table name.
var table = constants.dynamoDBTableName;
if(!table) {
callback('DynamoDB Table name is not set.');
}
// To set the DocumentClient.
if(!doc) {
doc = new aws.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
}
// To set the params.
var params = {
Key: {
CustomerId: userId
},
TableName: table,
ConsistentRead: true
};
// To get data from table.
var skillContext = this;
doc.get(params, function(err, data){
if(err) {
console.log('get error: ' + JSON.stringify(err, null, 4));
callback(err);
} else {
if(isEmptyObject(data)) {
callback('The object is empty.');
} else {
var userData = JSON.parse(data.Item['Data']);
extractUserData(skillContext, userData, callback);
}
}
});
}

avoiding while loop when checking if file exists

I have a node application that reads an uploaded file like so:
router.route('/moduleUpload')
.post(function (request, response) {
request.files.file.originalname = request.files.file.originalname.replace(/ +?/g, '');
var media = new Media(request.files.file, './user_resources/module/' + request.body.module_id + '/');
if (!fs.existsSync(media.targetDir)) {
fs.mkdirSync(media.targetDir, 0777, function (err) {
if (err) {
console.log(err);
response.send("ERROR! Can't make the directory! \n"); // echo the result back
}
});
fs.chmodSync(media.targetDir, 0777);
}
moveFile(media);
var token = jwt.encode({
mediaObject: media
}, require('../secret')());
response.status(200).json(token);
});
Now when this file is uploaded and status code 200 is recieved my system then calls the following route:
router.route('/resourcePath/:encodedString')
.all(function (req, res) {
var decoded = jwt.decode(req.params.encodedString, require('../secret')());
var mediaObject = decoded.mediaObject;
var ext = mediaObject.file.originalname.substr(mediaObject.file.originalname.lastIndexOf('.'));
var path = 'app_server' + mediaObject.targetDir.substring(1) + mediaObject.fileName + ext;
var fileExist = false;
res.status(200).send(path)
});
Now for some reason this call is being called before the file is correctly in place which results in that sometimes my users cannot see the content.
To make sure the file was in the folder i thought of the following code to add:
var fileExist = false;
while (!fileExist) {
if (fs.existsSync('/var/www/learningbankapp/'+path)) {
fileExist = true;
}
}
However im not sure that this a good solution namly because it goes against node.js nature. So my question is, is there a better way to do it?

Categories

Resources