How to refresh a Twit stream ? (Npm module & Twitter API) - node.js

I want to refresh a Twit stream.
I have a Twitter stream made with the npm module Twit (you can find it here: https://github.com/ttezel/twit ).
Here is my code:
Researches.find().observeChanges({
added: function(){
hashArray = Researches.find().fetch();
hashCount = Researches.find().count();
for(i=0; i<hashCount; i++){
hashArray[i]= hashArray[i].hashtag;
}
}
});
stream = T.stream('statuses/filter', {track: hashArray});
//Launch stream
stream.on('tweet', Meteor.bindEnvironment(function(tweet) {
//Get the hashtag of the tweet
tweetText = tweet.text;
tweetText = tweetText.toLowerCase();
//Get the hashtag of the current tweet
for(i=0; i<hashCount; i++){
var hashCompare = hashArray[i];
hashCompare = hashCompare.toLowerCase();
var isInString = tweetText.search(hashCompare);
if(isInString>=0)
goodHash = hashArray[i];
}
// Get the tweet informations
tweetToInsert = {
user: tweet.user.screen_name,
tweet: tweet.text,
picture: tweet.user.profile_image_url,
date: new Date().getTime(),
hashtag: goodHash
};
matchTweet = Tweets.findOne({tweet:tweetToInsert.tweet});
//Store tweets
if(matchTweet || (lastTweet.user == tweetToInsert.user) || (lastTweet.tweet == tweetToInsert.tweet)){
} else {
console.log(tweetToInsert.tweet);
Tweets.insert(tweetToInsert, function(error) {
if(error)
console.log(error);
});
}
//Store last tweet
lastTweet = {
user: tweetToInsert.user,
tweet: tweetToInsert.tweet
}
//Delete tweet overflow
nbTweet = Tweets.find({hashtag: goodHash}).count();
tweetToDelete = nbTweet-25;
if(nbTweet>25){
for(i=0; i<tweetToDelete;i++){
idDelete = Tweets.findOne({hashtag: goodHash});
Tweets.remove(idDelete._id);
}
}
}));
As you can see, I have an observe on my Researches Collection, with which I made an array with all the hashtag. Then, I made my stream using this array to track every of this hashtag.
Now, here is my problem. When I had a new hashtag to my collection, my array update himself with the new hashtag and is good. The problem is that the stream doesn't update himself.
What I have tried
I have tried to .stop() the stream, accorded to Twit documentation (this works fine), but when I tried to restart him with .start(), it don't work.
Here is the code I've tried:
Researches.find().observeChanges({
added: function(){
hashArray = Researches.find().fetch();
hashCount = Researches.find().count();
for(i=0; i<hashCount; i++){
hashArray[i]= hashArray[i].hashtag;
}
if(stream){
stream.stop();
stream.start();
}
}
});
So, do you know how to refresh/update a Twit stream or delete and created a new one, each time an hashtag is added to the collection.
Thanks

This github issue & comment answers your question: https://github.com/ttezel/twit/issues/90#issuecomment-41247402
Basically you will need to make a second stream and close the first one when you refresh your list.
var Twit = require('twit');
var twit = new Twit(config);
var stream1 = twit.stream('statuses/filter', { track: [ '#yolo' ] });
// ... some time passes ...
// initiate a new streaming connection with our updated track list
var stream2 = twit.stream('statuses/filter', { track: [ '#yolo', '#fun' ] });
stream2.once('connected', function (res) {
console.log('second stream connected')
// stop the first stream ASAP so twitter doesn't block us
stream1.stop();
stream2.on('tweet', function (tweet) {
// handle tweets
});
});

Related

How to connect my electron app using PouchDB (leveldb) with Cloudant or any other database that support couchDB and sync

I'm creating an electron app using pouchDB and I want the app to be able to diferents customers and sync the data between them. As an example I'm making the tutorial: https://github.com/nolanlawson/pouchdb-getting-started-todo, I adapt the code to electron and I created a noSQL database at cloudant.
At the moment I can save data but I cannot sync with my remote db that is in cloudant. Here is the endpoint I'm using to sync data between both database.
Here is the error that I'm getting.
Here is the code of my script.js
(function() {
'use strict';
var $ = document.querySelector.bind(document);
var ENTER_KEY = 13;
var newTodoDom = document.getElementById('new_todo');
var syncDom = document.getElementById('sync-wrapper');
// EDITING STARTS HERE (you dont need to edit anything above this line)
var NodePouchDB = require('pouchdb');
var db = new NodePouchDB('todos');
var couchdb = require('felix-couchdb')
var remoteCouch = couchdb.createClient(5984, 'https://ac725f4e-29ec-4614-8e96-02ebc74a529b-bluemix.cloudant.com/')
db.info(function(err, info) {
console.log("is working", info)
db.changes({
since: info.update_seq,
live: true
}).on('change', showTodos);
});
// We have to create a new todo document and enter it in the database
function addTodo(text) {
var todo = {
_id: new Date().toISOString(),
title: text,
completed: false
};
db.put(todo).then(function (result) {
console.log("everything is A-OK");
console.log(result);
}).catch(function (err) {
console.log('everything is terrible');
console.log(err);
});
}
// Show the current list of todos by reading them from the database
function showTodos() {
db.allDocs({include_docs: true, descending: true}).then(function(doc) {
redrawTodosUI(doc.rows);
}).catch(function (err) {
console.log(err);
});
}
function checkboxChanged(todo, event) {
todo.completed = event.target.checked;
console.log(todo);
db.put(todo);
}
// User pressed the delete button for a todo, delete it
function deleteButtonPressed(todo) {
db.remove(todo);
}
// The input box when editing a todo has blurred, we should save
// the new title or delete the todo if the title is empty
function todoBlurred(todo, event) {
var trimmedText = event.target.value.trim();
if (!trimmedText) {
db.remove(todo);
} else {
todo.title = trimmedText;
db.put(todo);
}
}
// Initialise a sync with the remote server
function sync() {
syncDom.setAttribute('data-sync-state', 'syncing');
var opts = {live: true};
db.sync(remoteCouch, opts, syncError);
}
// EDITING STARTS HERE (you dont need to edit anything below this line)
// There was some form or error syncing
function syncError() {
syncDom.setAttribute('data-sync-state', 'error');
}
// User has double clicked a todo, display an input so they can edit the title
function todoDblClicked(todo) {
var div = document.getElementById('li_' + todo._id);
var inputEditTodo = document.getElementById('input_' + todo._id);
div.className = 'editing';
inputEditTodo.focus();
}
// If they press enter while editing an entry, blur it to trigger save
// (or delete)
function todoKeyPressed(todo, event) {
if (event.keyCode === ENTER_KEY) {
var inputEditTodo = document.getElementById('input_' + todo._id);
inputEditTodo.blur();
}
}
// Given an object representing a todo, this will create a list item
// to display it.
function createTodoListItem(todo) {
var checkbox = document.createElement('input');
checkbox.className = 'toggle';
checkbox.type = 'checkbox';
checkbox.addEventListener('change', checkboxChanged.bind(this, todo));
var label = document.createElement('label');
label.appendChild( document.createTextNode(todo.title));
label.addEventListener('dblclick', todoDblClicked.bind(this, todo));
var deleteLink = document.createElement('button');
deleteLink.className = 'destroy';
deleteLink.addEventListener( 'click', deleteButtonPressed.bind(this, todo));
var divDisplay = document.createElement('div');
divDisplay.className = 'view';
divDisplay.appendChild(checkbox);
divDisplay.appendChild(label);
divDisplay.appendChild(deleteLink);
var inputEditTodo = document.createElement('input');
inputEditTodo.id = 'input_' + todo._id;
inputEditTodo.className = 'edit';
inputEditTodo.value = todo.title;
inputEditTodo.addEventListener('keypress', todoKeyPressed.bind(this, todo));
inputEditTodo.addEventListener('blur', todoBlurred.bind(this, todo));
var li = document.createElement('li');
li.id = 'li_' + todo._id;
li.appendChild(divDisplay);
li.appendChild(inputEditTodo);
if (todo.completed) {
li.className += 'complete';
checkbox.checked = true;
}
return li;
}
function redrawTodosUI(todos) {
var ul = document.getElementById('todo-list');
ul.innerHTML = '';
todos.forEach(function(todo) {
ul.appendChild(createTodoListItem(todo.doc));
});
}
function newTodoKeyPressHandler( event ) {
if (event.keyCode === ENTER_KEY) {
addTodo(newTodoDom.value);
newTodoDom.value = '';
}
}
function addEventListeners() {
newTodoDom.addEventListener('keypress', newTodoKeyPressHandler, false);
}
addEventListeners();
showTodos();
if (remoteCouch) {
sync();
}
})();
To get to where the problem sits, can you verify that you can speak to the Cloudant database normally, that is using curl from the command-line? Using curl, fetch a document by its _id, perhaps a document you created manually using the Cloudant dashboard. That should shake out any problems with authentication: I note you're using IAM, which isn't always straight-forward -- and to my knowledge, not supported by PouchDB (or wasn't, last time I looked).
If that is the problem, create a new Cloudant instance with IAM+Legacy credentials.

control doesnot enter in req.on in node.js

I am using req.on() inmy project but it doesnot enter in the function I don't know why because it was working till last night.
exports._login= function(req,res){
console.log("1111");
// Post data may be sent in chunks so need to build it up
var body ="";
console.log("here")
// From here without entering in funtion it goes to last line (outsidefunction)
req.on("data", (data) =>
{
console.log("in req.on function")
body += data;
console.log("abc"+body);
var vars = body.split("&");
console.log("vars "+vars);
var value =[];
for (var t = 0; t < vars.length; t++)
{
var pair = vars[t].split("=");
var key = decodeURIComponent(pair[0]);
var val = decodeURIComponent(pair[1]);
value.push( decodeURIComponent(pair[1]));
console.log(key + ":" + val);
}
console.log(value[0]+"******"+value[1]);
username=value[0];
userPassword=value[1]
console.log("out function")
username=req.query.usernamePost;
userPassword=req.query.passwordPost;
console.log(username+"hello");
});
console.log("last");
}
I cant figure out what is the problem kindly help

Issues with 'Follow' on Twitter API

I am working on a project where I want to follow two separate twitter accounts, and for a specific function to be called when each account tweets. I am using the Twitter API, Node.js and a NPM Module called Twit.
I have it working no problem when one account tweets but not for both of them:
I believe my issue may be here:
var stream = T.stream('statuses/filter', { follow: ( userID1 , userID2 ) });
If I have follow set to just one User it works fine, however with two it will only work with one. Furthermore, it only works with the second in the list so if its: userID1, user ID2 only userID2 will work. If its userID2, userID1 only userID1 will work.
Full code/logic here:
//SetUp info
var Twit = require('twit'); // NPM twit package
var config = require('./config'); // the config file to allow me access Auth Keys etc
var T = new Twit(config);//run config file
//end of setup
var userID1 = 'XXXXXXXXXXX1'; //TwitterAccount1
var userID2 = 'XXXXXXXXXXX2'; //TwitterAccount2
//these two lines set up the twitter API
var stream = T.stream('statuses/filter', { follow: ( userID1 , userID2 ) }); // here seems to be my issue?
stream.on('tweet', function (tweet) {
if (tweet.user.id == userID1 ) { // is tweet.user.id matches UserID1
DoStuff_1(); //call this function
} else if (tweet.user.id == userID2 ) { // if tweet.user.id matches UserID2
DoStuff_2(); // call this function instead
}
});
//Function for userID1
function DoStuff_1(){
console.log("Doing Stuff 1");
}
//Function for userID2
function DoStuff_2(){
console.log("Doing Stuff 2");
}
Any suggestions greatly appreciated!
You can do it all with some stream; simply make an array with the user ids and join them in the follow parameter like below:
var userId = ['XXXXXXXXXXX1','XXXXXXXXXXX2'];
var stream = T.stream('statuses/filter', { follow: userId.join(',') });
By establishing a separate stream for the Second user account it seems to work:
//SetUp info
var Twit = require('twit'); // NPM twit package
var config = require('./config'); // the config file to allow me access Auth Keys etc
var T = new Twit(config);//run config file
//end of setup
var userID1 = 'XXXXXXXXXXX1'; //TwitterAccount1
//these two lines set up the twitter API
var stream = T.stream('statuses/filter', { follow: ( userID1 ) }); // here seems to be my issue?
stream.on('tweet', function (tweet) {
if (tweet.user.id == userID1 ) { // is tweet.user.id matches UserID1
DoStuff_1(); //call this function
}
});
var userID2 = 'XXXXXXXXXXX2'; //TwitterAccount2
//Separate stream for UserID2
var stream = T.stream('statuses/filter', { follow: ( userID2 ) }); // here seems to be my issue?
stream.on('tweet', function (tweet) {
if (tweet.user.id == userID2 ) { // if tweet.user.id matches UserID2
DoStuff_2(); // call this function instead
}
});
//Function for userID1
function DoStuff_1(){
console.log("Doing Stuff 1");
}
//Function for userID2
function DoStuff_2(){
console.log("Doing Stuff 2");
}

How to get mail id of twitter account through nodejs

I am trying to get mail id from twitter user through nodejs at the result I only got tweets and other details of users but I don't get mail id. I attach my code anyone tell me whether my code is write way to get mail id
// twitter api script
var config = require("./config");
// In config file I have my consumer_key, consumer_secret, access_token_key,access_token_secret
var fs = require('fs');
var Twitter = require('twitter');
var client = new Twitter(config.twitter);
var writer = fs.createWriteStream('tweets.json')
var start_time = 0;
var handles = "";
fs.readFile('./t_handle.csv', 'utf8', function(err, contents) {
var params = {
'include_email' : true
};
handles = contents.split("\n");
writer.write("[");
handles.forEach(function(handle){
handle = handle.split("/")[3];
if(typeof handle !== 'undefined' && handle){
handle = handle.split("?")[0];
get_handle_tweets(handle,params);
}
});
});
function get_handle_tweets(handle){
client.get('statuses/user_timeline', { screen_name: handle }, function(error, tweets,params,response) {
if(error){
console.log(error);
}else{
tweets.forEach(function(tweet){
writer.write(JSON.stringify(tweet)+",\n");
});
}
});
}
First check if when you Authorize for your app in the Will be able to see field, "see your email address" is there , if not check if you have valid privacy policy and TOS URL since white listing the app is no longer required, also in php I had to Change 'include_email' : true to 'include_email' : 'true' sometime ago when I tried this, so that could be the issue.

Socket.io Client.emit not working inside if loop

I am starting with Node.js. I want to emit some data to client at the starting of every hour.
var d = new Date();
var a=d.getDate();
var h = d.getHours();
if(h<10){
h="0"+h;
}
if(d<10){
d="0"+d;
}
time=a+""+h;
//Message from redis
rClient.on("message", function(channel, message) {
var vals=message.split("#");
if(vals[1]!=time){
var msg="sending reset";
console.log(msg);
client.emit('hreset',msg);
time=vals[1];
}
}
inside client
socket.on('hreset', function(val) {
alert(val);
reset();
alert("reseting Data completed");
});
But it's not triggering the code in client. If I change the condition from != to == it's working fine and triggering every second. But not working in case of !=. It's going inside the if condition but not emitting the hreset.
You could use setInterval:
var obj = setInterval(yourFunc, 3600000); // 60*60*1000 ms
var yourFunc = function() {
client.emit("message", data);
};

Resources