diff --git a/social/twitter/27-twitter.html b/social/twitter/27-twitter.html
index 57ea833b3..eee02c4f1 100644
--- a/social/twitter/27-twitter.html
+++ b/social/twitter/27-twitter.html
@@ -96,6 +96,10 @@
+
+
+
+
@@ -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,
@@ -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") {
@@ -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 {
diff --git a/social/twitter/27-twitter.js b/social/twitter/27-twitter.js
index ac037bee8..caa9953af 100644
--- a/social/twitter/27-twitter.js
+++ b/social/twitter/27-twitter.js
@@ -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({});
@@ -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") {
@@ -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) {
@@ -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) {
@@ -328,7 +375,7 @@ module.exports = function(RED) {
}
if (this.poll_ids) {
for (var i=0; i 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))
@@ -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))
@@ -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;
@@ -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) {
@@ -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))
@@ -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))
@@ -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))
diff --git a/social/twitter/locales/en-US/27-twitter.json b/social/twitter/locales/en-US/27-twitter.json
index 4282327da..739262a3e 100644
--- a/social/twitter/locales/en-US/27-twitter.json
+++ b/social/twitter/locales/en-US/27-twitter.json
@@ -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",