mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
join a MUC if we're already connected to server and refactor error handling (#749)
This commit is contained in:
parent
0d0c88d19e
commit
fc2f6ed3c7
@ -57,7 +57,7 @@ module.exports = function(RED) {
|
|||||||
this.register = function(xmppThat) {
|
this.register = function(xmppThat) {
|
||||||
if (RED.settings.verbose || LOGITALL) {that.log("registering "+xmppThat.id); }
|
if (RED.settings.verbose || LOGITALL) {that.log("registering "+xmppThat.id); }
|
||||||
that.users[xmppThat.id] = xmppThat;
|
that.users[xmppThat.id] = xmppThat;
|
||||||
// So we could start the connection here, but we already have the logic in the thats.
|
// So we could start the connection here, but we already have the logic in the nodes that takes care of that.
|
||||||
// if (Object.keys(that.users).length === 1) {
|
// if (Object.keys(that.users).length === 1) {
|
||||||
// this.client.start();
|
// this.client.start();
|
||||||
// }
|
// }
|
||||||
@ -211,6 +211,66 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function joinMUC(node, xmpp, name) {
|
||||||
|
// the presence with the muc x element signifies we want to join the muc
|
||||||
|
// if we want to support passwords, we need to add that as a child of the x element
|
||||||
|
// (third argument to the x/muc/children )
|
||||||
|
// We also turn off chat history (maxstanzas 0) because that's not what this node is about.
|
||||||
|
var stanza = xml('presence',
|
||||||
|
{"to": name},
|
||||||
|
xml("x",'http://jabber.org/protocol/muc'),
|
||||||
|
{ maxstanzas:0, seconds:1 }
|
||||||
|
);
|
||||||
|
node.serverConfig.used(node);
|
||||||
|
xmpp.send(stanza);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// separated out since we want the same functionality from both in and out nodes
|
||||||
|
function errorHandler(node, err){
|
||||||
|
if (!node.quiet) {
|
||||||
|
node.quiet = true;
|
||||||
|
// if the error has a "stanza" then we've probably done something wrong and the
|
||||||
|
// server is unhappy with us
|
||||||
|
if (err.hasOwnProperty("stanza")) {
|
||||||
|
if (err.stanza.name === 'stream:error') { node.error("stream:error - bad login id/pwd ?",err); }
|
||||||
|
else { node.error(err.stanza.name,err); }
|
||||||
|
node.status({fill:"red",shape:"ring",text:"bad login"});
|
||||||
|
}
|
||||||
|
// The error might be a string
|
||||||
|
else if (err == "TimeoutError") {
|
||||||
|
// OK, this happens with OpenFire, suppress it.
|
||||||
|
node.status({fill:"grey",shape:"dot",text:"opening"});
|
||||||
|
node.log("Timed out! ",err);
|
||||||
|
// node.status({fill:"red",shape:"ring",text:"XMPP timeout"});
|
||||||
|
}
|
||||||
|
else if (err === "XMPP authentication failure") {
|
||||||
|
node.error(err,err);
|
||||||
|
node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
|
||||||
|
}
|
||||||
|
// or it might have a name that tells us what's wrong
|
||||||
|
else if (err.name === "SASLError") {
|
||||||
|
node.error("Authorization error! "+err.condition,err);
|
||||||
|
node.status({fill:"red",shape:"ring",text:"XMPP authorization failure"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// or it might have the errno set.
|
||||||
|
else if (err.errno === "ETIMEDOUT") {
|
||||||
|
node.error("Timeout connecting to server",err);
|
||||||
|
node.status({fill:"red",shape:"ring",text:"timeout"});
|
||||||
|
}
|
||||||
|
else if (err.errno === "ENOTFOUND") {
|
||||||
|
node.error("Server doesn't exist "+xmpp.options.service,err);
|
||||||
|
node.status({fill:"red",shape:"ring",text:"bad address"});
|
||||||
|
}
|
||||||
|
// nothing we've seen before!
|
||||||
|
else {
|
||||||
|
node.error("Unknown error: "+err,err);
|
||||||
|
node.status({fill:"red",shape:"ring",text:"node-red:common.status.error"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function XmppInNode(n) {
|
function XmppInNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.server = n.server;
|
this.server = n.server;
|
||||||
@ -220,6 +280,9 @@ module.exports = function(RED) {
|
|||||||
this.sendAll = n.sendObject;
|
this.sendAll = n.sendObject;
|
||||||
// Yes, it's called "from", don't ask me why; I don't know why
|
// Yes, it's called "from", don't ask me why; I don't know why
|
||||||
this.from = n.to || "";
|
this.from = n.to || "";
|
||||||
|
this.quiet = false;
|
||||||
|
// MUC == Multi-User-Chat == chatroom
|
||||||
|
this.muc = this.join && (this.from !== "")
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
var xmpp = this.serverConfig.client;
|
var xmpp = this.serverConfig.client;
|
||||||
@ -237,26 +300,27 @@ module.exports = function(RED) {
|
|||||||
disconnect: Socket is disconnected
|
disconnect: Socket is disconnected
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xmpp.on('online', async address => {
|
// if we're already connected, then do the actions now, otherwise register a callback
|
||||||
|
if(xmpp.status === "online") {
|
||||||
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
if ((node.join) && (node.from !== "")) {
|
if(node.muc) {
|
||||||
var to = node.from+'/'+node.nick;
|
joinMUC(node, xmpp, node.from+'/'+node.nick);
|
||||||
// the presence with the muc x element signifies we want to join the muc
|
}
|
||||||
// if we want to support passwords, we need to add that as a child of the x element
|
}
|
||||||
// (third argument to the x/muc/children )
|
// sod it, register it anyway, that way things will work better on a reconnect:
|
||||||
// We also turn off chat history (maxstanzas 0) because that's not what this node is about.
|
xmpp.on('online', async address => {
|
||||||
var stanza = xml('presence',
|
node.quiet = false;
|
||||||
{"to": to},
|
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
xml("x",'http://jabber.org/protocol/muc'),
|
if (node.muc) {
|
||||||
{ maxstanzas:0, seconds:1 }
|
// if we want to use a chatroom, we need to tell the server we want to join it
|
||||||
);
|
joinMUC(node, xmpp, node.from+'/'+node.nick);
|
||||||
node.serverConfig.used(node);
|
|
||||||
xmpp.send(stanza).catch(error => {node.warn("Got error when sending presence: "+error)});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
xmpp.on('connecting', async address => {
|
xmpp.on('connecting', async address => {
|
||||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
if(!node.quiet) {
|
||||||
|
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
xmpp.on('connect', async address => {
|
xmpp.on('connect', async address => {
|
||||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connected"});
|
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
@ -281,39 +345,7 @@ module.exports = function(RED) {
|
|||||||
// Should we listen on other's status (chatstate) or a chatroom state (groupbuddy)?
|
// Should we listen on other's status (chatstate) or a chatroom state (groupbuddy)?
|
||||||
xmpp.on('error', err => {
|
xmpp.on('error', err => {
|
||||||
if (RED.settings.verbose || LOGITALL) { node.log("XMPP Error: "+err); }
|
if (RED.settings.verbose || LOGITALL) { node.log("XMPP Error: "+err); }
|
||||||
if (err.hasOwnProperty("stanza")) {
|
errorHandler(node, err);
|
||||||
if (err.stanza.name === 'stream:error') { node.error("stream:error - bad login id/pwd ?",err); }
|
|
||||||
else { node.error(err.stanza.name,err); }
|
|
||||||
node.status({fill:"red",shape:"ring",text:"bad login"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (err.errno === "ETIMEDOUT") {
|
|
||||||
node.error("Timeout connecting to server",err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"timeout"});
|
|
||||||
}
|
|
||||||
if (err.errno === "ENOTFOUND") {
|
|
||||||
node.error("Server doesn't exist "+xmpp.options.service,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"bad address"});
|
|
||||||
}
|
|
||||||
else if (err === "XMPP authentication failure") {
|
|
||||||
node.error("Authentication failure! "+err,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
|
|
||||||
}
|
|
||||||
else if (err.name === "SASLError") {
|
|
||||||
node.error("Authorization error! "+err.condition,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"XMPP authorization failure"});
|
|
||||||
}
|
|
||||||
else if (err == "TimeoutError") {
|
|
||||||
// Suppress it!
|
|
||||||
node.warn("Timed out! ");
|
|
||||||
node.status({fill:"grey",shape:"dot",text:"opening"});
|
|
||||||
//node.status({fill:"red",shape:"ring",text:"XMPP timeout"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.error(err,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.error"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Meat of it, a stanza object contains chat messages (and other things)
|
// Meat of it, a stanza object contains chat messages (and other things)
|
||||||
@ -408,7 +440,6 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
node.error("Bad xmpp configuration; service: "+xmpp.options.service+" jid: "+node.serverConfig.jid);
|
node.error("Bad xmpp configuration; service: "+xmpp.options.service+" jid: "+node.serverConfig.jid);
|
||||||
node.warn(e);
|
|
||||||
node.warn(e.stack);
|
node.warn(e.stack);
|
||||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"});
|
node.status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"});
|
||||||
}
|
}
|
||||||
@ -429,6 +460,9 @@ module.exports = function(RED) {
|
|||||||
this.join = n.join || false;
|
this.join = n.join || false;
|
||||||
this.sendAll = n.sendObject;
|
this.sendAll = n.sendObject;
|
||||||
this.to = n.to || "";
|
this.to = n.to || "";
|
||||||
|
this.quiet = false;
|
||||||
|
// MUC == Multi-User-Chat == chatroom
|
||||||
|
this.muc = this.join && (this.to !== "")
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
var xmpp = this.serverConfig.client;
|
var xmpp = this.serverConfig.client;
|
||||||
@ -446,27 +480,26 @@ module.exports = function(RED) {
|
|||||||
disconnect: Socket is disconnected
|
disconnect: Socket is disconnected
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xmpp.on('online', function(data) {
|
// if we're already connected, then do the actions now, otherwise register a callback
|
||||||
|
if(xmpp.status === "online") {
|
||||||
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
if ((node.join) && (node.to !== "")) {
|
if(node.muc){
|
||||||
// disable chat history
|
joinMUC(node, xmpp, node.to+'/'+node.nick);
|
||||||
var to = node.to+'/'+node.nick;
|
}
|
||||||
// the presence with the muc x element signifies we want to join the muc
|
}
|
||||||
// if we want to support passwords, we need to add that as a child of the x element
|
// sod it, register it anyway, that way things will work better on a reconnect:
|
||||||
// (third argument to the x/muc/children )
|
xmpp.on('online', function(data) {
|
||||||
// We also turn off chat history (maxstanzas 0) because that's not what this node is about.
|
node.quiet = false;
|
||||||
var stanza = xml('presence',
|
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
{"to": to},
|
if (node.muc) {
|
||||||
xml("x",'http://jabber.org/protocol/muc'),
|
joinMUC(node, xmpp,node.to+"/"+node.nick);
|
||||||
{ maxstanzas:0, seconds:1 }
|
|
||||||
);
|
|
||||||
node.serverConfig.used(node);
|
|
||||||
xmpp.send(stanza);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
xmpp.on('connecting', async address => {
|
xmpp.on('connecting', async address => {
|
||||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
if(!node.quiet) {
|
||||||
|
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
xmpp.on('connect', async address => {
|
xmpp.on('connect', async address => {
|
||||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connected"});
|
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connected"});
|
||||||
@ -490,35 +523,7 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
xmpp.on('error', function(err) {
|
xmpp.on('error', function(err) {
|
||||||
if (RED.settings.verbose || LOGITALL) { node.log(err); }
|
if (RED.settings.verbose || LOGITALL) { node.log(err); }
|
||||||
if (err.hasOwnProperty("stanza")) {
|
errorHandler(node, err)
|
||||||
if (err.stanza.name === 'stream:error') { node.error("stream:error - bad login id/pwd ?",err); }
|
|
||||||
else { node.error(err.stanza.name,err); }
|
|
||||||
node.status({fill:"red",shape:"ring",text:"bad login"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (err.errno === "ETIMEDOUT") {
|
|
||||||
node.error("Timeout connecting to server",err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"timeout"});
|
|
||||||
}
|
|
||||||
else if (err.errno === "ENOTFOUND") {
|
|
||||||
node.error("Server doesn't exist "+xmpp.options.service,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"bad address"});
|
|
||||||
}
|
|
||||||
else if (err === "XMPP authentication failure") {
|
|
||||||
node.error(err,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
|
|
||||||
}
|
|
||||||
else if (err == "TimeoutError") {
|
|
||||||
// OK, this happens with OpenFire, suppress it.
|
|
||||||
node.status({fill:"grey",shape:"dot",text:"opening"});
|
|
||||||
node.log("Timed out! ",err);
|
|
||||||
// node.status({fill:"red",shape:"ring",text:"XMPP timeout"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.error("Unknown error: "+err,err);
|
|
||||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.error"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//register with config
|
//register with config
|
||||||
|
Loading…
x
Reference in New Issue
Block a user