Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull Request: Twitter-In node topics on input, refresh interval input #803

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions social/twitter/27-twitter.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-row">
<label for="node-input-pollInterval"><i class="fa fa-clock"></i> <span data-i18n="twitter.label.pollInterval"></span></label>
<input type="text" id="node-input-pollInterval" data-i18n="[placeholder]twitter.placeholder.pollInterval">
</div>
<div class="form-tips"><span data-i18n="[html]twitter.tip"></span></div>
</script>

Expand All @@ -108,7 +112,8 @@
tags: {value:""},
user: {value:"false",required:true},
name: {value:""},
inputs: {value:0}
inputs: {value:0},
pollInterval: {value:60000}
},
inputs: 0,
outputs: 1,
Expand Down Expand Up @@ -139,6 +144,7 @@
var userph = this._("twitter.placeholder.user");
var forlabel = this._("twitter.label.for");
var forph = this._("twitter.placeholder.for");
var pollInterval = this._("twitter.placeholder.pollInterval")
$("#node-input-user").change(function() {
var type = $("#node-input-user option:selected").val();
if (type == "user") {
Expand All @@ -156,7 +162,7 @@
$("#node-input-user").change();
},
oneditsave: function() {
if ($('#node-input-tags').val() === '' && $("#node-input-user option:selected").val() === 'false') {
if ($('#node-input-tags').val() === ''/* && $("#node-input-user option:selected").val() === 'false'*/) {
this.inputs = 1;
}
else {
Expand Down
81 changes: 66 additions & 15 deletions social/twitter/27-twitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ module.exports = function(RED) {
this.twitterConfig = RED.nodes.getNode(this.twitter);
this.poll_ids = [];
this.timeout_ids = [];
this.pollInterval=n.pollInterval || 60000;

var credentials = RED.nodes.getCredentials(this.twitter);
this.status({});
Expand All @@ -177,17 +178,60 @@ module.exports = function(RED) {
var node = this;
if (this.user === "true") {
// Poll User Home Timeline 1/min
this.poll(60000,"https://api.twitter.com/1.1/statuses/home_timeline.json");
this.poll(node.pollInterval,"https://api.twitter.com/1.1/statuses/home_timeline.json");
} else if (this.user === "user") {
var users = node.tags.split(/\s*,\s*/).filter(v=>!!v);
var tags= node.tags || "";
var users = tags.split(/\s*,\s*/).filter(v=>!!v);
/* // Block no longer reqd as accepts msg.payload
if (users.length === 0) {
node.error(RED._("twitter.warn.nousers"));
return;
}
*/


// Poll User timeline
node.lastMessageTS = new Date();
node.status({fill:"green",shape:"ring",text:"Initializing"});
users.forEach(function(user) {
node.poll(60000,"https://api.twitter.com/1.1/statuses/user_timeline.json",{screen_name: user});
node.poll(node.pollInterval,"https://api.twitter.com/1.1/statuses/user_timeline.json",{screen_name: user});
})

node.on("input", function(msg) { // sticky polling - identifies already tracked handles vs add/remove handles
var payloadtags=msg.payload.split(/\s*,\s*/).filter(v=>!!v);
var screennames=node.poll_ids.map(p=>p.asset.opts.screen_name);
var newusers=payloadtags.filter(x=>!screennames.includes(x));
var removeusers=screennames.filter(x=>!payloadtags.includes(x));
newusers.forEach(function(user) { //start tracking new users in msg.payload
node.warn("Twitter-In: New Handle: "+user)
node.status({fill:"green",shape:"ring",text:"Adding handles"});
node.lastMessageTS = new Date();
node.poll(node.pollInterval,"https://api.twitter.com/1.1/statuses/user_timeline.json",{screen_name: user});
});
removeusers.forEach(function(user) { // remove any tracked users missing from msg.payload
node.poll_ids.forEach((p,i)=>{
if(user===p.asset.opts.screen_name){
node.status({fill:"green",shape:"ring",text:"Removing handles"});
node.lastMessageTS = new Date();
node.warn("Twitter-In: Delete Handle: "+p.asset.opts.screen_name);
clearInterval(p.interval);
node.poll_ids.splice(i,1);
}
})
});
});

function checklastMessageTS() {
if(node.lastMessageTS != null){
var timeDiff = new Date() - node.lastMessageTS;
if(timeDiff > 5000){
node.status({fill:"yellow",shape:"ring",text:"Idle @ "+node.lastMessageTS.toLocaleTimeString()});
node.lastMessageTS=null;
}
}
}

node.interval = setInterval(checklastMessageTS, 1000);
} else if (this.user === "dm") {
node.pollDirectMessages();
} else if (this.user === "event") {
Expand Down Expand Up @@ -266,7 +310,7 @@ module.exports = function(RED) {
node.log(RED._("twitter.status.using-geo",{location:node.tags.toString()}));
}
}

// all public tweets
if (this.user === "false") {
node.on("input", function(msg) {
Expand Down Expand Up @@ -312,8 +356,11 @@ module.exports = function(RED) {
catch (err) {
node.error(err);
}


}
this.on('close', function() {
clearInterval(node.interval);
if (this.tout) { clearTimeout(this.tout); }
if (this.tout2) { clearTimeout(this.tout2); }
if (this.stream) {
Expand All @@ -328,7 +375,7 @@ module.exports = function(RED) {
}
if (this.poll_ids) {
for (var i=0; i<this.poll_ids.length; i++) {
clearInterval(this.poll_ids[i]);
clearInterval(this.poll_ids[i].interval);
}
}
});
Expand All @@ -342,7 +389,7 @@ module.exports = function(RED) {
TwitterInNode.prototype.poll = function(interval, url, opts) {
var node = this;
var opts = opts || {};
var pollId;
var pollId={};
opts.count = 1;
this.twitterConfig.get(url,opts).then(function(result) {
if (result.status === 429) {
Expand All @@ -359,12 +406,15 @@ module.exports = function(RED) {
if (res.length > 0) {
since = res[0].id_str;
}
pollId = setInterval(function() {
pollId.asset={url:url,opts:opts};
pollId.interval = setInterval(function() {
node.lastMessageTS = new Date();
node.status({fill:"blue",shape:"ring",text:"Polling"});
opts.since_id = since;
node.twitterConfig.get(url,opts).then(function(result) {
if (result.status === 429) {
node.warn("Rate limit hit. Waiting "+Math.floor(result.rateLimitTimeout/1000)+" seconds to try again");
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
node.poll(interval,url,opts);
},result.rateLimitTimeout))
Expand All @@ -378,7 +428,7 @@ module.exports = function(RED) {
// 'since_id parameter is invalid' - reset it for next time
delete opts.since_id;
}
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
node.poll(interval,url,opts);
},interval))
Expand Down Expand Up @@ -409,7 +459,7 @@ module.exports = function(RED) {
}
}).catch(function(err) {
node.error(err);
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
delete opts.since_id;
delete opts.count;
Expand All @@ -433,7 +483,7 @@ module.exports = function(RED) {
var node = this;
var opts = {};
var url = "https://api.twitter.com/1.1/direct_messages/events/list.json";
var pollId;
var pollId={};
opts.count = 50;
this.twitterConfig.get(url,opts).then(function(result) {
if (result.status === 429) {
Expand All @@ -457,11 +507,12 @@ module.exports = function(RED) {
if (messages.length > 0) {
since = messages[0].id;
}
pollId = setInterval(function() {
pollId.asset={url:url,opts:opts};
pollId.interval = setInterval(function() {
node.twitterConfig.get(url,opts).then(function(result) {
if (result.status === 429) {
node.warn("Rate limit hit. Waiting "+Math.floor(result.rateLimitTimeout/1000)+" seconds to try again");
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
node.pollDirectMessages();
},result.rateLimitTimeout))
Expand All @@ -471,7 +522,7 @@ module.exports = function(RED) {
var res = result.body;
if (res.errors) {
node.error(res.errors[0].message);
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
node.pollDirectMessages();
},interval))
Expand Down Expand Up @@ -532,7 +583,7 @@ module.exports = function(RED) {
}
}).catch(function(err) {
node.error(err);
clearInterval(pollId);
clearInterval(pollId.interval);
node.timeout_ids.push(setTimeout(function() {
node.pollDirectMessages();
},interval))
Expand Down
6 changes: 4 additions & 2 deletions social/twitter/locales/en-US/27-twitter.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
"copy-accessToken": "Create a new 'Access token & access token secret' and copy them",
"access_key": "Access token",
"access_secret": "Access token secret",
"enter-id": "Set your Twitter ID"
"enter-id": "Set your Twitter ID",
"pollInterval": "Poll Interval"
},
"placeholder": {
"for": "comma-separated words, @ids, #tags",
"user": "comma-separated @twitter handles"
"user": "comma-separated @twitter handles",
"pollInterval": "Time in milliseconds, default 60000 (1 minute)"
},
"search": {
"public": "all public tweets",
Expand Down