mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Got to start somewhere
This commit is contained in:
192
nodes/social/27-twitter.html
Normal file
192
nodes/social/27-twitter.html
Normal file
@@ -0,0 +1,192 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="twitter-credentials">
|
||||
<div class="form-row" id="node-config-twitter-row"></div>
|
||||
<input type="hidden" id="node-config-input-screen_name">
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var twitterConfigNodeId = null;
|
||||
var twitterConfigNodeIntervalId = null;
|
||||
|
||||
function showTwitterAuthStart() {
|
||||
var pathname = document.location.pathname;
|
||||
if (pathname.slice(-1) != "/") {
|
||||
pathname += "/";
|
||||
}
|
||||
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"twitter/"+twitterConfigNodeId+"/auth/callback");
|
||||
|
||||
$("#node-config-twitter-row").html('Click <a id="node-config-twitter-start" href="/twitter/'+twitterConfigNodeId+'/auth?callback='+callback+'" target="_blank">here</a> to authenticate with Twitter.');
|
||||
$("#node-config-twitter-start").click(function() {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
});
|
||||
}
|
||||
function updateTwitterScreenName(sn) {
|
||||
$("#node-config-input-screen_name").val(sn);
|
||||
$("#node-config-twitter-row").html('<label><i class="icon-user"></i> Twitter ID</label><span class="input-xlarge uneditable-input">'+sn+'</span>');
|
||||
}
|
||||
function pollTwitterCredentials(e) {
|
||||
$.getJSON('twitter/'+twitterConfigNodeId,function(data) {
|
||||
if (data.sn) {
|
||||
updateTwitterScreenName(data.sn);
|
||||
twitterConfigNodeIntervalId = null;
|
||||
} else {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
}
|
||||
})
|
||||
}
|
||||
RED.nodes.registerType('twitter-credentials',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
screen_name: {value:""},
|
||||
access_token: {value: ""},
|
||||
access_token_secret: {value:""}
|
||||
},
|
||||
label: function() {
|
||||
return this.screen_name;
|
||||
},
|
||||
exportable: false,
|
||||
oneditprepare: function() {
|
||||
twitterConfigNodeId = this.id;
|
||||
if (!this.screen_name || this.screen_name == "") {
|
||||
showTwitterAuthStart();
|
||||
} else {
|
||||
$.getJSON('twitter/'+twitterConfigNodeId,function(data) {
|
||||
if (data.sn) {
|
||||
updateTwitterScreenName(data.sn);
|
||||
} else {
|
||||
showTwitterAuthStart();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
oneditsave: function() {
|
||||
if (twitterConfigNodeIntervalId) {
|
||||
window.clearTimeout(twitterConfigNodeIntervalId);
|
||||
}
|
||||
},
|
||||
oneditcancel: function(adding) {
|
||||
if (twitterConfigNodeIntervalId) {
|
||||
window.clearTimeout(twitterConfigNodeIntervalId);
|
||||
}
|
||||
if (adding) {
|
||||
$.ajax({
|
||||
url: 'twitter/'+this.id,
|
||||
type: 'DELETE',
|
||||
success: function(result) {}
|
||||
});
|
||||
}
|
||||
},
|
||||
ondelete: function() {
|
||||
$.ajax({
|
||||
url: 'twitter/'+this.id,
|
||||
type: 'DELETE',
|
||||
success: function(result) {}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="twitter in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-twitter"><i class="icon-user"></i> Twitter</label>
|
||||
<input type="text" id="node-input-twitter">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tags"><i class="icon-tag"></i> Tags</label>
|
||||
<input type="text" id="node-input-tags" placeholder="comma-separated tags">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-user" placeholder="Name" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-user" style="width: 70%;">Tick to use user stream<br/>(rather than status/filter)</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic"><i class="icon-tasks"></i> Topic</label>
|
||||
<input type="text" id="node-input-topic" placeholder="Topic">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Tip: the Senders name gets appended to the topic heirarchy
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twitter in">
|
||||
<p>Twitter input node. Watches the public stream for tweets containing the configured search term.</p>
|
||||
<p>Sets the <b>msg.topic</b> to the configured topic and then appends the senders screen name.</p>
|
||||
<p>Sets <b>msg.location</b> to the tweeters location if known.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('twitter in',{
|
||||
category: 'social-input',
|
||||
color:"#C0DEED",
|
||||
defaults: {
|
||||
twitter: {type:"twitter-credentials",required:true},
|
||||
tags: {value:"",required:true},
|
||||
user: {value:false},
|
||||
name: {value:""},
|
||||
topic: {value:"tweets"}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "twitter.png",
|
||||
label: function() {
|
||||
return this.name||this.topic;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="twitter out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-twitter"><i class="icon-user"></i> Twitter</label>
|
||||
<input type="text" id="node-input-twitter">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twitter out">
|
||||
<p>Twitter out node. Tweets the <b>msg.payload</b>.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('twitter out',{
|
||||
category: 'social-output',
|
||||
color:"#C0DEED",
|
||||
defaults: {
|
||||
twitter: {type:"twitter-credentials",required:true},
|
||||
name: {value:"Tweet"}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "twitter.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name;
|
||||
}
|
||||
});
|
||||
</script>
|
211
nodes/social/27-twitter.js
Normal file
211
nodes/social/27-twitter.js
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var ntwitter = require('ntwitter');
|
||||
var OAuth= require('oauth').OAuth;
|
||||
|
||||
function TwitterNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.screen_name = n.screen_name;
|
||||
}
|
||||
RED.nodes.registerType("twitter-credentials",TwitterNode);
|
||||
|
||||
|
||||
function TwitterInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.active = true;
|
||||
this.user = n.user;
|
||||
this.tags = n.tags.replace(/ /g,'');
|
||||
this.twitter = n.twitter;
|
||||
this.topic = n.topic;
|
||||
this.twitterConfig = RED.nodes.getNode(this.twitter);
|
||||
var credentials = RED.nodes.getCredentials(this.twitter);
|
||||
|
||||
if (credentials && credentials.screen_name == this.twitterConfig.screen_name) {
|
||||
var twit = new ntwitter({
|
||||
consumer_key: "OKjYEd1ef2bfFolV25G5nQ",
|
||||
consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g",
|
||||
access_token_key: credentials.access_token,
|
||||
access_token_secret: credentials.access_token_secret
|
||||
});
|
||||
|
||||
var node = this;
|
||||
if (this.tags !== "") {
|
||||
try {
|
||||
var thing = 'statuses/filter';
|
||||
if (this.user) { thing = 'user'; }
|
||||
function setupStream() {
|
||||
if (node.active) {
|
||||
twit.stream(thing, { track: [node.tags] }, function(stream) {
|
||||
//twit.stream('user', { track: [node.tags] }, function(stream) {
|
||||
//twit.stream('statuses/filter', { track: [node.tags] }, function(stream) {
|
||||
node.stream = stream;
|
||||
stream.on('data', function(tweet) {
|
||||
//console.log(tweet.user);
|
||||
if (tweet.user !== undefined) {
|
||||
var where = tweet.user.location||"";
|
||||
var la = tweet.lang || tweet.user.lang;
|
||||
//console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay);
|
||||
var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet };
|
||||
node.send(msg);
|
||||
}
|
||||
});
|
||||
stream.on('error', function(tweet) {
|
||||
node.warn(tweet);
|
||||
setTimeout(setupStream,5000);
|
||||
});
|
||||
stream.on('destroy', function (response) {
|
||||
if (this.active) {
|
||||
node.warn("twitter ended unexpectedly");
|
||||
setTimeout(setupStream,5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
setupStream();
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
} else {
|
||||
this.error("Invalid tag property");
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
this.error("missing twitter credentials");
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.registerType("twitter in",TwitterInNode);
|
||||
|
||||
TwitterInNode.prototype.close = function() {
|
||||
if (this.stream) {
|
||||
this.active = false;
|
||||
this.stream.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function TwitterOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.topic = n.topic;
|
||||
this.twitter = n.twitter;
|
||||
this.twitterConfig = RED.nodes.getNode(this.twitter);
|
||||
var credentials = RED.nodes.getCredentials(this.twitter);
|
||||
var node = this;
|
||||
|
||||
if (credentials && credentials.screen_name == this.twitterConfig.screen_name) {
|
||||
var twit = new ntwitter({
|
||||
consumer_key: "OKjYEd1ef2bfFolV25G5nQ",
|
||||
consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g",
|
||||
access_token_key: credentials.access_token,
|
||||
access_token_secret: credentials.access_token_secret
|
||||
}).verifyCredentials(function (err, data) {
|
||||
if (err) {
|
||||
node.error("Error verifying credentials: " + err);
|
||||
} else {
|
||||
node.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
if (msg.payload.length > 140) {
|
||||
msg.payload = msg.payload.slice(0,139);
|
||||
node.warn("Tweet greater than 140 : truncated");
|
||||
}
|
||||
twit.updateStatus(msg.payload, function (err, data) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.registerType("twitter out",TwitterOutNode);
|
||||
|
||||
|
||||
|
||||
var oa = new OAuth(
|
||||
"https://api.twitter.com/oauth/request_token",
|
||||
"https://api.twitter.com/oauth/access_token",
|
||||
"OKjYEd1ef2bfFolV25G5nQ",
|
||||
"meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g",
|
||||
"1.0",
|
||||
null,
|
||||
"HMAC-SHA1"
|
||||
);
|
||||
|
||||
var credentials = {};
|
||||
|
||||
RED.app.get('/twitter/:id', function(req,res) {
|
||||
var credentials = RED.nodes.getCredentials(req.params.id);
|
||||
if (credentials) {
|
||||
res.send(JSON.stringify({sn:credentials.screen_name}));
|
||||
} else {
|
||||
res.send(JSON.stringify({}));
|
||||
}
|
||||
});
|
||||
|
||||
RED.app.delete('/twitter/:id', function(req,res) {
|
||||
RED.nodes.deleteCredentials(req.params.id);
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
RED.app.get('/twitter/:id/auth', function(req, res){
|
||||
var credentials = {};
|
||||
oa.getOAuthRequestToken({
|
||||
oauth_callback: req.query.callback
|
||||
},function(error, oauth_token, oauth_token_secret, results){
|
||||
if (error) {
|
||||
console.log(error);
|
||||
res.send("yeah no. didn't work.")
|
||||
}
|
||||
else {
|
||||
credentials.oauth_token = oauth_token;
|
||||
credentials.oauth_token_secret = oauth_token_secret;
|
||||
res.redirect('https://twitter.com/oauth/authorize?oauth_token='+oauth_token)
|
||||
RED.nodes.addCredentials(req.params.id,credentials);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
RED.app.get('/twitter/:id/auth/callback', function(req, res, next){
|
||||
|
||||
var credentials = RED.nodes.getCredentials(req.params.id);
|
||||
credentials.oauth_verifier = req.query.oauth_verifier;
|
||||
|
||||
oa.getOAuthAccessToken(
|
||||
credentials.oauth_token,
|
||||
credentials.token_secret,
|
||||
credentials.oauth_verifier,
|
||||
function(error, oauth_access_token, oauth_access_token_secret, results){
|
||||
if (error){
|
||||
console.log(error);
|
||||
res.send("yeah something broke.");
|
||||
} else {
|
||||
credentials = {};
|
||||
credentials.access_token = oauth_access_token;
|
||||
credentials.access_token_secret = oauth_access_token_secret;
|
||||
credentials.screen_name = "@"+results.screen_name;
|
||||
RED.nodes.addCredentials(req.params.id,credentials);
|
||||
res.send("<html><head></head><body>Authorised - you can close this window and return to Node-RED</body></html>");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
57
nodes/social/32-feedparse.html
Normal file
57
nodes/social/32-feedparse.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="feedparse">
|
||||
<div class="form-row">
|
||||
<label for="node-input-url"><i class="icon-globe"></i> Feed url</label>
|
||||
<input type="text" id="node-input-url">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-interval"><i class="icon-repeat"></i> Repeat <span style="font-size: 0.9em;">(M)</span></label>
|
||||
<input type="text" id="node-input-interval" placeholder="minutes">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<!-- <div class="form-tips"></div> -->
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="feedparse">
|
||||
<p>Monitors an RSS/atom feed for new entries.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('feedparse',{
|
||||
category: 'advanced-input',
|
||||
color:"#C0DEED",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
url: {value:"", required:true},
|
||||
interval: { value:15, required: true,validate:RED.validators.number()}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "feed.png",
|
||||
label: function() {
|
||||
return this.name||this.url;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
75
nodes/social/32-feedparse.js
Normal file
75
nodes/social/32-feedparse.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var FeedParser = require("feedparser");
|
||||
var request = require("request");
|
||||
|
||||
function FeedParseNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.url = n.url;
|
||||
this.interval = (parseInt(n.interval)||15)*60000;
|
||||
var node = this;
|
||||
this.interval_id = null;
|
||||
this.seen = {};
|
||||
if (this.url !== "") {
|
||||
var getFeed = function() {
|
||||
request(node.url,function(err) {
|
||||
if (err) node.error(err);
|
||||
})
|
||||
.pipe(new FeedParser({feedurl:node.url}))
|
||||
.on('error', function(error) {
|
||||
node.error(error);
|
||||
})
|
||||
.on('meta', function (meta) {})
|
||||
.on('article', function (article) {
|
||||
if (!(article.guid in node.seen) || ( node.seen[article.guid] != 0 && node.seen[article.guid] != article.date.getTime())) {
|
||||
node.seen[article.guid] = article.date?article.date.getTime():0;
|
||||
var msg = {
|
||||
topic:article.origlink||article.link,
|
||||
payload: article.description,
|
||||
article: {
|
||||
summary:article.summary,
|
||||
link:article.link,
|
||||
date: article.date,
|
||||
pubdate: article.pubdate,
|
||||
author: article.author,
|
||||
guid: article.guid,
|
||||
}
|
||||
};
|
||||
node.send(msg);
|
||||
}
|
||||
})
|
||||
.on('end', function () {
|
||||
});
|
||||
};
|
||||
this.interval_id = setInterval(getFeed,node.interval);
|
||||
getFeed();
|
||||
|
||||
} else {
|
||||
this.error("Invalid url");
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.registerType("feedparse",FeedParseNode);
|
||||
|
||||
FeedParseNode.prototype.close = function() {
|
||||
if (this.interval_id != null) {
|
||||
clearInterval(this.interval_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
55
nodes/social/57-notify.html
Normal file
55
nodes/social/57-notify.html
Normal file
@@ -0,0 +1,55 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="notify">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-tag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="notify">
|
||||
<p>Uses Growl to provide a desktop popup containing the <b>msg.payload</b>. Only useful on the local machine.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> as the title.</p>
|
||||
<p>Uses Growl so should work cross platform but will need pre-reqs installed... see <i><a href="https://npmjs.org/package/growl" target="_new">this link.</a></i></p>
|
||||
<p>If installing on Windows you MUST read the install instructions ... especially the bit about adding growlnotify to your path... or it WON'T work.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('notify',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "alert.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"notify";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
39
nodes/social/57-notify.js
Normal file
39
nodes/social/57-notify.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var growl = require('growl');
|
||||
var imagefile = __dirname+"/../../public/mqtt-node-red.png";
|
||||
|
||||
function NotifyNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.title||msg.topic;
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (typeof(titl) != 'undefined') {
|
||||
growl(msg.payload, { title: titl, image: imagefile });
|
||||
}
|
||||
else {
|
||||
growl(msg.payload, { image: imagefile });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("notify",NotifyNode);
|
61
nodes/social/57-prowl.html
Normal file
61
nodes/social/57-prowl.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="prowl">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-tag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-priority"><i class="icon-tag"></i> Priority</label>
|
||||
<input type="text" id="node-input-priority" placeholder="0">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="prowl">
|
||||
<p>Uses Prowl to push the <b>msg.payload</b> to an Apple device that has the prowl app installed.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> to set the title. You can also set <b>msg.priority</b> to confgure the urgency from -2 (low), through 0 (normal) to 2 (urgent).</p>
|
||||
<p>You MUST configure your prowl API key into the pushkey.js file in the directory above node-red.</p>
|
||||
<p><pre>module.exports = { prowl:'My-API-KEY' }</pre></p>
|
||||
<p>Uses Prowl so see <i><a href="https://www.prowlapp.com" target="_new">this link</a></i> for more details.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('prowl',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
priority: {value:0,required:true,validate:RED.validators.number()},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "prowl.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"prowl";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
56
nodes/social/57-prowl.js
Normal file
56
nodes/social/57-prowl.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var Prowl = require('node-prowl');
|
||||
|
||||
// pushkey.js just needs to be like (with the quotes)
|
||||
// module.exports = {prowl:'My-API-KEY'}
|
||||
|
||||
try {
|
||||
var pushkey = require("../../settings").prowl || require("../../../pushkey.js");
|
||||
} catch(err) {
|
||||
throw new Error("Failed to load Prowl credentials");
|
||||
}
|
||||
|
||||
var prowl = new Prowl(pushkey.prowl);
|
||||
|
||||
function ProwlNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
this.priority = n.priority * 1;
|
||||
if (this.priority > 2) this.priority = 2;
|
||||
if (this.priority < -2) this.priority = -2;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.title||msg.topic||"Node-RED";
|
||||
var pri = msg.priority||this.priority;
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
try {
|
||||
prowl.push(msg.payload, titl, { priority: pri }, function( err, remaining ){
|
||||
if ( err ) node.error(err);
|
||||
node.log( remaining + ' calls to Prowl api during current hour.' );
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("prowl",ProwlNode);
|
60
nodes/social/57-pushbullet.html
Normal file
60
nodes/social/57-pushbullet.html
Normal file
@@ -0,0 +1,60 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="pushbullet">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-tag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-priority"><i class="icon-tag"></i> Priority</label>
|
||||
<input type="text" id="node-input-priority" placeholder="0">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="pushbullet">
|
||||
<p>Uses PushBullet to push the <b>msg.payload</b> to an Android device that has PushBullet app installed.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> to set the title.</p>
|
||||
<p>You MUST configure both your API key and the target device ID into the pushkey.js file in the directory above node-red.<p>
|
||||
<p><pre>>module.exports = { pushbullet:'My-API-KEY', deviceid:'12345' }</pre</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('pushbullet',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
priority: {value:0,required:true,validate:RED.validators.number()},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "bullet.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"pushbullet";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
54
nodes/social/57-pushbullet.js
Normal file
54
nodes/social/57-pushbullet.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var PushBullet = require('pushbullet');
|
||||
|
||||
// pushkey.js just needs to be like (with the quotes)
|
||||
// module.exports = {pushbullet:'My-API-KEY', deviceid:'12345'}
|
||||
|
||||
try {
|
||||
var pushkey = require("../../settings").pushbullet || require("../../../pushkey.js");
|
||||
} catch(err) {
|
||||
throw new Error("Failed to load PushBullet credentials");
|
||||
}
|
||||
|
||||
var pusher = new PushBullet(pushkey.pushbullet);
|
||||
var deviceId = pushkey.deviceid;
|
||||
|
||||
function PushbulletNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
this.device
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.title||msg.topic||"Node-RED";
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
try {
|
||||
pusher.note(deviceId, titl, msg.payload, function(err, response) {
|
||||
if ( err ) node.error(err);
|
||||
node.log( JSON.stringify(response) );
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("pushbullet",PushbulletNode);
|
50
nodes/social/61-email.html
Normal file
50
nodes/social/61-email.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="email">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-envelope"></i> To</label>
|
||||
<input type="text" id="node-input-name" placeholder="email@address.com">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="email">
|
||||
<p>Sends the <b>msg.payload</b> as an email, with a subject of <b>msg.topic</b>.</p>
|
||||
<p>It sends the message to the configured recipient <i>only</i>.</p>
|
||||
<p><b>msg.topic</b> is used to set the subject of the email, and <b>msg.payload</b> is the body text.</p>
|
||||
<p>Uses the nodemailer module - you also need to pre-configure your email SMTP settings in ../../emailkeys.js - see INSTALL file for details.</p>
|
||||
<p><pre>module.exports = { service: "Gmail", user: "blahblah@gmail.com", pass: "password", server: "imap.gmail.com", port: "993" }</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('email',{
|
||||
category: 'social-output',
|
||||
color:"#c7e9c0",
|
||||
defaults: {
|
||||
name: {value:"",required:true}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "envelope.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.name||!this.topic)?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
55
nodes/social/61-email.js
Normal file
55
nodes/social/61-email.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var nodemailer = require("nodemailer");
|
||||
var emailkey = require("../../../emailkeys.js");
|
||||
|
||||
var smtpTransport = nodemailer.createTransport("SMTP",{
|
||||
service: emailkey.service,
|
||||
auth: {
|
||||
user: emailkey.user,
|
||||
pass: emailkey.pass
|
||||
}
|
||||
});
|
||||
|
||||
function EmailNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.topic = n.topic;
|
||||
this.name = n.name;
|
||||
var node = this;
|
||||
this.on("input", function(msg) {
|
||||
//node.log("email :",this.id,this.topic," received",msg.payload);
|
||||
if (msg != null) {
|
||||
|
||||
smtpTransport.sendMail({
|
||||
from: emailkey.user, // sender address
|
||||
to: node.name, // comma separated list of receivers
|
||||
subject: msg.topic, // Subject line
|
||||
text: msg.payload // plaintext body
|
||||
}, function(error, response) {
|
||||
if (error) {
|
||||
node.error(error);
|
||||
} else {
|
||||
node.log("Message sent: " + response.message);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("email",EmailNode);
|
54
nodes/social/61-imap.html
Normal file
54
nodes/social/61-imap.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="imap">
|
||||
<div class="form-row node-input-repeat">
|
||||
<label for="node-input-repeat"><i class="icon-repeat"></i>Repeat (S)</label>
|
||||
<input type="text" id="node-input-repeat" placeholder="300">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="imap">
|
||||
<p>Repeatedly gets a <b>single email</b> from an IMAP server and forwards on as a msg if not already seen.</p>
|
||||
<p>The subject is loaded into <b>msg.topic</b> and <b>msg.payload</b> is the body text. <b>msg.from</b> is also set if you need it.</p>
|
||||
<p>Uses the imap module - you also need to pre-configure your email settings in ../../emailkeys.js - see INSTALL file for details.</p>
|
||||
<p><pre>module.exports = { service: "Gmail", user: "blahblah@gmail.com", pass: "password", server: "imap.gmail.com", port: "993" }</pre></p>
|
||||
<p><b>Note:</b> this node <i>only</i> gets the most recent single email from the inbox, so set the repeat (polling) time appropriately.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('imap',{
|
||||
category: 'social-input',
|
||||
color:"#c7e9c0",
|
||||
defaults: {
|
||||
repeat: {value:"300",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "envelope.png",
|
||||
label: function() {
|
||||
return this.name||"IMAP";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.name||!this.topic)?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
114
nodes/social/61-imap.js
Normal file
114
nodes/social/61-imap.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var Imap = require('imap');
|
||||
var inspect = require('util').inspect;
|
||||
var oldmail = {};
|
||||
|
||||
try {
|
||||
var emailkey = require("../../settings").email || require("../../../emailkeys.js");
|
||||
} catch(err) {
|
||||
throw new Error("Failed to load Email credentials");
|
||||
}
|
||||
|
||||
var imap = new Imap({
|
||||
user: emailkey.user,
|
||||
password: emailkey.pass,
|
||||
host: emailkey.server||"imap.gmail.com",
|
||||
port: emailkey.port||"993",
|
||||
secure: true
|
||||
});
|
||||
|
||||
function show(obj) {
|
||||
return inspect(obj, false, Infinity);
|
||||
}
|
||||
|
||||
function fail(err) {
|
||||
console.log('[imap] : ' + err);
|
||||
}
|
||||
|
||||
function openInbox(cb) {
|
||||
imap.connect(function(err) {
|
||||
if (err) fail(err);
|
||||
imap.openBox('INBOX', true, cb);
|
||||
});
|
||||
}
|
||||
|
||||
function ImapNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.name = n.name;
|
||||
this.repeat = n.repeat * 1000;
|
||||
var node = this;
|
||||
this.interval_id = null;
|
||||
|
||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||
this.log("repeat = "+this.repeat);
|
||||
this.interval_id = setInterval( function() {
|
||||
node.emit("input",{});
|
||||
}, this.repeat );
|
||||
}
|
||||
|
||||
this.on("input", function(msg) {
|
||||
openInbox(function(err, mailbox) {
|
||||
if (err) fail(err);
|
||||
imap.seq.fetch(mailbox.messages.total + ':*', { struct: false },
|
||||
{ headers: ['from', 'subject'],
|
||||
body: true,
|
||||
cb: function(fetch) {
|
||||
fetch.on('message', function(msg) {
|
||||
//node.log('Saw message no. ' + msg.seqno);
|
||||
var pay = {};
|
||||
var body = '';
|
||||
msg.on('headers', function(hdrs) {
|
||||
pay.from = hdrs.from[0];
|
||||
pay.topic = hdrs.subject[0];
|
||||
});
|
||||
msg.on('data', function(chunk) {
|
||||
body += chunk.toString('utf8');
|
||||
});
|
||||
msg.on('end', function() {
|
||||
pay.payload = body;
|
||||
if ((pay.topic !== oldmail.topic)|(pay.payload !== oldmail.payload)) {
|
||||
oldmail = pay;
|
||||
//node.log("From: "+pay.from);
|
||||
node.log("Subj: "+pay.topic);
|
||||
//node.log("Body: "+pay.payload);
|
||||
node.send(pay);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}, function(err) {
|
||||
if (err) node.log("Err : "+err);
|
||||
//node.log("Done fetching messages.");
|
||||
imap.logout();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("imap",ImapNode);
|
||||
|
||||
ImapNode.prototype.close = function() {
|
||||
if (this.interval_id != null) {
|
||||
clearInterval(this.interval_id);
|
||||
this.log("inject: repeat stopped");
|
||||
}
|
||||
}
|
||||
|
126
nodes/social/91-irc.html
Normal file
126
nodes/social/91-irc.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="irc in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="icon-tasks"></i> IRC Server</label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc in">
|
||||
<p>Connects to a channel on an IRC server</p>
|
||||
<p>Any messages on that channel will appear on the <b>msg.payload</b> at the output, while <b>msg.topic</b> will contain who it is from.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc in',{
|
||||
category: 'social-input',
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
ircserver: {type:"irc-server", required:true}
|
||||
},
|
||||
color:"Silver",
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "hash.png",
|
||||
label: function() {
|
||||
return this.name||(this.ircserver)?RED.nodes.node(this.ircserver).label():"irc";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="irc out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="icon-tasks"></i> IRC Server</label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-sendObject" placeholder="" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-sendObject" style="width: 70%;">Send complete msg object ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Sending complete object will stringify the whole msg object before sending.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc out">
|
||||
<p>Connects to a channel on an IRC server</p>
|
||||
<p>If you send something with NO msg.topic it will go to the channel - otherwise it will go to the id in the <b>msg.topic</b> field.</p>
|
||||
<p>You can either just send the <b>msg.payload</b>, or you can send the complete <b>msg</b> object.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc out',{
|
||||
category: 'social-output',
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
sendObject: {value:false},
|
||||
ircserver: {type:"irc-server", required:true}
|
||||
},
|
||||
color:"Silver",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "hash.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name || (this.ircserver)?RED.nodes.node(this.ircserver).label():"irc";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="irc-server">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-server"><i class="icon-tasks"></i> IRC Server</label>
|
||||
<input type="text" id="node-config-input-server" placeholder="irc.UK-IRC.net">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-channel"><i class="icon-tasks"></i> Channel</label>
|
||||
<input type="text" id="node-config-input-channel" placeholder="#testing1234">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-nickname"><i class="icon-tasks"></i> Nickname</label>
|
||||
<input type="text" id="node-config-input-nickname" placeholder="joe123">
|
||||
</div>
|
||||
<div class="form-tips">The channel to join must start with a # (as per normal irc rules...)</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc-server',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
channel: {value:"",required:true,validate:RED.validators.regex(/^#/)},
|
||||
server: {value:"",required:true},
|
||||
nickname: {value:"",required:true}
|
||||
},
|
||||
label: function() {
|
||||
return this.server+":"+this.channel;
|
||||
}
|
||||
});
|
||||
</script>
|
84
nodes/social/91-irc.js
Normal file
84
nodes/social/91-irc.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var irc = require("irc");
|
||||
|
||||
// The Server Definition - this opens (and closes) the connection
|
||||
function IRCServerNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.server = n.server;
|
||||
this.channel = n.channel;
|
||||
this.nickname = n.nickname;
|
||||
this.ircclient = new irc.Client(this.server, this.nickname, {
|
||||
channels: [this.channel]
|
||||
});
|
||||
this._close = function() {
|
||||
this.ircclient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.registerType("irc-server",IRCServerNode);
|
||||
|
||||
IRCServerNode.prototype.close = function() {
|
||||
this._close();
|
||||
}
|
||||
|
||||
|
||||
// The Input Node
|
||||
function IrcInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.ircserver = n.ircserver;
|
||||
this.serverConfig = RED.nodes.getNode(this.ircserver);
|
||||
this.ircclient = this.serverConfig.ircclient;
|
||||
var node = this;
|
||||
|
||||
|
||||
this.ircclient.addListener('message', function (from, to, message) {
|
||||
console.log(from + ' => ' + to + ': ' + message);
|
||||
var msg = { "topic":from, "to":to, "payload":message };
|
||||
node.send(msg);
|
||||
});
|
||||
|
||||
this.ircclient.addListener('error', function(message) {
|
||||
node.error(JSON.stringify(message));
|
||||
});
|
||||
|
||||
}
|
||||
RED.nodes.registerType("irc in",IrcInNode);
|
||||
|
||||
// The Output Node
|
||||
function IrcOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.sendAll = n.sendObject;
|
||||
this.ircserver = n.ircserver;
|
||||
this.serverConfig = RED.nodes.getNode(this.ircserver);
|
||||
this.ircclient = this.serverConfig.ircclient;
|
||||
this.channel = this.serverConfig.channel;
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
console.log(msg);
|
||||
if (node.sendAll) {
|
||||
node.ircclient.say(node.channel, JSON.stringify(msg));
|
||||
}
|
||||
else {
|
||||
var to = msg.topic || node.channel;
|
||||
node.ircclient.say(to, msg.payload);
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("irc out",IrcOutNode);
|
80
nodes/social/92-xmpp.html
Normal file
80
nodes/social/92-xmpp.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="xmpp">
|
||||
<div class="form-row">
|
||||
<label for="node-input-server"><i class="icon-bookmark"></i> Server</label>
|
||||
<input type="text" id="node-input-server" placeholder="talk.google.com" style="width: 40%;" >
|
||||
<label for="node-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||
<input type="text" id="node-input-port" placeholder="Port" style="width:45px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-sendObject" placeholder="" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-sendObject" style="width: 70%;">Send complete msg object ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-to"><i class="icon-envelope"></i> To</label>
|
||||
<input type="text" id="node-input-to" placeholder="joe@gmail.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-join" placeholder="" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-join" style="width: 70%;">Is a Chat Room ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-nick"><i class="icon-user"></i> Nickname</label>
|
||||
<input type="text" id="node-input-nick" placeholder="Joe">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">The <b>To</b> field is optional. If not set uses the <b>msg.topic</b> property of the message.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="xmpp">
|
||||
<p>Connects to an XMPP server to send and receive messages.</p>
|
||||
<p>Incoming messages will appear as <b>msg.payload</b> on the first output, while <b>msg.topic</b> will contain who it is from.</p>
|
||||
<p>The second output will user presence and status in <b>msg.payload</b>.</p>
|
||||
<p>The <b>To</b> field is optional. If not set uses the <b>msg.topic</b> property of the message.</p>
|
||||
<p>If you are joining a room then the <b>To</b> field must be filled in.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('xmpp',{
|
||||
category: 'advanced-function',
|
||||
color:"Silver",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
server: { value:"",required:true},
|
||||
port: {value:5222,required:true},
|
||||
to: {value:""},
|
||||
join: {value:"false"},
|
||||
sendObject: { value:false },
|
||||
nick: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:2,
|
||||
icon: "xmpp.png",
|
||||
label: function() {
|
||||
return this.name||this.server||"xmpp";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.name||!this.server)?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
113
nodes/social/92-xmpp.js
Normal file
113
nodes/social/92-xmpp.js
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var xmpp = require('simple-xmpp');
|
||||
|
||||
try {
|
||||
var xmppkey = require("../../settings").xmpp || require("../../../xmppkeys.js");
|
||||
} catch(err) {
|
||||
throw new Error("Failed to load XMPP credentials");
|
||||
}
|
||||
|
||||
function XmppNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.server = n.server;
|
||||
this.port = n.port;
|
||||
this.join = n.join || false;
|
||||
this.nick = n.nick || "Node-RED";
|
||||
this.sendAll = n.sendObject;
|
||||
this.to = n.to || "";
|
||||
var node = this;
|
||||
|
||||
setTimeout(function() {
|
||||
xmpp.connect({
|
||||
jid : xmppkey.jid,
|
||||
password : xmppkey.password,
|
||||
host : this.server,
|
||||
port : this.port,
|
||||
skipPresence : true,
|
||||
reconnect : false
|
||||
});
|
||||
}, 5000);
|
||||
|
||||
xmpp.on('online', function() {
|
||||
node.log('connected to '+node.server);
|
||||
xmpp.setPresence('online', node.nick+' online');
|
||||
if (node.join) {
|
||||
xmpp.join(node.to+'/'+node.nick);
|
||||
}
|
||||
});
|
||||
|
||||
xmpp.on('chat', function(from, message) {
|
||||
var msg = { topic:from, payload:message };
|
||||
node.send([msg,null]);
|
||||
});
|
||||
|
||||
xmpp.on('groupchat', function(conference, from, message, stamp) {
|
||||
var msg = { topic:from, payload:message, room:conference };
|
||||
if (from != node.nick) { node.send([msg,null]); }
|
||||
});
|
||||
|
||||
//xmpp.on('chatstate', function(from, state) {
|
||||
//console.log('%s is currently %s', from, state);
|
||||
//var msg = { topic:from, payload:state };
|
||||
//node.send([null,msg]);
|
||||
//});
|
||||
|
||||
xmpp.on('buddy', function(jid, state, statusText) {
|
||||
node.log(jid+" is "+state+" : "+statusText);
|
||||
var msg = { topic:jid, payload: { presence:state, status:statusText} };
|
||||
node.send([null,msg]);
|
||||
});
|
||||
|
||||
xmpp.on('error', function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
xmpp.on('close', function(err) {
|
||||
node.log('connection closed');
|
||||
});
|
||||
|
||||
xmpp.on('subscribe', function(from) {
|
||||
xmpp.acceptSubscription(from);
|
||||
});
|
||||
|
||||
this.on("input", function(msg) {
|
||||
var to = msg.topic;
|
||||
if (node.to != "") { to = node.to; }
|
||||
if (node.sendAll) {
|
||||
xmpp.send(to, JSON.stringify(msg), node.join);
|
||||
}
|
||||
else {
|
||||
xmpp.send(to, msg.payload, node.join);
|
||||
}
|
||||
});
|
||||
|
||||
this._close = function() {
|
||||
xmpp.setPresence('offline');
|
||||
//xmpp.conn.end();
|
||||
// TODO - DCJ NOTE... this is not good. It leaves the connection up over a restart - which will end up with bad things happening...
|
||||
// (but requires the underlying xmpp lib to be fixed (which does have an open bug request on fixing the close method)).
|
||||
this.warn("Due to an underlying bug in the xmpp library this does not disconnect old sessions. This is bad... A restart would be better.");
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.registerType("xmpp",XmppNode);
|
||||
|
||||
XmppNode.prototype.close = function() {
|
||||
this._close();
|
||||
}
|
Reference in New Issue
Block a user