This repository was archived by the owner on Jun 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathXmppClient.js
More file actions
executable file
·180 lines (152 loc) · 4.52 KB
/
XmppClient.js
File metadata and controls
executable file
·180 lines (152 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
* The logic for the jabber client connection
*/
"use strict";
var xmpp = require('node-xmpp');
var util = require('util');
var events = require('events');
var crypto = require('crypto');
var StringUtils = require('./StringUtils.js');
function XmppClient(params) {
events.EventEmitter.call(this);
this._config = params.config;
this._debug = params.debug;
// all recieved messages
// { time, sender, msg }
this._messages = [];
this._hasRoomEntered = false;
this._sendOnRoomEntered = [];
};
// inherit events.EventEmitter
XmppClient.super_ = events.EventEmitter;
XmppClient.prototype = Object.create(events.EventEmitter.prototype, {
constructor : {
value : XmppClient,
enumerable : false
}
});
module.exports = XmppClient;
XmppClient.prototype.getMessages = function() {
var self = this;
return self._messages;
};
/**
* Connects to the jabber server AND enters the configured room. Sends also any queued messages.
*/
XmppClient.prototype.connect = function() {
var self = this;
this.cl = new xmpp.Client({
jid : this._config.xmpp.jid,
password : this._config.xmpp.password,
reconnect : true
});
this.cl.on('error', function(data) {
util.log('XmppClient Error: ' + JSON.stringify(data));
});
if (this._debug) {
// Log all data received
this.cl.on('data', function(d) {
util.log("[data in] " + d);
});
}
// Once connected, set available presence and join room
self.cl.on('online', function() {
util.log("We're online!");
// set ourselves as online
self.cl.send(new xmpp.Element('presence', {
type : 'available'
}).c('show').t('chat'));
// join room (and request no chat history)
self.cl.send(new xmpp.Element('presence', {
to : self._config.xmpp.roomJid + '/' + self._config.xmpp.roomNick
}).c('x', {
xmlns : 'http://jabber.org/protocol/muc'
}));
// send queued events
self._hasRoomEntered = true;
self._sendOnRoomEntered.forEach(function sendQueued(item) {
self.send(item.nick, item.msg);
});
self._sendOnRoomEntered = [];
// send keepalive data or server will disconnect us after 150s of
// inactivity
setInterval(function() {
self.cl.send(' ');
}, 30000);
});
self.cl.on('stanza', onMessageRecieved);
function onMessageRecieved(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}
// ignore everything that isn't a room message
if (!stanza.is('message') || !stanza.attrs.type == 'groupchat') {
return;
}
// ignore messages we sent
// if (stanza.attrs.from == self.config.roomJid + '/' +
// self.config.roomNick) {
// return;
// }
var body = stanza.getChild('body');
// message without body is probably a topic change
if (!body) {
return;
}
var message = body.getText();
var sender = StringUtils.substringAfterLast(stanza.from, '/');
// no message if we don't have a sender's name
// most likely this is a channel topic
if (StringUtils.isEmpty(sender)) {
return;
}
if (sender === self._config.xmpp.roomNick) {
// a message by this bot, replace the sender with client sender (encoded in the message)
var index = message.indexOf(':');
if (index !== -1) {
sender = message.substring(0, index);
message = message.substring(index + 2);
}
}
var delay = stanza.getChild('delay');
var date;
if (delay) {
// history group chat message
date = new Date(Date.parse(delay.attrs.stamp) - self._config.timezoneOffset);
} else {
// normal group chat message
date = new Date();
}
// create an id by hashing the message text
var shasum = crypto.createHash('sha1');
var id = shasum.update(message, 'utf8').digest('hex');
var newMsg = {
id : id,
date : date,
sender : sender,
msg : message
};
self._messages.push(newMsg);
self.emit('message', newMsg, self._messages.length - 1);
}
;
};
// send the message to the groupchat
XmppClient.prototype.send = function(nick, message) {
var self = this;
if (!self._hasRoomEntered) {
util.log("Currently not in room, queuing this message");
self._sendOnRoomEntered.push({
nick : nick,
msg : message
});
return;
}
// util.log(util.format("Sending for '%s': %s", nick, message));
self.cl.send(new xmpp.Element('message', {
to : self._config.xmpp.roomJid,
type : 'groupchat'
}).c('body').t(nick + ': ' + message));
};