-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate from simple-xmpp to xmpp/client
- Loading branch information
Showing
13 changed files
with
586 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,9 +41,9 @@ | |
} | ||
}, | ||
"xmppServer": { | ||
"host": "domain-xmpp.ltd", | ||
"port": 5222, | ||
"jid": "[email protected]", | ||
"service": "xmpps:https://domain-xmpp.ltd:5223", | ||
"domain": "domain-xmpp.ltd", | ||
"username": "[email protected]", | ||
"password": "botPass", | ||
"rooms": [ | ||
{ | ||
|
@@ -62,14 +62,14 @@ | |
"action": "send_xmpp_template", | ||
"args": { | ||
"destination": "[email protected]", | ||
"sendToGroup": true | ||
"type": "groupchat" | ||
}, | ||
"template": "${title}\r\n${message}\r\n${evalMatches[].metric}: ${evalMatches[].value}\r\n${imageUrl}" | ||
} | ||
], | ||
"xmppHooks": [ | ||
{ | ||
"room": "bot", | ||
"room": "bot@domain-xmpp.ltd", | ||
"action": "outgoing_webhook", | ||
"args": ["w1"] | ||
}, | ||
|
@@ -91,4 +91,4 @@ | |
"bearer": null | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,81 +6,140 @@ | |
* @exports xmpp | ||
* @file This files defines the XMPP bot | ||
* @author nioc | ||
* @since 1.0.0 | ||
* @since 2.0.0 | ||
* @license AGPL-3.0+ | ||
*/ | ||
|
||
module.exports = (logger, config) => { | ||
const xmpp = require('simple-xmpp') | ||
const { client, xml, jid } = require('@xmpp/client') | ||
const outgoing = require('../outgoing') | ||
this.jid = null | ||
|
||
// declare send chat/groupchat function | ||
this.send = async (to, message, type) => { | ||
logger.debug(`Send ${type} message to ${to}: '${message}'`) | ||
const stanza = xml( | ||
'message', { | ||
to, | ||
type | ||
}, | ||
xml( | ||
'body', { | ||
}, | ||
message) | ||
) | ||
await xmppClient.send(stanza) | ||
} | ||
|
||
// declare close function | ||
this.close = async () => { | ||
await xmppClient.stop() | ||
} | ||
|
||
// create XMPP client | ||
const xmppClient = client(config.xmpp) | ||
|
||
// handle connection | ||
xmpp.on('online', function (data) { | ||
logger.info(`XMPP connected on ${config.xmpp.host}:${config.xmpp.port} with JID: ${data.jid.user}`) | ||
this.jid = data.jid.user | ||
xmppClient.on('online', (address) => { | ||
logger.info(`XMPP connected on ${config.xmpp.service} with JID: ${address.toString()}`) | ||
this.jid = address | ||
// send presence | ||
xmppClient.send(xml('presence')) | ||
.then(logger.debug('presence sent')) | ||
.catch((error) => { | ||
logger.warn('presence returned following error:', error) | ||
}) | ||
// join rooms | ||
config.xmpp.rooms.forEach(function (room) { | ||
logger.debug(`Join room: ${room.id} ('${room.id}/${data.jid.user}')`) | ||
xmpp.join(room.id + '/' + data.jid.user, room.password) | ||
let occupantJid = room.id + '/' + address.local | ||
logger.debug(`Join room: ${room.id} ('${occupantJid}')`) | ||
const stanza = xml( | ||
'presence', { | ||
to: occupantJid | ||
}, | ||
xml( | ||
'x', { | ||
xmlns: 'https://jabber.org/protocol/muc' | ||
} | ||
) | ||
) | ||
xmppClient.send(stanza) | ||
logger.info(`Joined room: ${room.id}`) | ||
}) | ||
}) | ||
|
||
// handle direct message | ||
xmpp.on('chat', function (from, message) { | ||
logger.info(`Incoming chat message from ${from}`) | ||
logger.debug(`Message: "${message}"`) | ||
let xmppHook = config.getXmppHookAction(this.jid) | ||
if (!xmppHook) { | ||
logger.error(`There is no action for incoming chat message to ${this.jid}`) | ||
// handle stanzas | ||
xmppClient.on('stanza', stanza => { | ||
if (!stanza.is('message')) { | ||
// not a message, do nothing | ||
return | ||
} | ||
switch (xmppHook.action) { | ||
case 'outgoing_webhook': | ||
logger.debug(`Call outgoing webhook: ${xmppHook.args[0]}`) | ||
outgoing(logger, config, xmpp, from, from, message, false, xmppHook.args[0]) | ||
break | ||
default: | ||
let type = stanza.attrs.type | ||
switch (type) { | ||
case 'chat': | ||
case 'groupchat': | ||
let body = stanza.getChild('body') | ||
if (!body) { | ||
// empty body, do nothing | ||
return | ||
} | ||
let fromJid = jid(stanza.attrs.from) | ||
// for chat, "to" and "replyTo" must be something like "[email protected]", "from" is local part "user" | ||
let to = this.jid.bare() | ||
let from = fromJid.local | ||
let replyTo = fromJid.bare() | ||
if (type === 'groupchat') { | ||
// for groupchat, "to" and "replyTo" is conference name, "from" is nickname | ||
to = fromJid.bare() | ||
from = fromJid.getResource() | ||
replyTo = to | ||
if (from === this.jid.local || stanza.getChild('delay')) { | ||
// message from bot or old message, do nothing | ||
return | ||
} | ||
} | ||
let message = body.text() | ||
logger.info(`Incoming ${type} message from ${from} (${fromJid.toString()}) to ${to}`) | ||
logger.debug(`Message: "${message}"`) | ||
let xmppHook = config.getXmppHookAction(to.toString()) | ||
if (!xmppHook) { | ||
logger.error(`There is no action for incoming ${type} message to: "${to}"`) | ||
return | ||
} | ||
switch (xmppHook.action) { | ||
case 'outgoing_webhook': | ||
logger.debug(`Call outgoing webhook: ${xmppHook.args[0]}`) | ||
outgoing(logger, config, this, from.toString(), replyTo.toString(), message, type, xmppHook.args[0]) | ||
break | ||
default: | ||
break | ||
} | ||
break | ||
} | ||
}) | ||
|
||
// handle group message | ||
xmpp.on('groupchat', function (conference, from, message, stamp, delay) { | ||
// logger.trace(`Get following group message: "${message}" in ${conference} from ${from}. stamp = ${stamp} - delay = `, delay) | ||
if (from === this.jid || stamp !== null) { | ||
// message from bot, do nothing | ||
return | ||
} | ||
logger.info(`Incoming groupchat message from ${from} in ${conference}`) | ||
logger.debug(`Message: "${message}"`) | ||
let xmppHook = config.getXmppHookAction(conference) | ||
if (!xmppHook) { | ||
logger.error(`There is no action for incoming groupchat message from conference: "${conference}"`) | ||
return | ||
} | ||
switch (xmppHook.action) { | ||
case 'outgoing_webhook': | ||
logger.debug(`Call outgoing webhook: ${xmppHook.args[0]}`) | ||
outgoing(logger, config, xmpp, from, conference, message, true, xmppHook.args[0]) | ||
break | ||
default: | ||
break | ||
} | ||
// handle status | ||
xmppClient.on('status', (status) => { | ||
logger.trace(`Status changed to ${status}`) | ||
}) | ||
|
||
// trace input/output | ||
// xmppClient.on('input', (input) => { | ||
// logger.trace('<<<<', input) | ||
// }) | ||
// xmppClient.on('output', (output) => { | ||
// logger.trace('>>>', output) | ||
// }) | ||
|
||
// handle error | ||
xmpp.on('error', function (err) { | ||
logger.error(err) | ||
xmppClient.on('error', (err) => { | ||
logger.error('XMPP client encountered following error:', err.message) | ||
process.exit(99) | ||
}) | ||
|
||
// connect | ||
xmpp.connect(config.xmpp) | ||
|
||
// get roster | ||
xmpp.getRoster() | ||
xmppClient.start() | ||
.catch(logger.error) | ||
|
||
return xmpp | ||
return this | ||
} |
Oops, something went wrong.