Commit dcbdd261df3fddc30515a19c7c17be5489215791
1 parent
f0b4793fef
Exists in
master
Create sender module
Showing 3 changed files with 55 additions and 11 deletions Inline Diff
lib/custom-ping.js
1 | const MODULE_NAME = 'CUSTOM-PING'; | 1 | const MODULE_NAME = 'CUSTOM-PING'; |
2 | 2 | ||
3 | const uniqid = require('uniqid'); | 3 | const uniqid = require('uniqid'); |
4 | const config = require('komodo-sdk/config'); | 4 | const config = require('komodo-sdk/config'); |
5 | const logger = require('tektrans-logger'); | 5 | const logger = require('tektrans-logger'); |
6 | 6 | ||
7 | const sender = require('./sender'); | ||
8 | |||
7 | let bot; | 9 | let bot; |
8 | 10 | ||
9 | const allowedFromPartnerList = ( | 11 | const allowedFromPartnerList = ( |
10 | (config.custom_ping && config.custom_ping.allowed_from_partners) || [] | 12 | (config.custom_ping && config.custom_ping.allowed_from_partners) || [] |
11 | ) | 13 | ) |
12 | .filter((item) => typeof item === 'string') | 14 | .filter((item) => typeof item === 'string') |
13 | .map((item) => (item || '').trim().toUpperCase()) | 15 | .map((item) => (item || '').trim().toUpperCase()) |
14 | .filter((item) => item); | 16 | .filter((item) => item); |
15 | 17 | ||
16 | const isPingMessage = (msg) => { | 18 | const isPingMessage = (msg) => { |
17 | if (!msg) return false; | 19 | if (!msg) return false; |
18 | if (typeof msg !== 'string') return false; | 20 | if (typeof msg !== 'string') return false; |
19 | 21 | ||
20 | return ((msg || '').trim().toUpperCase().search(/^PING($| )/) === 0); | 22 | return ((msg || '').trim().toUpperCase().search(/^PING($| )/) === 0); |
21 | }; | 23 | }; |
22 | exports.isPingMessage = isPingMessage; | 24 | exports.isPingMessage = isPingMessage; |
23 | 25 | ||
24 | const isPongMessage = (msg) => { | 26 | const isPongMessage = (msg) => { |
25 | if (!msg) return false; | 27 | if (!msg) return false; |
26 | if (typeof msg !== 'string') return false; | 28 | if (typeof msg !== 'string') return false; |
27 | 29 | ||
28 | return ((msg || '').trim().toUpperCase().search(/^PONG($| )/) === 0); | 30 | return ((msg || '').trim().toUpperCase().search(/^PONG($| )/) === 0); |
29 | }; | 31 | }; |
30 | exports.isPongMessage = isPongMessage; | 32 | exports.isPongMessage = isPongMessage; |
31 | 33 | ||
32 | const isAllowedPartner = (partner) => { | 34 | const isAllowedPartner = (partner) => { |
33 | if (!config.custom_ping) return false; | 35 | if (!config.custom_ping) return false; |
34 | if (config.custom_ping.disable_pong) return false; | 36 | if (config.custom_ping.disable_pong) return false; |
35 | 37 | ||
36 | if (config.custom_ping.allowed_from_all) return true; | 38 | if (config.custom_ping.allowed_from_all) return true; |
37 | return allowedFromPartnerList.indexOf((partner || '').trim().toUpperCase()) >= 0; | 39 | return allowedFromPartnerList.indexOf((partner || '').trim().toUpperCase()) >= 0; |
38 | }; | 40 | }; |
39 | exports.isAllowedPartner = isAllowedPartner; | 41 | exports.isAllowedPartner = isAllowedPartner; |
40 | 42 | ||
41 | const sendPong = (xid, partner, pingMessage) => { | 43 | const sendPong = (xid, partner, pingMessage) => { |
42 | if (!bot) return; | 44 | if (!bot) return; |
43 | if (!partner || typeof partner !== 'string' || !partner.trim()) return; | 45 | if (!partner || typeof partner !== 'string' || !partner.trim()) return; |
44 | 46 | ||
45 | const tokens = pingMessage.trim().split(/ +/); | 47 | const tokens = pingMessage.trim().split(/ +/); |
46 | 48 | ||
47 | const pongMessage = [ | 49 | const pongMessage = [ |
48 | 'PONG', | 50 | 'PONG', |
49 | (tokens && tokens[1]) || null, | 51 | (tokens && tokens[1]) || null, |
50 | ].filter((item) => item) | 52 | ].filter((item) => item) |
51 | .join(' '); | 53 | .join(' '); |
52 | 54 | ||
53 | if (config.custom_ping && config.custom_ping.verbose) { | 55 | if (config.custom_ping && config.custom_ping.verbose) { |
54 | logger.verbose(`${MODULE_NAME} F0D18EF4: Responding PING message`, { | 56 | logger.verbose(`${MODULE_NAME} F0D18EF4: Responding PING message`, { |
55 | xid, partner, pongMessage, | 57 | xid, partner, pongMessage, |
56 | }); | 58 | }); |
57 | } | 59 | } |
58 | 60 | ||
59 | bot.send(partner.trim(), pongMessage); | 61 | sender.send(partner.trim(), pongMessage); |
60 | }; | 62 | }; |
61 | exports.sendPong = sendPong; | 63 | exports.sendPong = sendPong; |
62 | 64 | ||
63 | const sleepMs = (ms) => new Promise((resolve) => { | 65 | const sleepMs = (ms) => new Promise((resolve) => { |
64 | setTimeout(() => { | 66 | setTimeout(() => { |
65 | resolve(true); | 67 | resolve(true); |
66 | }, ms); | 68 | }, ms); |
67 | }); | 69 | }); |
68 | 70 | ||
69 | const pingSender = async () => { | 71 | const pingSender = async () => { |
70 | const xid = uniqid(); | 72 | const xid = uniqid(); |
71 | 73 | ||
72 | if (bot) { | 74 | if (bot) { |
73 | const msg = `PING ${xid}`; | 75 | const msg = `PING ${xid}`; |
74 | 76 | ||
75 | bot.send(config.username, msg); | 77 | sender.send(config.username, msg); |
76 | 78 | ||
77 | if ( | 79 | if ( |
78 | config.custom_ping | 80 | config.custom_ping |
79 | && config.custom_ping.send_to | 81 | && config.custom_ping.send_to |
80 | && Array.isArray(config.custom_ping.send_to) | 82 | && Array.isArray(config.custom_ping.send_to) |
81 | ) { | 83 | ) { |
82 | const partnerCount = config.custom_ping.send_to.length; | 84 | const partnerCount = config.custom_ping.send_to.length; |
83 | for (let i = 0; i < partnerCount; i += 1) { | 85 | for (let i = 0; i < partnerCount; i += 1) { |
86 | const additionalDelay = Math.random() * 1000; | ||
87 | |||
84 | // eslint-disable-next-line no-await-in-loop | 88 | // eslint-disable-next-line no-await-in-loop |
85 | await sleepMs(1000); | 89 | await sleepMs(1000 + additionalDelay); |
86 | 90 | ||
87 | const partner = config.custom_ping.send_to[i]; | 91 | const partner = config.custom_ping.send_to[i]; |
88 | 92 | ||
89 | if (config.custom_ping.verbose) { | 93 | if (config.custom_ping.verbose) { |
90 | logger.verbose(`${MODULE_NAME} 21358F45: Sending custom ping`, { | 94 | logger.verbose(`${MODULE_NAME} 21358F45: Sending custom ping`, { |
91 | xid, | 95 | xid, |
92 | partner, | 96 | partner, |
93 | msg, | 97 | msg, |
94 | }); | 98 | }); |
95 | } | 99 | } |
96 | 100 | ||
97 | bot.send(partner, msg); | 101 | sender.send(partner, msg, xid); |
98 | } | 102 | } |
99 | } | 103 | } |
100 | } | 104 | } |
101 | 105 | ||
102 | await sleepMs(3 * 1000); | 106 | await sleepMs(3 * 1000); |
103 | pingSender(); | 107 | pingSender(); |
104 | }; | 108 | }; |
105 | 109 | ||
106 | const setBot = (botFromCaller) => { | 110 | const setBot = (botFromCaller) => { |
107 | logger.verbose(`${MODULE_NAME} A063F39F: Bot registered for custom ping`); | 111 | logger.verbose(`${MODULE_NAME} A063F39F: Bot registered for custom ping`); |
108 | bot = botFromCaller; | 112 | bot = botFromCaller; |
109 | pingSender(); | 113 | pingSender(); |
110 | }; | 114 | }; |
111 | exports.setBot = setBot; | 115 | exports.setBot = setBot; |
112 | 116 |
lib/sender.js
File was created | 1 | const MODULE_NAME = 'SENDER'; | |
2 | |||
3 | const logger = require('tektrans-logger'); | ||
4 | |||
5 | let bot; | ||
6 | |||
7 | const init = (botFromCaller) => { | ||
8 | logger.verbose(`${MODULE_NAME} D74B30FF: Sender initialized`); | ||
9 | bot = botFromCaller; | ||
10 | }; | ||
11 | exports.init = init; | ||
12 | |||
13 | const send = (partner, msg, xid) => { | ||
14 | if (!bot) { | ||
15 | logger.verbose(`${MODULE_NAME} 78B04B3B: Not sending message because bot has not been initialized`, { | ||
16 | xid, | ||
17 | partner, | ||
18 | msg, | ||
19 | }); | ||
20 | |||
21 | return; | ||
22 | } | ||
23 | |||
24 | logger.verbose(`${MODULE_NAME} 648A5F17: Sending message`, { | ||
25 | xid, | ||
26 | partner, | ||
27 | msg, | ||
28 | }); | ||
29 | |||
30 | try { | ||
31 | bot.send(partner, msg); | ||
32 | } catch (e) { | ||
33 | logger.warn(`${MODULE_NAME} C50237D8: Exception on sending message`, { | ||
34 | xid, | ||
35 | eCode: e.code, | ||
36 | eMessage: e.message || e, | ||
37 | }); | ||
38 | } | ||
39 | }; | ||
40 | exports.send = send; | ||
41 |
lib/transport.js
1 | const MODULE_NAME = 'TRANSPORT'; | 1 | const MODULE_NAME = 'TRANSPORT'; |
2 | const SLEEP_BEFORE_TERMINATE_ON_ERROR_MS = 5 * 1000; | 2 | const SLEEP_BEFORE_TERMINATE_ON_ERROR_MS = 5 * 1000; |
3 | 3 | ||
4 | const bot = require('simple-xmpp'); | 4 | const bot = require('simple-xmpp'); |
5 | const config = require('komodo-sdk/config'); | 5 | const config = require('komodo-sdk/config'); |
6 | const logger = require('tektrans-logger'); | 6 | const logger = require('tektrans-logger'); |
7 | const messagingService = require('komodo-center-messaging-client-lib'); | 7 | const messagingService = require('komodo-center-messaging-client-lib'); |
8 | const uniqid = require('uniqid'); | 8 | const uniqid = require('uniqid'); |
9 | 9 | ||
10 | const customPing = require('./custom-ping'); | 10 | const customPing = require('./custom-ping'); |
11 | const killOnIdle = require('./kill-on-idle'); | 11 | const killOnIdle = require('./kill-on-idle'); |
12 | const sender = require('./sender'); | ||
12 | 13 | ||
13 | let isReady; | 14 | let isReady; |
14 | 15 | ||
15 | bot.on('online', (data) => { | 16 | bot.on('online', (data) => { |
16 | logger.info(`XMPP transport connected, JID: ${data.jid.user}`); | 17 | logger.info(`XMPP transport connected, JID: ${data.jid.user}`); |
17 | 18 | ||
19 | sender.init(bot); | ||
20 | |||
18 | if (config.custom_ping) { | 21 | if (config.custom_ping) { |
19 | customPing.setBot(bot); | 22 | customPing.setBot(bot); |
20 | } | 23 | } |
21 | 24 | ||
22 | bot.getRoster(); | 25 | bot.getRoster(); |
23 | 26 | ||
24 | setTimeout( | 27 | setTimeout( |
25 | () => { | 28 | () => { |
26 | isReady = true; | 29 | isReady = true; |
27 | 30 | ||
28 | logger.verbose('Transport is ready'); | 31 | logger.verbose('Transport is ready'); |
29 | 32 | ||
30 | if (messagingService.onOnline) { | 33 | if (messagingService.onOnline) { |
31 | messagingService.onOnline({ | 34 | messagingService.onOnline({ |
32 | me: config.username, | 35 | me: config.username, |
33 | }); | 36 | }); |
34 | } | 37 | } |
35 | }, | 38 | }, |
36 | 39 | ||
37 | config.warming_up_ms || (30 * 1000), | 40 | config.warming_up_ms || (30 * 1000), |
38 | ); | 41 | ); |
39 | }); | 42 | }); |
40 | 43 | ||
41 | bot.on('chat', (partner, msg) => { | 44 | bot.on('chat', (partner, msg) => { |
42 | if (!msg || !msg.trim()) { | 45 | if (!msg || !msg.trim()) { |
43 | return; | 46 | return; |
44 | } | 47 | } |
45 | 48 | ||
46 | if (partner === config.username.replace(/\/.*$/, '')) { | 49 | if ((partner || '').toLowerCase() === config.username.toLowerCase().replace(/\/.*$/, '')) { |
47 | return; | 50 | return; |
48 | } | 51 | } |
49 | 52 | ||
50 | killOnIdle.touch(); | 53 | killOnIdle.touch(); |
51 | 54 | ||
52 | const xid = uniqid(); | 55 | const xid = uniqid(); |
53 | 56 | ||
54 | if (!isReady) { | 57 | if (!isReady) { |
55 | if (!customPing.isPingMessage(msg) && !customPing.isPongMessage(msg)) { | 58 | if (!customPing.isPingMessage(msg) && !customPing.isPongMessage(msg)) { |
56 | logger.warn('Warming up is not finished yet, ignoring message', { | 59 | logger.warn('Warming up is not finished yet, ignoring message', { |
57 | xid, me: config.username, partner, msg, | 60 | xid, me: config.username, partner, msg, |
58 | }); | 61 | }); |
59 | } | 62 | } |
60 | return; | 63 | return; |
61 | } | 64 | } |
62 | 65 | ||
63 | if (msg.toLowerCase().indexOf('error') === 0) { | 66 | if (msg.toLowerCase().indexOf('error') === 0) { |
64 | return; | 67 | return; |
65 | } | 68 | } |
66 | 69 | ||
67 | if (msg.toLowerCase().indexOf('perintah salah') === 0) { | 70 | if (msg.toLowerCase().indexOf('perintah salah') === 0) { |
68 | return; | 71 | return; |
69 | } | 72 | } |
70 | 73 | ||
71 | if (msg.toLowerCase().indexOf('pembelian ') === 0) { | 74 | if (msg.toLowerCase().indexOf('pembelian ') === 0) { |
72 | return; | 75 | return; |
73 | } | 76 | } |
74 | 77 | ||
75 | if (customPing.isPongMessage(msg)) { | 78 | if (customPing.isPongMessage(msg)) { |
76 | if (config.custom_ping && config.custom_ping.verbose) { | 79 | if (config.custom_ping && config.custom_ping.verbose) { |
77 | logger.verbose(`${MODULE_NAME} 70CDD087: Got PONG message`, { | 80 | logger.verbose(`${MODULE_NAME} 70CDD087: Got PONG message`, { |
78 | xid, | 81 | xid, |
79 | partner, | 82 | partner, |
80 | msg, | 83 | msg, |
81 | }); | 84 | }); |
82 | } | 85 | } |
83 | return; | 86 | return; |
84 | } | 87 | } |
85 | 88 | ||
86 | if (customPing.isPingMessage(msg)) { | 89 | if (customPing.isPingMessage(msg)) { |
87 | if (customPing.isAllowedPartner(partner)) { | 90 | if (customPing.isAllowedPartner(partner)) { |
88 | if (config.custom_ping && config.custom_ping.verbose) { | 91 | if (config.custom_ping && config.custom_ping.verbose) { |
89 | logger.verbose(`${MODULE_NAME} ED8C8786: Processing PING message`, { | 92 | logger.verbose(`${MODULE_NAME} ED8C8786: Processing PING message`, { |
90 | xid, | 93 | xid, |
91 | partner, | 94 | partner, |
92 | msg, | 95 | msg, |
93 | }); | 96 | }); |
94 | } | 97 | } |
95 | 98 | ||
96 | customPing.sendPong(xid, partner, msg); | 99 | customPing.sendPong(xid, partner, msg); |
97 | } | 100 | } |
98 | 101 | ||
99 | return; | 102 | return; |
100 | } | 103 | } |
101 | 104 | ||
102 | logger.info('Incoming message via XMPP transport', { | 105 | logger.info('Incoming message via XMPP transport', { |
103 | xid, me: config.username, partner, msg, | 106 | xid, me: config.username, partner, msg, |
104 | }); | 107 | }); |
105 | 108 | ||
106 | if (messagingService && messagingService.onIncomingMessage) { | 109 | if (messagingService && messagingService.onIncomingMessage) { |
107 | messagingService.onIncomingMessage( | 110 | messagingService.onIncomingMessage( |
108 | { | 111 | { |
109 | me: config.username, | 112 | me: config.username, |
110 | partner, | 113 | partner, |
111 | msg: msg.trim(), | 114 | msg: msg.trim(), |
112 | xid, | 115 | xid, |
113 | }, | 116 | }, |
114 | ); | 117 | ); |
115 | } | 118 | } |
116 | }); | 119 | }); |
117 | 120 | ||
118 | bot.on('error', (err) => { | 121 | bot.on('error', (err) => { |
119 | const xid = uniqid(); | 122 | const xid = uniqid(); |
120 | 123 | ||
121 | logger.warn(`${MODULE_NAME} F2E53C12: Error detected.`, { | 124 | logger.warn(`${MODULE_NAME} F2E53C12: Error detected.`, { |
122 | xid, | 125 | xid, |
123 | eCode: err.code, | 126 | eCode: err.code, |
124 | eMessage: err.message, | 127 | eMessage: err.message, |
125 | }); | 128 | }); |
126 | 129 | ||
127 | if (!config.do_not_terminate_on_error) { | 130 | if (!config.do_not_terminate_on_error) { |
128 | logger.warn(`${MODULE_NAME} BA6C0C55: Terminating on error`, { | 131 | logger.warn(`${MODULE_NAME} BA6C0C55: Terminating on error`, { |
129 | xid, | 132 | xid, |
130 | millisecondSleepBeforeTerminate: SLEEP_BEFORE_TERMINATE_ON_ERROR_MS, | 133 | millisecondSleepBeforeTerminate: SLEEP_BEFORE_TERMINATE_ON_ERROR_MS, |
131 | }); | 134 | }); |
132 | 135 | ||
133 | setTimeout(() => { | 136 | setTimeout(() => { |
134 | process.exit(1); | 137 | process.exit(1); |
135 | }, SLEEP_BEFORE_TERMINATE_ON_ERROR_MS); | 138 | }, SLEEP_BEFORE_TERMINATE_ON_ERROR_MS); |
136 | } | 139 | } |
137 | }); | 140 | }); |
138 | 141 | ||
139 | function send(partner, msg) { | 142 | function send(partner, msg, xid) { |
140 | logger.verbose('Sending message via XMPP transport', { | 143 | sender.send(partner, msg, xid); |
141 | transport: 'xmpp', me: config.username, partner, msg, | ||
142 | }); | ||
143 | bot.send(partner, msg); | ||
144 | } | 144 | } |
145 | 145 | ||
146 | bot.on('subscribe', (from) => { | 146 | bot.on('subscribe', (from) => { |
147 | logger.verbose(`Incoming subscribe request from ${from}`); | 147 | logger.verbose(`Incoming subscribe request from ${from}`); |
148 | bot.acceptSubscription(from); | 148 | bot.acceptSubscription(from); |
149 | bot.subscribe(from); | 149 | bot.subscribe(from); |
150 | }); | 150 | }); |
151 | 151 | ||
152 | function ping() { | 152 | function ping() { |
153 | if (isReady) bot.send(config.username, 'PING!'); | 153 | if (isReady) send(config.username, `PING ${uniqid()}`); |
154 | } | 154 | } |
155 | 155 | ||
156 | function init() { | 156 | function init() { |
157 | messagingService.setTransport(exports); | 157 | messagingService.setTransport(exports); |
158 | 158 | ||
159 | if (!killOnIdle.getDisabled()) { | 159 | if (!killOnIdle.getDisabled()) { |
160 | killOnIdle.init(); | 160 | killOnIdle.init(); |
161 | } | 161 | } |
162 | 162 | ||
163 | bot.connect({ | 163 | bot.connect({ |
164 | jid: config.username, | 164 | jid: config.username, |
165 | password: config.password, | 165 | password: config.password, |
166 | host: config.xmpp_host, | 166 | host: config.xmpp_host, |
167 | }); | 167 | }); |
168 | 168 | ||
169 | setInterval( | 169 | setInterval( |
170 | ping, | 170 | ping, |
171 | config.ping_interval_ms || 25000, | 171 | config.ping_interval_ms || 25000, |
172 | ); | 172 | ); |
173 | } | 173 | } |
174 | 174 | ||
175 | init(); | 175 | init(); |
176 | 176 |