Fix merge conflicts on i18n

This commit is contained in:
Nick O'Leary
2015-07-15 10:24:44 +01:00
35 changed files with 660 additions and 379 deletions

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2013,2014 IBM Corp.
Copyright 2013, 2015 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
<script type="text/x-red" data-template-name="e-mail">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-envelope"></i> To</label>
<label for="node-input-name"><i class="fa fa-envelope"></i> <span data-i18n="email.label.to"></span></label>
<input type="text" id="node-input-name" placeholder="email@address.com">
</div>
<!-- <div class="form-row">
@@ -45,27 +45,27 @@
</select>
</div> -->
<div class="form-row">
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
<label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="email.label.server"></span></label>
<input type="text" id="node-input-server" placeholder="smtp.gmail.com">
</div>
<div class="form-row">
<label for="node-input-port"><i class="fa fa-random"></i> Port</label>
<label for="node-input-port"><i class="fa fa-random"></i> <span data-i18n="email.label.port"></span></label>
<input type="text" id="node-input-port" placeholder="465">
</div>
<div class="form-row">
<label for="node-input-userid"><i class="fa fa-user"></i> Userid</label>
<label for="node-input-userid"><i class="fa fa-user"></i> <span data-i18n="email.label.userid"></span></label>
<input type="text" id="node-input-userid">
</div>
<div class="form-row">
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="email.label.password"></span></label>
<input type="password" id="node-input-password">
</div>
<br/>
<div class="form-row">
<label for="node-input-dname"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-dname" placeholder="Name">
<label for="node-input-dname"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-dname" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-tips" id="node-tip"><b>Note:</b> Copied credentials from global emailkeys.js file.</div>
<div class="form-tips" id="node-tip"><span data-i18n="[html]email.tip.cred"></span></div>
</script>
<script type="text/x-red" data-help-name="e-mail">
@@ -119,36 +119,36 @@
<script type="text/x-red" data-template-name="e-mail in">
<div class="form-row node-input-repeat">
<label for="node-input-repeat"><i class="fa fa-repeat"></i> Check Repeat (S)</label>
<input type="text" id="node-input-repeat" placeholder="300">
<label for="node-input-repeat"><i class="fa fa-repeat"></i> <span data-i18n="email.label.repeat"></span></label>
<input type="text" id="node-input-repeat" style="width: 80px"> <span data-i18n="email.label.seconds">seconds</span>
</div>
<div class="form-row">
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
<label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="email.label.server"></span></label>
<input type="text" id="node-input-server" placeholder="imap.gmail.com">
</div>
<div class="form-row">
<label for="node-input-port"><i class="fa fa-random"></i> Port</label>
<label for="node-input-port"><i class="fa fa-random"></i> <span data-i18n="email.label.port"></span></label>
<input type="text" id="node-input-port" placeholder="993">
</div>
<div class="form-row">
<label for="node-input-userid"><i class="fa fa-user"></i> Userid</label>
<label for="node-input-userid"><i class="fa fa-user"></i> <span data-i18n="email.label.userid"></span></label>
<input type="text" id="node-input-userid">
</div>
<div class="form-row">
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="email.label.password"></span></label>
<input type="password" id="node-input-password">
</div>
<div class="form-row">
<label for="node-input-box"><i class="fa fa-inbox"></i> Folder</label>
<label for="node-input-box"><i class="fa fa-inbox"></i> <span data-i18n="email.label.folder"></span></label>
<input type="text" id="node-input-box">
</div>
<br/>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-tips" id="node-tip"><b>Note:</b> Copied credentials from global emailkeys.js file.</div>
<div id="node-input-tip" class="form-tips">Tip: <b>ONLY</b> retrieves the single most recent email.</div>
<div class="form-tips" id="node-tip"><span data-i18n="[html]email.tip.cred"></span></div>
<div id="node-input-tip" class="form-tips"><span data-i18n="[html]email.tip.recent"></span></div>
</script>
<script type="text/x-red" data-help-name="e-mail in">

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013,2014 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ module.exports = function(RED) {
this.userid = globalkeys.user;
flag = true;
} else {
this.error("No e-mail userid set");
this.error(RED._("email.errors.nouserid"));
}
}
if (this.credentials && this.credentials.hasOwnProperty("password")) {
@@ -50,7 +50,7 @@ module.exports = function(RED) {
this.password = globalkeys.pass;
flag = true;
} else {
this.error("No e-mail password set");
this.error(RED._("email.errors.nopassword"));
}
}
if (flag) {
@@ -71,9 +71,9 @@ module.exports = function(RED) {
this.on("input", function(msg) {
if (msg.hasOwnProperty("payload")) {
if (smtpTransport) {
node.status({fill:"blue",shape:"dot",text:"sending"});
node.status({fill:"blue",shape:"dot",text:"email.status.sending"});
if (msg.to && node.name && (msg.to !== node.name)) {
node.warn("Warning: msg properties can no longer override set node properties. See bit.ly/nr-override-msg-props");
node.warn(RED._("node-red:common.errors.nooverride"));
}
var sendopts = { from: node.userid }; // sender address
sendopts.to = node.name || msg.to; // comma separated list of addressees
@@ -92,7 +92,7 @@ module.exports = function(RED) {
sendopts.attachments[0].contentType = msg.headers["content-type"];
}
// Create some body text..
sendopts.text = "Your file from Node-RED is attached : "+(msg.filename.replace(/^.*[\\\/]/, '') || "file.bin")+ (msg.hasOwnProperty("description") ? "\n\n"+msg.description : "");
sendopts.text = RED._("email.default-message",{filename:(msg.filename.replace(/^.*[\\\/]/, '') || "file.bin"),description:(msg.hasOwnProperty("description") ? "\n\n"+msg.description : "")});
}
else {
var payload = RED.util.ensureString(msg.payload);
@@ -103,16 +103,16 @@ module.exports = function(RED) {
smtpTransport.sendMail(sendopts, function(error, info) {
if (error) {
node.error(error,msg);
node.status({fill:"red",shape:"ring",text:"send failed"});
node.status({fill:"red",shape:"ring",text:"email.status.sendfail"});
} else {
node.log("Message sent: " + info.response);
node.log(RED._("email.status.messagesent",{response:info.response}));
node.status({});
}
});
}
else { node.warn("No Email credentials found. See info panel."); }
else { node.warn(RED._("email.errors.nocredentials")); }
}
else { node.warn("No payload to send"); }
else { node.warn(RED._("email.errors.nopayload")); }
});
}
RED.nodes.registerType("e-mail",EmailNode,{
@@ -139,7 +139,7 @@ module.exports = function(RED) {
this.userid = globalkeys.user;
flag = true;
} else {
this.error("No e-mail userid set");
this.error(RED._("email.errors.nouserid"));
}
}
if (this.credentials && this.credentials.hasOwnProperty("password")) {
@@ -149,7 +149,7 @@ module.exports = function(RED) {
this.password = globalkeys.pass;
flag = true;
} else {
this.error("No e-mail password set");
this.error(RED._("email.errors.nopassword"));
}
}
if (flag) {
@@ -172,7 +172,6 @@ module.exports = function(RED) {
});
if (!isNaN(this.repeat) && this.repeat > 0) {
node.log("repeat = "+this.repeat);
this.interval_id = setInterval( function() {
node.emit("input",{});
}, this.repeat );
@@ -180,19 +179,19 @@ module.exports = function(RED) {
this.on("input", function(msg) {
imap.once('ready', function() {
node.status({fill:"blue",shape:"dot",text:"fetching"});
node.status({fill:"blue",shape:"dot",text:"email.status.fetching"});
var pay = {};
imap.openBox(node.box, false, function(err, box) {
if (err) {
node.status({fill:"red",shape:"ring",text:"fetch folder error"});
node.error("Failed to fetch folder "+node.box,err);
node.status({fill:"red",shape:"ring",text:"email.status.foldererror"});
node.error(RED._("email.errors.fetchfail",{folder:node.box}),err);
}
else {
if (box.messages.total > 0) {
//var f = imap.seq.fetch(box.messages.total + ':*', { markSeen:true, bodies: ['HEADER.FIELDS (FROM SUBJECT DATE TO CC BCC)','TEXT'] });
var f = imap.seq.fetch(box.messages.total + ':*', { markSeen:true, bodies: ['HEADER','TEXT'] });
f.on('message', function(msg, seqno) {
node.log('message: #'+ seqno);
node.log(RED._("email.status.message",{number:seqno}));
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info) {
var buffer = '';
@@ -210,62 +209,54 @@ module.exports = function(RED) {
var parts = buffer.split("Content-Type");
for (var p = 0; p < parts.length; p++) {
if (parts[p].indexOf("text/plain") >= 0) {
console.log("TEXT");
pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim();
}
else if (parts[p].indexOf("text/html") >= 0) {
console.log("HTML");
pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim();
} else {
console.log("OTHER");
pay.payload = parts[0];
}
console.log("***",pay.payload,"***");
}
//pay.body = buffer;
}
});
});
msg.on('end', function() {
//node.log('Finished: '+prefix);
//node.log('finished: '+prefix);
});
});
f.on('error', function(err) {
node.warn('fetch message error: ' + err);
node.status({fill:"red",shape:"ring",text:"fetch message error"});
node.warn(RED._("email.errors.messageerror",{error:err}));
node.status({fill:"red",shape:"ring",text:"email.status.messageerror"});
});
f.on('end', function() {
delete(pay._msgid);
if (JSON.stringify(pay) !== oldmail) {
oldmail = JSON.stringify(pay);
node.send(pay);
node.log('received new email: '+pay.topic);
node.log(RED._("email.status.newemail",{topic:pay.topic}));
}
else { node.log('duplicate not sent: '+pay.topic); }
//node.status({fill:"green",shape:"dot",text:"ok"});
else { node.log(RED._("email.status.duplicate",{topic:pay.topic})); }
//node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
node.status({});
});
}
else {
node.log("you have achieved inbox zero");
//node.status({fill:"green",shape:"dot",text:"ok"});
node.log(RED._("email.status.inboxzero"));
//node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
node.status({});
}
}
imap.end();
});
});
node.status({fill:"grey",shape:"dot",text:"connecting"});
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
imap.connect();
});
imap.on('error', function(err) {
node.log(err);
node.status({fill:"red",shape:"ring",text:"connect error"});
});
this.on("error", function(err) {
node.log("error: ",err);
node.status({fill:"red",shape:"ring",text:"email.status.connecterror"});
});
this.on("close", function() {

View File

@@ -0,0 +1,43 @@
{
"email": {
"label": {
"to": "To",
"server": "Server",
"port": "Port",
"userid": "Userid",
"password": "Password",
"repeat": "Refresh",
"seconds": "seconds",
"folder": "Folder"
},
"default-message": "Your file from Node-RED is attached: __filename__ __description__",
"tip": {
"cred": "<b>Note:</b> Copied credentials from global emailkeys.js file.",
"recent": "Tip: Only retrieves the single most recent email."
},
"status": {
"messagesent": "Message sent: __response__",
"fetching": "fetching",
"foldererror": "fetch folder error",
"messageerror": "fetch message error",
"message": "message #__number__",
"newemail": "received new email: __topic__",
"duplicate": "duplicate not sent: __topic__",
"inboxzero": "you have achieved Inbox Zero",
"sending": "sending",
"sendfail": "send failed",
"connecterror": "connect error"
},
"errors": {
"nouserid": "No e-mail userid set",
"nopassword": "No e-mail password set",
"nocredentials": "No Email credentials found. See info panel.",
"nopayload": "No payload to send",
"fetchfail": "Failed to fetch folder: __folder__",
"messageerror": "Fetch message error: __error__"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name" : "node-red-node-email",
"version" : "0.0.5",
"version" : "0.1.0",
"description" : "Node-RED nodes to send and receive simple emails",
"dependencies" : {
"nodemailer" : "1.3.4",

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2013 IBM Corp.
Copyright 2013, 2015 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,18 +16,17 @@
<script type="text/x-red" data-template-name="feedparse">
<div class="form-row">
<label for="node-input-url"><i class="fa fa-globe"></i> Feed url</label>
<label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="feedparse.label.feedurl"></span></label>
<input type="text" id="node-input-url">
</div>
<div class="form-row">
<label for="node-input-interval"><i class="fa fa-repeat"></i> Repeat <span style="font-size: 0.9em;">(M)</span></label>
<input type="text" id="node-input-interval" placeholder="minutes">
<label for="node-input-interval"><i class="fa fa-repeat"></i> <span data-i18n="feedparse.label.refresh"></span></label>
<input type="text" id="node-input-interval" style="width: 50px"> <span data-i18n="feedparse.label.minutes"></span>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<!-- <div class="form-tips"></div> -->
</script>
<script type="text/x-red" data-help-name="feedparse">

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013,2014 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ module.exports = function(RED) {
req.on('error', function(err) { node.error(err); });
req.on('response', function(res) {
if (res.statusCode != 200) { node.warn('error - Bad status code'); }
if (res.statusCode != 200) { node.warn(RED._("feedparse.errors.badstatuscode")); }
else { res.pipe(feedparser); }
});
@@ -65,7 +65,7 @@ module.exports = function(RED) {
this.interval_id = setInterval(function() { getFeed(); }, node.interval);
getFeed();
} else {
this.error("Invalid url");
this.error(RED._("feedparse.errors.invalidurl"));
}
this.on("close", function() {

View File

@@ -0,0 +1,13 @@
{
"feedparse": {
"label": {
"feedurl": "Feed url",
"refresh": "Refresh",
"minutes": "minutes"
},
"errors": {
"badstatuscode": "error - Bad status code",
"invalidurl": "Invalid url"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name" : "node-red-node-feedparser",
"version" : "0.0.4",
"version" : "0.1.0",
"description" : "A Node-RED node to get RSS Atom feeds.",
"dependencies" : {
"feedparser" : "0.19.2",

View File

@@ -16,19 +16,18 @@
<script type="text/x-red" data-template-name="irc in">
<div class="form-row">
<label for="node-input-ircserver"><i class="fa fa-globe"></i> IRC Server</label>
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
<input type="text" id="node-input-ircserver">
</div>
<div class="form-row">
<label for="node-input-channel"><i class="fa fa-random"></i> Channel</label>
<label for="node-input-channel"><i class="fa fa-random"></i> <span data-i18n="irc.label.channel"></span></label>
<input type="text" id="node-input-channel" placeholder="#nodered">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-tips">The channel to join must start with a # (as per normal irc rules...)<br/>
You may join multiple channels by comma separating a list - #chan1,#chan2,etc.</div>
<div class="form-tips"><span data-i18n="[html]irc.tip.in"></span></div>
</script>
<script type="text/x-red" data-help-name="irc in">
@@ -118,27 +117,26 @@
<script type="text/x-red" data-template-name="irc out">
<div class="form-row">
<label for="node-input-ircserver"><i class="fa fa-globe"></i> IRC Server</label>
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
<input type="text" id="node-input-ircserver">
</div>
<div class="form-row">
<label for="node-input-channel"><i class="fa fa-random"></i> Channel</label>
<label for="node-input-channel"><i class="fa fa-random"></i> <span data-i18n="irc.label.channel"></span></label>
<input type="text" id="node-input-channel" placeholder="#nodered">
</div>
<div class="form-row">
<label for="node-input-sendObject"><i class="fa fa-arrows"></i> Action</label>
<label for="node-input-sendObject"><i class="fa fa-arrows"></i> <span data-i18n="irc.label.action"></span></label>
<select type="text" id="node-input-sendObject" style="display: inline-block; vertical-align: middle; width:70%;">
<option value="pay">Send payload to channel(s)</option>
<option value="true">Use msg.topic to set nickname or channel(s)</option>
<option value="false">Send complete msg object to channel(s)</option>
<option value="pay" data-i18n="irc.payload"></option>
<option value="true" data-i18n="irc.topic"></option>
<option value="false" data-i18n="irc.msg"></option>
</select>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-tips">The channel to join must start with a # (as per normal irc rules...)<br/>
Sending the complete object will stringify the whole msg object before sending.</div>
<div class="form-tips"><span data-i18n="[html]irc.tip.out"></span></div>
</script>
<script type="text/x-red" data-help-name="irc out">
@@ -183,24 +181,24 @@
<script type="text/x-red" data-template-name="irc-server">
<div class="form-row">
<label for="node-config-input-server"><i class="fa fa-globe"></i> IRC Server</label>
<label for="node-config-input-server"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
<input type="text" id="node-config-input-server" placeholder="irc.freenode.net" style="width: 45%;" >
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
<input type="text" id="node-config-input-port" placeholder="Port" style="width:45px">
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> <span data-i18n="irc.label.port"></span></label>
<input type="text" id="node-config-input-port" style="width:45px">
</div>
<div class="form-row">
<label>&nbsp;</label>
<input type="checkbox" id="node-config-input-ssl" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-config-input-ssl" style="width: 70%;">Use Secure SSL connection ?</label>
<label for="node-config-input-ssl" style="width: 70%;"><span data-i18n="irc.label.ssl"></span></label>
</div>
<div class="form-row" id="certrow">
<label>&nbsp;</label>
<input type="checkbox" id="node-config-input-cert" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-config-input-cert" style="width: 70%;">Allow self-signed certificates ?</label>
<label for="node-config-input-cert" style="width: 70%;"><span data-i18n="irc.label.self"></span></label>
</div>
<div class="form-row">
<label for="node-config-input-nickname"><i class="fa fa-user"></i> Nickname</label>
<input type="text" id="node-config-input-nickname" placeholder="joe123">
<label for="node-config-input-nickname"><i class="fa fa-user"></i> <span data-i18n="irc.label.nickname"></span></label>
<input type="text" id="node-config-input-nickname">
</div>
</script>

View File

@@ -47,45 +47,45 @@ module.exports = function(RED) {
this.channel = n.channel || this.serverConfig.channel;
var node = this;
if (node.serverConfig.ircclient === null) {
node.log("CONNECT: "+node.serverConfig.server);
node.status({fill:"grey",shape:"dot",text:"connecting"});
node.log(RED._("irc.errors.connect")+": "+node.serverConfig.server);
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
var options = {autoConnect:true,autoRejoin:false,floodProtection:true,secure:node.serverConfig.ssl,selfSigned:node.serverConfig.cert,port:node.serverConfig.port,retryDelay:20000};
node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname, options);
node.serverConfig.ircclient.setMaxListeners(0);
node.serverConfig.ircclient.addListener('error', function(message) {
if (RED.settings.verbose) { node.log("ERR: "+JSON.stringify(message)); }
if (RED.settings.verbose) { node.log(RED._("irc.errors.err")+": "+JSON.stringify(message)); }
});
node.serverConfig.ircclient.addListener('netError', function(message) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("NET: "+JSON.stringify(message)); }
node.status({fill:"red",shape:"ring",text:"net error"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.net")+": "+JSON.stringify(message)); }
node.status({fill:"red",shape:"ring",text:"node-red:common.status.neterror"});
});
node.serverConfig.ircclient.addListener('connect', function() {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("CONNECTED "); }
if (RED.settings.verbose) { node.log(RED._("irc.errors.connected")); }
});
node.serverConfig.ircclient.addListener('registered', function(message) {
node.serverConfig.lastseen = Date.now();
node.log(node.serverConfig.ircclient.nick+" ONLINE: "+message.server);
node.status({fill:"yellow",shape:"dot",text:"connected"});
node.log(node.serverConfig.ircclient.nick+" "+RED._("irc.errors.online")+": "+message.server);
node.status({fill:"yellow",shape:"dot",text:"node-red:common.status.connected"});
node.serverConfig.ircclient.join( node.channel, function(data) {
node.log(data+" JOINED: "+node.channel);
node.status({fill:"green",shape:"dot",text:"joined"});
node.log(data+" "+RED._("irc.errors.joined")+": "+node.channel);
node.status({fill:"green",shape:"dot",text:"node-red:common.status.joined"});
});
});
node.serverConfig.ircclient.addListener('ping', function(server) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("PING from "+JSON.stringify(server)); }
node.status({fill:"green",shape:"dot",text:"ok"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.ping")+" "+JSON.stringify(server)); }
node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
});
node.serverConfig.ircclient.addListener('quit', function(nick, reason, channels, message) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("QUIT: "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
node.status({fill:"grey",shape:"ring",text:"quit"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.quit")+": "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
node.status({fill:"grey",shape:"ring",text:"node-red:common.status.quit"});
//node.serverConfig.ircclient.disconnect( function() {
// node.serverConfig.ircclient.connect();
//});
//if (RED.settings.verbose) { node.log("restart"); } // then retry
//if (RED.settings.verbose) { node.log(RED._("irc.errors.restart")); } // then retry
});
node.serverConfig.ircclient.addListener('raw', function (message) { // any message received means we are alive
//console.log("RAW:"+JSON.stringify(message));
@@ -102,8 +102,8 @@ module.exports = function(RED) {
if ((Date.now()-node.serverConfig.lastseen) > 300000) { // If more than 5 mins
//node.serverConfig.ircclient.disconnect();
//node.serverConfig.ircclient.connect();
node.status({fill:"grey",shape:"ring",text:"no connection"});
if (RED.settings.verbose) { node.log("CONNECTION LOST ?"); }
node.status({fill:"grey",shape:"ring",text:"node-red:common.status.noconnection"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.connectionlost")); }
}
//node.serverConfig.ircclient.send.apply(node.serverConfig.ircclient,["TIME"]); // request time to check link
}, 60000); // check every 1 min
@@ -113,11 +113,11 @@ module.exports = function(RED) {
node.ircclient = node.serverConfig.ircclient;
node.ircclient.addListener('registered', function(message) {
//node.log(node.ircclient.nick+" ONLINE");
node.status({fill:"yellow",shape:"dot",text:"connected"});
//node.log(node.ircclient.nick+" "+RED._("irc.errors.online"));
node.status({fill:"yellow",shape:"dot",text:"node-red:common.status.connected"});
node.ircclient.join( node.channel, function(data) {
// node.log(data+" JOINED "+node.channel);
node.status({fill:"green",shape:"dot",text:"joined"});
// node.log(data+" "+RED._("irc.errors.joined")+" "+node.channel);
node.status({fill:"green",shape:"dot",text:"node-red:common.status.joined"});
});
});
node.ircclient.addListener('message', function (from, to, message) {
@@ -136,27 +136,27 @@ module.exports = function(RED) {
node.ircclient.addListener('join', function(channel, who) {
var msg = { "payload": { "type":"join", "who":who, "channel":channel } };
node.send([null,msg]);
//node.log(who+' has joined '+channel);
//node.log(who+' '+RED._("irc.errors.hasjoined")+' '+channel);
});
node.ircclient.addListener('invite', function(channel, from, message) {
var msg = { "payload": { "type":"invite", "who":from, "channel":channel, "message":message } };
node.send([null,msg]);
//node.log(from+' sent invite to '+channel+': '+message);
//node.log(from+' '+RED._("irc.errors.sentinvite")+' '+channel+': '+message);
});
node.ircclient.addListener('part', function(channel, who, reason) {
var msg = { "payload": { "type":"part", "who":who, "channel":channel, "reason":reason } };
node.send([null,msg]);
//node.log(who+' has left '+channel+': '+reason);
//node.log(who+' '+RED._("irc.errors.hasleft")+' '+channel+': '+reason);
});
node.ircclient.addListener('quit', function(nick, reason, channels, message) {
var msg = { "payload": { "type":"quit", "who":nick, "channel":channels, "reason":reason } };
node.send([null,msg]);
//node.log(nick+' has quit '+channels+': '+reason);
//node.log(nick+' '+RED._("irc.errors.hasquit")+' '+channels+': '+reason);
});
node.ircclient.addListener('kick', function(channel, who, by, reason) {
var msg = { "payload": { "type":"kick", "who":who, "channel":channel, "by":by, "reason":reason } };
node.send([null,msg]);
//node.log(who+' was kicked from '+channel+' by '+by+': '+reason);
//node.log(who+' '+RED._("irc.errors.kickedfrom")+' '+channel+' by '+by+': '+reason);
});
node.ircclient.addListener('names', function (channel, nicks) {
var msg = { "payload": { "type": "names", "channel": channel, "names": nicks} };
@@ -182,45 +182,45 @@ module.exports = function(RED) {
this.channel = n.channel || this.serverConfig.channel;
var node = this;
if (node.serverConfig.ircclient === null) {
node.log("CONNECT: "+node.serverConfig.server);
node.status({fill:"grey",shape:"dot",text:"connecting"});
node.log(RED._("irc.errors.connect")+": "+node.serverConfig.server);
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
var options = {autoConnect:true,autoRejoin:false,floodProtection:true,secure:node.serverConfig.ssl,selfSigned:node.serverConfig.cert,port:node.serverConfig.port,retryDelay:20000};
node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname, options);
node.serverConfig.ircclient.setMaxListeners(0);
node.serverConfig.ircclient.addListener('error', function(message) {
if (RED.settings.verbose) { node.log("ERR: "+JSON.stringify(message)); }
if (RED.settings.verbose) { node.log(RED._("irc.errors.err")+": "+JSON.stringify(message)); }
});
node.serverConfig.ircclient.addListener('netError', function(message) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("NET: "+JSON.stringify(message)); }
node.status({fill:"red",shape:"ring",text:"net error"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.net")+": "+JSON.stringify(message)); }
node.status({fill:"red",shape:"ring",text:"node-red:common.status.neterror"});
});
node.serverConfig.ircclient.addListener('connect', function() {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("CONNECTED "); }
if (RED.settings.verbose) { node.log(RED._("irc.errors.connected")); }
});
node.serverConfig.ircclient.addListener('registered', function(message) {
node.serverConfig.lastseen = Date.now();
node.log(node.serverConfig.ircclient.nick+" ONLINE: "+message.server);
node.status({fill:"yellow",shape:"dot",text:"connected"});
node.log(node.serverConfig.ircclient.nick+" "+RED._("irc.errors.online")+": "+message.server);
node.status({fill:"yellow",shape:"dot",text:"node-red:common.status.connected"});
node.serverConfig.ircclient.join( node.channel, function(data) {
node.log(data+" JOINED: "+node.channel);
node.status({fill:"green",shape:"dot",text:"joined"});
node.log(data+" "+RED._("irc.errors.joined")+": "+node.channel);
node.status({fill:"green",shape:"dot",text:"node-red:common.status.joined"});
});
});
node.serverConfig.ircclient.addListener('ping', function(server) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("PING from "+JSON.stringify(server)); }
node.status({fill:"green",shape:"dot",text:"ok"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.ping")+" "+JSON.stringify(server)); }
node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
});
node.serverConfig.ircclient.addListener('quit', function(nick, reason, channels, message) {
node.serverConfig.lastseen = Date.now();
if (RED.settings.verbose) { node.log("QUIT: "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
node.status({fill:"grey",shape:"ring",text:"quit"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.quit")+": "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
node.status({fill:"grey",shape:"ring",text:"node-red:common.status.quit"});
//node.serverConfig.ircclient.disconnect( function() {
// node.serverConfig.ircclient.connect();
//});
//if (RED.settings.verbose) { node.log("restart"); } // then retry
//if (RED.settings.verbose) { node.log(RED._("irc.errors.restart")); } // then retry
});
node.serverConfig.ircclient.addListener('raw', function (message) { // any message received means we are alive
//console.log("RAW:"+JSON.stringify(message));
@@ -237,8 +237,8 @@ module.exports = function(RED) {
if ((Date.now()-node.serverConfig.lastseen) > 300000) { // If more than 5 mins
//node.serverConfig.ircclient.disconnect();
//node.serverConfig.ircclient.connect();
node.status({fill:"grey",shape:"ring",text:"no connection"});
if (RED.settings.verbose) { node.log("CONNECTION LOST ?"); }
node.status({fill:"grey",shape:"ring",text:"node-red:common.status.noconnection"});
if (RED.settings.verbose) { node.log(RED._("irc.errors.connectionlost")); }
}
//node.serverConfig.ircclient.send.apply(node.serverConfig.ircclient,["TIME"]); // request time to check link
}, 60000); // check every 1 min
@@ -249,7 +249,7 @@ module.exports = function(RED) {
node.on("input", function(msg) {
if (Object.prototype.toString.call( msg.raw ) === '[object Array]') {
if (RED.settings.verbose) { node.log("RAW command:"+msg.raw); }
if (RED.settings.verbose) { node.log(RED._("irc.errors.rawcommand")+":"+msg.raw); }
node.ircclient.send.apply(node.ircclient,msg.raw);
}
else {
@@ -259,7 +259,7 @@ module.exports = function(RED) {
if ((msg.hasOwnProperty('topic'))&&(typeof msg.topic === "string")) {
ch = msg.topic.split(","); // split on , so we can send to multiple
}
else { node.warn("msg.topic not set"); }
else { node.warn(RED._("irc.errors.topicnotset")); }
}
for (var c = 0; c < ch.length; c++) {
if (node.sendFlag == "false") { // send whole message object to each channel

View File

@@ -0,0 +1,39 @@
{
"irc": {
"label": {
"ircserver": "IRC Server",
"channel": "Channel",
"action": "Action",
"port": "Port",
"ssl": "Use Secure SSL connection?",
"self": "Allow self-signed certificates?",
"nickname": "Nickname"
},
"payload": "Send payload to channel(s)",
"topic": "Use msg.topic to set nickname or channel(s)",
"msg": "Send complete msg object to channel(s)",
"tip": {
"in": "The channel to join must start with a #<br/>You may join multiple channels by comma separating a list - #chan1,#chan2,etc.",
"out": "The channel to join must start with a #<br/>Sending the complete object will stringify the whole msg object before sending."
},
"errors": {
"connect": "CONNECT",
"err": "ERR",
"net": "NET",
"connected": "CONNECTED",
"online": "ONLINE",
"joined": "JOINED",
"ping": "PING from",
"quit": "QUIT",
"restart": "restart",
"connectionlost": "CONNECTION LOST?",
"hasjoined": "has joined",
"sentinvite": "sent invite to",
"hasleft": "has left",
"hasquit": "has quit",
"kickedfrom": "was kicked from",
"rawcommand": "RAW command",
"topicnotset": "msg.topic not set"
}
}
}

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2013 IBM Corp.
Copyright 2013, 2015 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,33 +24,6 @@
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-credentials/"+twitterConfigNodeId+"/auth/callback");
$("#node-config-dialog-ok").button("disable");
$("#node-config-twitter-row").html('<div style="text-align: center; margin-top: 20px; "><a class="btn" id="node-config-twitter-start" href="twitter-credentials/'+twitterConfigNodeId+'/auth?callback='+callback+'" target="_blank">Click here to authenticate with Twitter.</a></div>');
$("#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="fa fa-user"></i> Twitter ID</label><span class="input-xlarge uneditable-input">'+sn+'</span>');
}
function pollTwitterCredentials(e) {
$.getJSON('credentials/twitter-credentials/'+twitterConfigNodeId,function(data) {
if (data.screen_name) {
updateTwitterScreenName(data.screen_name);
twitterConfigNodeIntervalId = null;
$("#node-config-dialog-ok").button("enable");
} else {
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
}
})
}
RED.nodes.registerType('twitter-credentials',{
category: 'config',
defaults: {
@@ -66,7 +39,35 @@
},
exportable: false,
oneditprepare: function() {
twitterConfigNodeId = this.id;
var clickhere = this._("twitter.label.clickhere");
var twitterID = this._("twitter.label.twitter-id");
function showTwitterAuthStart() {
var pathname = document.location.pathname;
if (pathname.slice(-1) != "/") {
pathname += "/";
}
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"twitter-credentials/"+twitterConfigNodeId+"/auth/callback");
$("#node-config-dialog-ok").button("disable");
$("#node-config-twitter-row").html('<div style="text-align: center; margin-top: 20px; "><a class="btn" id="node-config-twitter-start" href="twitter-credentials/'+twitterConfigNodeId+'/auth?callback='+callback+'" target="_blank">'+clickhere+'</a></div>');
$("#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="fa fa-user"></i> '+twitterID+'</label><span class="input-xlarge uneditable-input">'+sn+'</span>');
}
function pollTwitterCredentials(e) {
$.getJSON('credentials/twitter-credentials/'+twitterConfigNodeId,function(data) {
if (data.screen_name) {
updateTwitterScreenName(data.screen_name);
twitterConfigNodeIntervalId = null;
$("#node-config-dialog-ok").button("enable");
} else {
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
}
})
}
if (!this.screen_name || this.screen_name === "") {
showTwitterAuthStart();
} else {
@@ -93,29 +94,27 @@
<script type="text/x-red" data-template-name="twitter in">
<div class="form-row">
<label for="node-input-twitter"><i class="fa fa-user"></i> Log in as</label>
<label for="node-input-twitter"><i class="fa fa-user"></i> <span data-i18n="twitter.label.twitter-id"></span></label>
<input type="text" id="node-input-twitter">
</div>
<div class="form-row">
<label for="node-input-user"><i class="fa fa-search"></i> Search</label>
<label for="node-input-user"><i class="fa fa-search"></i> <span data-i18n="twitter.label.search"></span></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>
<option value="user">the tweets of specific users</option>
<option value="dm">your direct messages</option>
<option value="false" data-i18n="twitter.search.public"></option>
<option value="true" data-i18n="twitter.search.follow"></option>
<option value="user" data-i18n="twitter.search.user"></option>
<option value="dm" data-i18n="twitter.search.direct"></option>
</select>
</div>
<div class="form-row" id="node-input-tags-row">
<label for="node-input-tags"><i class="fa fa-tags"></i> <span id="node-input-tags-label">for</span></label>
<input type="text" id="node-input-tags" placeholder="comma-separated words, @ids, #tags">
<label for="node-input-tags"><i class="fa fa-tags"></i> <span id="node-input-tags-label" data-i18n="twitter.label.for"></span></label>
<input type="text" id="node-input-tags" data-i18n="[placeholder]twitter.placeholder.for">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-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>
<div class="form-tips"><span data-i18n="[html]twitter.tip"></span></div>
</script>
<script type="text/x-red" data-help-name="twitter in">
@@ -154,9 +153,9 @@
}
if (this.user == "dm") {
var user = RED.nodes.node(this.twitter);
return (user?user.label()+" ":"")+"DMs";
return (user?user.label()+" ":"")+this._("twitter.label.dmslabel");
} else if (this.user == "user") {
return this.tags+" tweets";
return this.tags+" "+this._("twitter.label.tweetslabel");
}
return this.tags;
},
@@ -164,18 +163,22 @@
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
var userlabel = this._("twitter.label.user");
var userph = this._("twitter.placeholder.user");
var forlabel = this._("twitter.label.for");
var forph = this._("twitter.placeholder.for");
$("#node-input-user").change(function() {
var type = $("#node-input-user option:selected").val();
if (type == "user") {
$("#node-input-tags-row").show();
$("#node-input-tags-label").html("User");
$("#node-input-tags").attr("placeholder","comma-separated @twitter handles");
$("#node-input-tags-label").html(userlabel);
$("#node-input-tags").attr("placeholder",userph);
} else if (type == "dm") {
$("#node-input-tags-row").hide();
} else {
$("#node-input-tags-row").show();
$("#node-input-tags-label").html("for");
$("#node-input-tags").attr("placeholder","comma-separated words, @ids, #hashtags");
$("#node-input-tags-label").html(forlabel);
$("#node-input-tags").attr("placeholder",forph);
}
});
@@ -187,12 +190,12 @@
<script type="text/x-red" data-template-name="twitter out">
<div class="form-row">
<label for="node-input-twitter"><i class="fa fa-user"></i> Twitter</label>
<label for="node-input-twitter"><i class="fa fa-user"></i> <span data-i18n="twitter.label.twitter-id"></span></label>
<input type="text" id="node-input-twitter">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
</script>

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -191,9 +191,7 @@ module.exports = function(RED) {
if (bits.length == 4) {
if ((Number(bits[0]) < Number(bits[2])) && (Number(bits[1]) < Number(bits[3]))) {
st = { locations: node.tags };
}
else {
node.log("possible bad geo area format. Should be lower-left lon, lat, upper-right lon, lat");
node.log(RED._("twitter.status.using-geo",{location:node.tags.toString()}));
}
}
@@ -218,19 +216,19 @@ module.exports = function(RED) {
}
});
stream.on('limit', function(tweet) {
node.warn("tweet rate limit hit");
node.warn(RED._("twitter.errors.ratelimit"));
});
stream.on('error', function(tweet,rc) {
if (rc == 420) {
node.warn("Twitter rate limit hit");
node.warn(RED._("twitter.errors.ratelimit"));
} else {
node.warn("Stream error:"+tweet.toString()+" ("+rc+")");
node.warn(RED._("twitter.errors.streamerror",{error:tweet.toString(),rc:rc}));
}
setTimeout(setupStream,10000);
});
stream.on('destroy', function (response) {
if (this.active) {
node.warn("twitter ended unexpectedly");
node.warn(RED._("twitter.errors.unexpectedend"));
setTimeout(setupStream,10000);
}
});
@@ -243,10 +241,10 @@ module.exports = function(RED) {
node.error(err);
}
} else {
this.error("Invalid tag property");
this.error(RED._("twitter.errors.invalidtag"));
}
} else {
this.error("missing twitter credentials");
this.error(RED._("twitter.errors.missingcredentials"));
}
this.on('close', function() {
@@ -281,11 +279,11 @@ module.exports = function(RED) {
});
node.on("input", function(msg) {
if (msg.hasOwnProperty("payload")) {
node.status({fill:"blue",shape:"dot",text:"tweeting"});
node.status({fill:"blue",shape:"dot",text:"twitter.status.tweeting"});
if (msg.payload.length > 140) {
msg.payload = msg.payload.slice(0,139);
node.warn("Tweet greater than 140 : truncated");
node.warn(RED._("twitter.errors.truncated"));
}
if (msg.media && Buffer.isBuffer(msg.media)) {
@@ -298,13 +296,13 @@ module.exports = function(RED) {
var r = request.post(signedUrl,function(err,httpResponse,body) {
if (err) {
node.error(err,msg);
node.status({fill:"red",shape:"ring",text:"failed"});
node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
} else {
var response = JSON.parse(body);
if (response.errors) {
var errorList = response.errors.map(function(er) { return er.code+": "+er.message }).join(", ");
node.error("Send tweet failed: "+errorList,msg);
node.status({fill:"red",shape:"ring",text:"failed"});
node.error(RED._("twitter.errors.sendfail",{error:errorList}),msg);
node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
} else {
node.status({});
}
@@ -317,14 +315,14 @@ module.exports = function(RED) {
} else {
twit.updateStatus(msg.payload, function (err, data) {
if (err) {
node.status({fill:"red",shape:"ring",text:"failed"});
node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
node.error(err,msg);
}
node.status({});
});
}
}
else { node.warn("No payload to tweet"); }
else { node.warn(RED._("twitter.errors.nopayload")); }
});
}
}
@@ -346,10 +344,8 @@ module.exports = function(RED) {
oauth_callback: req.query.callback
},function(error, oauth_token, oauth_token_secret, results) {
if (error) {
var resp = '<h2>Oh no!</h2>'+
'<p>Something went wrong with the authentication process. The following error was returned:<p>'+
'<p><b>'+error.statusCode+'</b>: '+error.data+'</p>'+
'<p>One known cause of this type of failure is if the clock is wrong on system running Node-RED.';
var err = {statusCode: 401, data: "dummy error"};
var resp = RED._("twitter.errors.oautherror",{statusCode: err.statusCode, errorData: err.data});
res.send(resp)
} else {
credentials.oauth_token = oauth_token;
@@ -371,14 +367,14 @@ module.exports = function(RED) {
function(error, oauth_access_token, oauth_access_token_secret, results) {
if (error) {
RED.log.error(error);
res.send("something in twitter oauth broke.");
res.send(RED._("twitter.errors.oauthbroke"));
} 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>");
res.send(RED._("twitter.errors.authorized"));
}
}
);

View File

@@ -0,0 +1,43 @@
{
"twitter": {
"label": {
"twitter-id":"Twitter ID",
"search": "Search",
"for": "for",
"user": "User",
"dmslabel": "DMs",
"tweetslabel": "tweets",
"clickhere": "Click here to authenticate with Twitter."
},
"placeholder": {
"for": "comma-separated words, @ids, #tags",
"user": "comma-separated @twitter handles"
},
"search": {
"public": "all public tweets",
"follow": "the tweets of who you follow",
"user": "the tweets of specific users",
"direct": "your direct messages"
},
"tip": "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.",
"status": {
"using-geo": "Using geo location: __location__",
"tweeting": "tweeting",
"failed":"failed"
},
"errors": {
"ratelimit":"tweet rate limit hit",
"streamerror":"stream error: __error__ (__rc__)",
"unexpectedend":"stream ended unexpectedly",
"invalidtag":"invalid tag property",
"missingcredentials":"missing twitter credentials",
"truncated":"truncated tweet greater than 140 characters",
"sendfail":"send tweet failed: __error__",
"nopayload":"no payload to tweet",
"oauthbroke":"something in twitter oauth broke.",
"oautherror": "<html><head></head><body><p>Something went wrong with the authentication process. The following error was returned:</p><p><b>__statusCode__</b>: __errorData__</p><p>One known cause of this type of failure is if the clock is wrong on system running Node-RED</p></body></html>",
"authorized": "<html><head></head><body><p>Authorised - you can close this window and return to Node-RED</p></body></html>"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name" : "node-red-node-twitter",
"version" : "0.0.6",
"version" : "0.1.0",
"description" : "A Node-RED node to talk to Twitter",
"dependencies" : {
"twitter-ng": "0.6.2",