mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Move all nodes into core subdirectory
This makes it easier to distinguish core nodes from those added later
This commit is contained in:
192
nodes/core/social/27-twitter.html
Normal file
192
nodes/core/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"><b>here</b></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> Log in as</label>
|
||||
<input type="text" id="node-input-twitter">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-user"><i class="icon-search"></i> Search</label>
|
||||
<select type="text" id="node-input-user" style="display: inline-block; vertical-align: middle; width:60%;">
|
||||
<option value="false">all public tweets</option>
|
||||
<option value="true">the tweets of who you follow</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tags"><i class="icon-tags"></i> for</label>
|
||||
<input type="text" id="node-input-tags" placeholder="comma-separated words, @ids, #tags">
|
||||
</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: Use commas without spaces between multiple search terms. Comma = OR, Space = AND.
|
||||
<br/>The Twitter API WILL NOT deliver 100% of all tweets.
|
||||
<br/>Tweets of who you follow will include their retweets and favourites.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twitter in">
|
||||
<p>Twitter input node. Watches either the public or the user's stream for tweets containing the configured search term.</p>
|
||||
<p>Sets the <b>msg.topic</b> to <i>tweets/</i> and then appends the senders screen name.</p>
|
||||
<p>Sets <b>msg.location</b> to the tweeters location if known.</p>
|
||||
<p>Sets <b>msg.tweet</b> to the full tweet object as documented by <a href="https://dev.twitter.com/docs/platform-objects/tweets">Twitter</a>.
|
||||
</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",required:true},
|
||||
name: {value:""},
|
||||
topic: {value:"tweets"}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "twitter.png",
|
||||
label: function() {
|
||||
return this.name||this.tags;
|
||||
},
|
||||
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>
|
209
nodes/core/social/27-twitter.js
Normal file
209
nodes/core/social/27-twitter.js
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* 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(process.env.NODE_RED_HOME+"/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||"tweets";
|
||||
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 == "true") { 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('site', { 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/core/social/32-feedparse.html
Normal file
57
nodes/core/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/core/social/32-feedparse.js
Normal file
75
nodes/core/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(process.env.NODE_RED_HOME+"/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);
|
||||
}
|
||||
}
|
||||
|
||||
|
50
nodes/core/social/61-email.html
Normal file
50
nodes/core/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/core/social/61-email.js
Normal file
55
nodes/core/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(process.env.NODE_RED_HOME+"/red/red");
|
||||
var nodemailer = require("nodemailer");
|
||||
var emailkey = require(process.env.NODE_RED_HOME+"/../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/core/social/61-imap.html
Normal file
54
nodes/core/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>
|
108
nodes/core/social/61-imap.js
Normal file
108
nodes/core/social/61-imap.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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(process.env.NODE_RED_HOME+"/red/red");
|
||||
var Imap = require('imap');
|
||||
var util = require('util');
|
||||
var oldmail = {};
|
||||
|
||||
try {
|
||||
var emailkey = RED.settings.email || require(process.env.NODE_RED_HOME+"/../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 fail(err) {
|
||||
util.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();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this.on("close", function() {
|
||||
if (this.interval_id != null) {
|
||||
clearInterval(this.interval_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("imap",ImapNode);
|
130
nodes/core/social/91-irc.html
Normal file
130
nodes/core/social/91-irc.html
Normal file
@@ -0,0 +1,130 @@
|
||||
<!--
|
||||
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() {
|
||||
var ircNode = RED.nodes.node(this.ircserver);
|
||||
return this.name||(ircNode?ircNode.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 for="node-input-sendObject"><i class="icon-check"></i> Action</label>
|
||||
<select type="text" id="node-input-sendObject" style="display: inline-block; vertical-align: middle; width:70%;">
|
||||
<option value="pay">Send msg.payload to channel</option>
|
||||
<option value="true">Send msg.payload to id in msg.topic</option>
|
||||
<option value="false">Send complete msg object to channel</option>
|
||||
</select>
|
||||
</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 the complete object will stringify the whole msg object before sending.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc out">
|
||||
<p>Sends messages to a channel on an IRC server</p>
|
||||
<p>You can send just the <b>msg.payload</b>, or the complete <b>msg</b> object to the selected channel,
|
||||
or you can select to use <b>msg.topic</b> to send the <b>msg.payload</b> to a specific user in the channel (private conversation).</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc out',{
|
||||
category: 'social-output',
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
sendObject: {value:"pay", required:true},
|
||||
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="#node-red">
|
||||
</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>
|
98
nodes/core/social/91-irc.js
Normal file
98
nodes/core/social/91-irc.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 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(process.env.NODE_RED_HOME+"/red/red");
|
||||
var irc = require("irc");
|
||||
var util = require("util");
|
||||
|
||||
// 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 = null;
|
||||
this.on("close", function() {
|
||||
if (this.ircclient != null) {
|
||||
this.ircclient.disconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("irc-server",IRCServerNode);
|
||||
|
||||
// The Input Node
|
||||
function IrcInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.ircserver = n.ircserver;
|
||||
this.serverConfig = RED.nodes.getNode(this.ircserver);
|
||||
if (this.serverConfig.ircclient == null) {
|
||||
this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, {
|
||||
channels: [this.serverConfig.channel]
|
||||
});
|
||||
this.serverConfig.ircclient.addListener('error', function(message) {
|
||||
util.log('[irc] '+ JSON.stringify(message));
|
||||
});
|
||||
}
|
||||
this.ircclient = this.serverConfig.ircclient;
|
||||
var node = this;
|
||||
|
||||
this.ircclient.addListener('message', function (from, to, message) {
|
||||
//util.log(from + ' => ' + to + ': ' + message);
|
||||
var msg = { "topic":from, "to":to, "payload":message };
|
||||
node.send(msg);
|
||||
});
|
||||
|
||||
}
|
||||
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.channel = this.serverConfig.channel;
|
||||
if (this.serverConfig.ircclient == null) {
|
||||
this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, {
|
||||
channels: [this.serverConfig.channel]
|
||||
});
|
||||
this.serverConfig.ircclient.addListener('error', function(message) {
|
||||
util.log('[irc] '+ JSON.stringify(message));
|
||||
});
|
||||
}
|
||||
this.ircclient = this.serverConfig.ircclient;
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
//console.log(msg,node.channel);
|
||||
if (msg._topic) { delete msg._topic; }
|
||||
if (node.sendAll == "false") {
|
||||
node.ircclient.say(node.channel, JSON.stringify(msg));
|
||||
}
|
||||
else {
|
||||
if (typeof msg.payload === "object") { msg.payload = JSON.stringify(msg.payload); }
|
||||
if (node.sendAll == "pay") {
|
||||
node.ircclient.say(node.channel, msg.payload);
|
||||
}
|
||||
else {
|
||||
var to = msg.topic || node.channel;
|
||||
node.ircclient.say(to, msg.payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("irc out",IrcOutNode);
|
Reference in New Issue
Block a user