Commit f43dbc16a329b2ffedd2103dc9ddbcb1343ef668
1 parent
4051d4be68
Exists in
master
New modem selector
Showing 7 changed files with 167 additions and 104 deletions Inline Diff
lib/apiserver/index.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | /** | 3 | /** |
4 | * Modul untuk menerima callback dari modem handler jika ada SMS masuk. | 4 | * Modul untuk menerima callback dari modem handler jika ada SMS masuk. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | const express = require('express'); | 8 | const express = require('express'); |
9 | const moment = require('moment'); | 9 | const moment = require('moment'); |
10 | 10 | ||
11 | const messagingService = require('komodo-center-messaging-client-lib'); | 11 | const messagingService = require('komodo-center-messaging-client-lib'); |
12 | 12 | ||
13 | const config = require('komodo-sdk/config'); | 13 | const config = require('komodo-sdk/config'); |
14 | const logger = require('komodo-sdk/logger'); | 14 | const logger = require('komodo-sdk/logger'); |
15 | 15 | ||
16 | const transport = require('../transport'); | 16 | const transport = require('../transport'); |
17 | const partnerLastSeen = require('../partner-last-seen'); | 17 | const partnerLastSeen = require('../partner-last-seen'); |
18 | const history = require('../history'); | 18 | const history = require('../history'); |
19 | const modems = require('../modems2'); | ||
19 | 20 | ||
20 | const app = express(); | 21 | const app = express(); |
21 | messagingService.setTransport(transport); | 22 | messagingService.setTransport(transport); |
22 | 23 | ||
23 | function apikeyChecker(req, res, next) { | 24 | function apikeyChecker(req, res, next) { |
24 | res.locals.has_valid_apikey = req.params.apikey === config.handler_callback_server.apikey; | 25 | res.locals.has_valid_apikey = req.params.apikey === config.handler_callback_server.apikey; |
25 | if (res.locals.has_valid_apikey) { | 26 | if (res.locals.has_valid_apikey) { |
26 | next(); | 27 | next(); |
27 | } | 28 | } |
28 | else { | 29 | else { |
29 | res.end('APISERVER: Invalid apikey'); | 30 | res.end('APISERVER: Invalid apikey'); |
30 | } | 31 | } |
31 | } | 32 | } |
32 | 33 | ||
33 | function onIncomingSms(req, res) { | 34 | function onIncomingSms(req, res) { |
34 | res.end('OK'); | 35 | res.end('OK'); |
35 | 36 | ||
36 | if (!req.query.number) return; | 37 | if (!req.query.number) return; |
37 | if (req.query.number.indexOf('+') !== 0) return; | 38 | if (req.query.number.indexOf('+') !== 0) return; |
38 | 39 | ||
39 | const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); | 40 | const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); |
40 | 41 | ||
41 | partnerLastSeen.set(req.query.number, req.query.modem); | 42 | partnerLastSeen.set(req.query.number, req.query.modem); |
42 | 43 | ||
43 | history.push({ | 44 | history.push({ |
44 | ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'), | 45 | ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'), |
45 | modem: { | 46 | modem: { |
46 | name: req.query.modem, | 47 | name: req.query.modem, |
47 | imsi: req.query.modem_imsi, | 48 | imsi: req.query.modem_imsi, |
48 | msisdn: req.query.modem_msisdn, | 49 | msisdn: req.query.modem_msisdn, |
49 | }, | 50 | }, |
50 | direction: 'INCOMING', | 51 | direction: 'INCOMING', |
51 | partner: req.query.number, | 52 | partner: req.query.number, |
52 | message: req.query.msg, | 53 | message: req.query.msg, |
53 | }); | 54 | }); |
54 | 55 | ||
56 | modems.set({ | ||
57 | name: req.query.modem, | ||
58 | imsi: req.query.modem_imsi, | ||
59 | msisdn: req.query.modem_msisdn, | ||
60 | reportIp: req.query.report_ip || req.ip, | ||
61 | reportPort: req.query.report_port, | ||
62 | reportApikey: req.query.report_apikey, | ||
63 | }); | ||
64 | |||
55 | logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); | 65 | logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); |
56 | messagingService.onIncomingMessage({ | 66 | messagingService.onIncomingMessage({ |
57 | me: req.query.modem, | 67 | me: req.query.modem, |
58 | partner: numberWithSuffix, | 68 | partner: numberWithSuffix, |
59 | msg: req.query.msg | 69 | msg: req.query.msg |
60 | }) | 70 | }) |
61 | } | 71 | } |
62 | 72 | ||
63 | async function pageHistory(req, res) { | 73 | async function pageHistory(req, res) { |
64 | res.json(await history.dump()); | 74 | res.json(await history.dump()); |
65 | } | 75 | } |
66 | 76 | ||
67 | app.use(function(req, res, next) { | 77 | app.use(function(req, res, next) { |
68 | logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url }); | 78 | logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url }); |
69 | next(); | 79 | next(); |
70 | }) | 80 | }) |
71 | 81 | ||
72 | app.use('/apikey/:apikey', apikeyChecker); | 82 | app.use('/apikey/:apikey', apikeyChecker); |
73 | app.get('/apikey/:apikey/on-sms', onIncomingSms); | 83 | app.get('/apikey/:apikey/on-sms', onIncomingSms); |
74 | app.get('/apikey/:apikey/inbox', onIncomingSms); | 84 | app.get('/apikey/:apikey/inbox', onIncomingSms); |
75 | app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); | 85 | app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); |
76 | app.get('/apikey/:apikey/history', pageHistory); | 86 | app.get('/apikey/:apikey/history', pageHistory); |
77 | 87 | ||
78 | const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null; | 88 | const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null; |
79 | listenPort && app.listen(listenPort, () => { | 89 | listenPort && app.listen(listenPort, () => { |
80 | logger.info('HTTP Handler Callback server listening on port ' + listenPort); | 90 | logger.info('HTTP Handler Callback server listening on port ' + listenPort); |
81 | }) | 91 | }) |
lib/modemSelect.js
File was created | 1 | "use strict"; | |
2 | |||
3 | function getModemConfig(modemName, modemsConfig) { | ||
4 | if (!modemsConfig) return; | ||
5 | if (!modemName) return; | ||
6 | if (typeof modemName === 'string' && !modemName.trim()) return; | ||
7 | |||
8 | return modemsConfig[modemName.trim()]; | ||
9 | } | ||
10 | |||
11 | function getModemUrl(modemName, modemsConfig) { | ||
12 | const modemConfig = getModemConfig(modemName, modemsConfig); | ||
13 | return modemConfig ? modemConfig.url : null; | ||
14 | } | ||
15 | |||
16 | function getModemApikey(modemName, modemsConfig) { | ||
17 | const modemConfig = getModemConfig(modemName, modemsConfig); | ||
18 | return modemConfig ? modemConfig.apikey : null; | ||
19 | } | ||
20 | |||
21 | function removeSuffixFromNumber(number, config) { | ||
22 | if (!config) { | ||
23 | config = {}; | ||
24 | } | ||
25 | |||
26 | const suffix = config && config.number_suffix ? config.number_suffix : '@.*'; | ||
27 | const re = new RegExp(suffix + '$'); | ||
28 | return number.replace(re, ''); | ||
29 | } | ||
30 | |||
31 | exports.getModemConfig = getModemConfig; | ||
32 | exports.getModemUrl = getModemUrl; | ||
33 | exports.getModemApikey = getModemApikey; | ||
34 | exports.removeSuffixFromNumber = removeSuffixFromNumber; |
lib/modems.js
1 | "use strict"; | File was deleted | |
2 | |||
3 | function getModemConfig(modemName, modemsConfig) { | ||
4 | if (!modemsConfig) return; | ||
5 | if (!modemName) return; | ||
6 | if (typeof modemName === 'string' && !modemName.trim()) return; | ||
7 | |||
8 | return modemsConfig[modemName.trim()]; | ||
9 | } | ||
10 | |||
11 | function getModemUrl(modemName, modemsConfig) { | ||
12 | const modemConfig = getModemConfig(modemName, modemsConfig); | ||
13 | return modemConfig ? modemConfig.url : null; | ||
14 | } | ||
15 | |||
16 | function getModemApikey(modemName, modemsConfig) { | ||
17 | const modemConfig = getModemConfig(modemName, modemsConfig); | ||
18 | return modemConfig ? modemConfig.apikey : null; | ||
19 | } | ||
20 | |||
21 | function removeSuffixFromNumber(number, config) { | ||
22 | if (!config) { | ||
23 | config = {}; | ||
24 | } | ||
25 | |||
26 | const suffix = config && config.number_suffix ? config.number_suffix : '@.*'; | ||
27 | const re = new RegExp(suffix + '$'); | ||
28 | return number.replace(re, ''); | ||
29 | } | ||
30 | |||
31 | exports.getModemConfig = getModemConfig; | ||
32 | exports.getModemUrl = getModemUrl; | ||
33 | exports.getModemApikey = getModemApikey; | ||
34 | exports.removeSuffixFromNumber = removeSuffixFromNumber; |
lib/modems2.js
File was created | 1 | 'use strict'; | |
2 | |||
3 | const modemList = { | ||
4 | by_name: {}, | ||
5 | by_imsi: {}, | ||
6 | by_msisdn: {}, | ||
7 | }; | ||
8 | |||
9 | /** | ||
10 | * Objek data sebuah modem. | ||
11 | * | ||
12 | * @typedef {Object} ModemData | ||
13 | * @property {string} name - nama modem | ||
14 | * @property {string} imsi - IMSI modem | ||
15 | * @property {string} msisdn - MSISDN modem | ||
16 | * @property {string} reportIp - IP modem | ||
17 | * @property {number} reportPort - TCP port modem | ||
18 | * @property {string} reportApikey - APIKEY modem | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * Update data sebuah modem berdasarkan nama modem. | ||
23 | * | ||
24 | * @param {ModemData} val - objek data modem | ||
25 | */ | ||
26 | function touchByName(val) { | ||
27 | if (!val || !val.name) return; | ||
28 | if (typeof val.name !== 'string') return; | ||
29 | if (!val.name.trim()) return; | ||
30 | |||
31 | modemList.by_name[val.name] = val; | ||
32 | } | ||
33 | /** | ||
34 | * Update data sebuah modem berdasarkan IMSI. | ||
35 | * | ||
36 | * @param {ModemData} val - objek data modem | ||
37 | */ | ||
38 | function touchByIMSI(val) { | ||
39 | if (!val || !val.imsi) return; | ||
40 | if (typeof val.imsi !== 'string') return; | ||
41 | if (!val.imsi.trim()) return; | ||
42 | |||
43 | modemList.by_imsi[val.imsi] = val; | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * Update data sebuah modem berdasarkan MSISDN. | ||
48 | * | ||
49 | * @param {ModemData} val - objek data modem | ||
50 | */ | ||
51 | function touchByMSISDN(val) { | ||
52 | if (!val || !val.msisdn) return; | ||
53 | if (typeof val.msisdn !== 'string') return; | ||
54 | if (!val.msisdn.trim()) return; | ||
55 | |||
56 | modemList.by_msisdn[val.msisdn] = val; | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Update data sebuah modem. | ||
61 | * | ||
62 | * @param {ModemData} val - objek data modem | ||
63 | * @see ModemData | ||
64 | */ | ||
65 | function touch(val) { | ||
66 | if (!val) return; | ||
67 | |||
68 | if (!val.reportIp) { | ||
69 | val.reportIp = '127.0.0.1'; | ||
70 | } | ||
71 | |||
72 | touchByName(val); | ||
73 | touchByIMSI(val); | ||
74 | touchByMSISDN(val); | ||
75 | } | ||
76 | /** | ||
77 | * Ambil data sebuah modem. | ||
78 | * | ||
79 | * @param {string} selector - selector pencarian, valid jika bernilai salah satu dari: name, imsi, msisdn | ||
80 | * @param {string} keyword - kata kunci modem yang ingin diambil | ||
81 | * @returns {ModemData} data modem terkait | ||
82 | */ | ||
83 | function get(selector, keyword) { | ||
84 | if (!selector || !keyword) return null; | ||
85 | |||
86 | return modemList[`by_${selector}`] ? modemList[`by_${selector}`][keyword] : null; | ||
87 | } | ||
88 | |||
89 | exports.touch = touch; | ||
90 | exports.set = touch; | ||
91 | exports.get = get; |
lib/partner-last-seen.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | const REDIS_TTL_SECS = 3600 * 24 * 7; | 3 | const REDIS_TTL_SECS = 3600 * 24 * 31; |
4 | 4 | ||
5 | const config = require('komodo-sdk/config'); | 5 | const config = require('komodo-sdk/config'); |
6 | // const logger = require('komodo-sdk/logger'); | 6 | // const logger = require('komodo-sdk/logger'); |
7 | 7 | ||
8 | const redis = require('redis'); | 8 | const redis = require('redis'); |
9 | const redisClient = redis.createClient(config.redis || { host: '127.0.0.1' }); | 9 | const redisClient = redis.createClient(config.redis || { host: '127.0.0.1' }); |
10 | 10 | ||
11 | const _caches = {}; | 11 | const _caches = {}; |
12 | 12 | ||
13 | 13 | ||
14 | function _composeKeyword(partner) { | 14 | function _composeKeyword(partner) { |
15 | return `POCHINKI_PARTNER_LAST_SEEN_${ partner }`; | 15 | return `POCHINKI_PARTNER_LAST_SEEN_${ partner }`; |
16 | } | 16 | } |
17 | 17 | ||
18 | function get(partnerNumber) { | 18 | function get(partnerNumber) { |
19 | return new Promise(function(resolve) { | 19 | return new Promise(function(resolve) { |
20 | 20 | ||
21 | partnerNumber = (partnerNumber || '').replace(/^\+/, ''); | 21 | partnerNumber = (partnerNumber || '').replace(/^\+/, ''); |
22 | 22 | ||
23 | if (!partnerNumber) { | 23 | if (!partnerNumber) { |
24 | resolve(null); | 24 | resolve(null); |
25 | } | 25 | } |
26 | else if (_caches[partnerNumber]) { | 26 | else if (_caches[partnerNumber]) { |
27 | resolve(_caches[partnerNumber]); | 27 | resolve(_caches[partnerNumber]); |
28 | } | 28 | } |
29 | else { | 29 | else { |
30 | const keyword = _composeKeyword(partnerNumber); | 30 | const keyword = _composeKeyword(partnerNumber); |
31 | // logger.verbose(`REDIS-DEBUG: GET`, {keyword}); | 31 | // logger.verbose(`REDIS-DEBUG: GET`, {keyword}); |
32 | 32 | ||
33 | redisClient.get(keyword, function(err, reply) { | 33 | redisClient.get(keyword, function(err, reply) { |
34 | if (err) { | 34 | if (err) { |
35 | resolve(null); | 35 | resolve(null); |
36 | } | 36 | } |
37 | else if (reply) { | 37 | else if (reply) { |
38 | resolve(Number(reply)); | 38 | resolve(Number(reply)); |
39 | _caches[partnerNumber] = Number(reply); | 39 | _caches[partnerNumber] = Number(reply); |
40 | } | 40 | } |
41 | else { | 41 | else { |
42 | resolve(null); | 42 | resolve(null); |
43 | } | 43 | } |
44 | }) | 44 | }) |
45 | } | 45 | } |
46 | }) | 46 | }) |
47 | } | 47 | } |
48 | 48 | ||
49 | function set(partnerNumber, modemName) { | 49 | function set(partnerNumber, modemName) { |
50 | partnerNumber = (partnerNumber || '').replace(/^\+/, ''); | 50 | partnerNumber = (partnerNumber || '').replace(/^\+/, ''); |
51 | 51 | ||
52 | if (!partnerNumber || !modemName) { | 52 | if (!partnerNumber || !modemName) { |
53 | return; | 53 | return; |
54 | } | 54 | } |
55 | 55 | ||
56 | _caches[partnerNumber] = modemName; | 56 | _caches[partnerNumber] = modemName; |
57 | 57 | ||
58 | const keyword = _composeKeyword(partnerNumber); | 58 | const keyword = _composeKeyword(partnerNumber); |
59 | // logger.verbose('REDIS-DEBUG: SET', { keyword }) | 59 | // logger.verbose('REDIS-DEBUG: SET', { keyword }) |
60 | redisClient.set(keyword, modemName, 'EX', REDIS_TTL_SECS); | 60 | redisClient.set(keyword, modemName, 'EX', REDIS_TTL_SECS); |
61 | } | 61 | } |
62 | 62 | ||
63 | exports.get = get; | 63 | exports.get = get; |
64 | exports.set = set; | 64 | exports.set = set; |
65 | 65 |
lib/transport.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | const url = require('url'); | ||
3 | const request = require('request'); | 4 | const request = require('request'); |
4 | const uuidv4 = require('uuid/v4'); | 5 | const uuidv4 = require('uuid/v4'); |
5 | const moment = require('moment'); | 6 | const moment = require('moment'); |
6 | 7 | ||
7 | const config = require('komodo-sdk/config'); | 8 | const config = require('komodo-sdk/config'); |
8 | const logger = require('komodo-sdk/logger'); | 9 | const logger = require('komodo-sdk/logger'); |
9 | 10 | ||
10 | const modems = require('./modems'); | 11 | const modemSelect = require('./modemSelect'); |
12 | const modems = require('./modems2'); | ||
11 | const partnerLastSeen = require('./partner-last-seen'); | 13 | const partnerLastSeen = require('./partner-last-seen'); |
12 | const history = require('./history'); | 14 | const history = require('./history'); |
13 | 15 | ||
14 | async function _getApproriateHandlerByLastSeen(partnerNumber) { | ||
15 | logger.verbose('Looking for last seen on for partner number ' + partnerNumber); | ||
16 | const lastSeenFrom = await partnerLastSeen.get(partnerNumber); | ||
17 | return lastSeenFrom; | ||
18 | } | ||
19 | |||
20 | function _getApproriateHandlerByForced() { | ||
21 | if (!config.sending_handler || !config.sending_handler.length) return; | ||
22 | |||
23 | const sendingHandlerCount = config.sending_handler.length; | ||
24 | const idx = Math.floor(Math.random() * sendingHandlerCount); | ||
25 | return config.sending_handler[idx]; | ||
26 | } | ||
27 | |||
28 | async function _getApproriateHandler(partnerNumber, origin) { | ||
29 | let handlerToUse; | ||
30 | |||
31 | if (config.handler_chooser_algorithm === 'FORCED') { | ||
32 | handlerToUse = _getApproriateHandlerByForced(); | ||
33 | logger.verbose('Config file mentioned to using FORCED handler chooser algorithm', { handler_to_use: handlerToUse}); | ||
34 | } | ||
35 | else { | ||
36 | handlerToUse = await _getApproriateHandlerByLastSeen(partnerNumber); | ||
37 | logger.verbose('Config file mentioned to using LAST-SEEN handler chooser algorithm', { handler_to_use: handlerToUse}); | ||
38 | } | ||
39 | |||
40 | if (!modems.getModemConfig(handlerToUse, config.modems)) { | ||
41 | const handlerWithSameOrigin = modems.getModemConfig(origin, config.modems); | ||
42 | if (handlerWithSameOrigin) { | ||
43 | logger.verbose('Invalid approriate handler, using handler from the same ORIGIN request by CORE to send sms') | ||
44 | handlerToUse = origin; | ||
45 | } | ||
46 | else { | ||
47 | logger.verbose('Invalid approriate handler, using default handler to send sms') | ||
48 | handlerToUse = config.default_modem; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | return handlerToUse; | ||
53 | } | ||
54 | |||
55 | function _send(destinationNumber, msg, handlerName) { | 16 | function _send(destinationNumber, msg, handlerName) { |
56 | 17 | ||
57 | /* | ||
58 | if (msg.length > 160 && !config.do_not_trim_long_sms) { | ||
59 | logger.verbose('Message trim to 160 chars'); | ||
60 | msg = msg.slice(0, 156) + ' ...'; | ||
61 | } | ||
62 | */ | ||
63 | |||
64 | if (msg.length > 160) { | 18 | if (msg.length > 160) { |
65 | const newMsg = msg.slice(0, 160); | 19 | const newMsg = msg.slice(0, 160); |
66 | const remainingMsg = msg.slice(160); | 20 | const remainingMsg = msg.slice(160); |
67 | 21 | ||
68 | _send(destinationNumber, newMsg, handlerName); | 22 | _send(destinationNumber, newMsg, handlerName); |
69 | setTimeout(() => { | 23 | setTimeout(() => { |
70 | _send(destinationNumber, remainingMsg, handlerName); | 24 | _send(destinationNumber, remainingMsg, handlerName); |
71 | }, 2000); | 25 | }, 2000); |
72 | 26 | ||
73 | return; | 27 | return; |
74 | } | 28 | } |
75 | 29 | ||
76 | const modem = modems.getModemConfig(handlerName, config.modems); | 30 | const modem = modems.get('name', handlerName); |
77 | if (!modem) { | 31 | if (!modem) { |
78 | logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, handler_name: handlerName }); | 32 | logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, handler_name: handlerName }); |
79 | return; | 33 | return; |
80 | } | 34 | } |
81 | 35 | ||
82 | if (!modem.url || !modem.apikey) { | 36 | if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) { |
83 | logger.warn('Invalid modem configuration', { config: modem, handler_name: handlerName }); | 37 | logger.warn('Invalid modem configuration', { modem }); |
84 | return; | 38 | return; |
85 | } | 39 | } |
86 | 40 | ||
87 | const reqId = uuidv4(); | 41 | const reqId = uuidv4(); |
88 | 42 | ||
89 | history.push({ | 43 | history.push({ |
90 | ts: moment().format('YYYY-MM-DD HH:mm:ss'), | 44 | ts: moment().format('YYYY-MM-DD HH:mm:ss'), |
91 | modem: { | 45 | modem: { |
92 | name: handlerName, | 46 | name: handlerName, |
93 | }, | 47 | }, |
94 | direction: 'OUTGOING', | 48 | direction: 'OUTGOING', |
95 | partner: destinationNumber, | 49 | partner: destinationNumber, |
96 | message: msg, | 50 | message: msg, |
97 | }); | 51 | }); |
98 | 52 | ||
99 | |||
100 | const requestOptions = { | 53 | const requestOptions = { |
101 | url: modem.url, | 54 | url: url.format({ |
55 | protocol: 'http', | ||
56 | hostname: modem.reportIp, | ||
57 | port: modem.reportPort, | ||
58 | }), | ||
102 | qs: { | 59 | qs: { |
103 | msg: msg, | 60 | msg: msg, |
104 | number: destinationNumber, | 61 | number: destinationNumber, |
105 | reqid: reqId, | 62 | reqid: reqId, |
106 | apikey: modem.apikey | 63 | apikey: modem.reportApikey |
107 | } | 64 | } |
108 | } | 65 | } |
109 | 66 | ||
110 | logger.info('Sending message to modem handler', { req_id: reqId, destination_number: destinationNumber, msg: msg, msg_length: msg.length, handler_name: handlerName }); | 67 | logger.info('Sending message to modem handler', { req_id: reqId, destination_number: destinationNumber, msg: msg, msg_length: msg.length, handler_name: handlerName }); |
111 | request(requestOptions, function(err, res, body) { | 68 | request(requestOptions, function(err, res, body) { |
112 | if (err) { | 69 | if (err) { |
113 | logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, handler_name: handlerName }); | 70 | logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, handler_name: handlerName }); |
114 | 71 | ||
115 | } | 72 | } |
116 | else if (res.statusCode != 200) { | 73 | else if (res.statusCode != 200) { |
117 | logger.warn('Modem handler not responding with HTTP status code 200.', { http_status_code: res.statusCode, req_id: reqId, handler_name: handlerName }); | 74 | logger.warn('Modem handler not responding with HTTP status code 200.', { http_status_code: res.statusCode, req_id: reqId, handler_name: handlerName }); |
118 | } | 75 | } |
119 | else { | 76 | else { |
120 | logger.verbose('Message sent to handler', { req_id: reqId, handler_name: handlerName, response_body: body }); | 77 | logger.verbose('Message sent to handler', { req_id: reqId, handler_name: handlerName, response_body: body }); |
121 | } | 78 | } |
122 | }) | 79 | }) |
123 | 80 | ||
124 | } | 81 | } |
125 | 82 | ||
126 | async function send(partner, msg, origin) { | 83 | async function send(partner, msg, origin) { |
127 | if (!partner) return; | 84 | if (!partner) return; |
128 | 85 | ||
129 | if (typeof msg !== 'string') { | 86 | if (typeof msg !== 'string') { |
130 | logger.warn('Message to send is not a string, ignoring message'); | 87 | logger.warn('Message to send is not a string, ignoring message'); |
131 | return; | 88 | return; |
132 | } | 89 | } |
133 | 90 | ||
134 | msg = msg.trim(); | 91 | msg = msg.trim(); |
135 | if (!msg) return; | 92 | if (!msg) return; |
136 | 93 | ||
137 | const destinationNumber = modems.removeSuffixFromNumber(partner, config); | 94 | const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config); |
95 | |||
96 | // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin }); |
test/modems.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | /* global describe it */ | 3 | /* global describe it */ |
4 | 4 | ||
5 | const should = require('should'); | 5 | const should = require('should'); |
6 | 6 | ||
7 | const modems = require('../lib/modems'); | 7 | const modemSelect = require('../lib/modemSelect'); |
8 | 8 | ||
9 | describe('#modems', function() { | 9 | describe('#modemSelect', function() { |
10 | 10 | ||
11 | describe('#getModemUrl', function() { | 11 | describe('#getModemUrl', function() { |
12 | 12 | ||
13 | const modemsConfig = { | 13 | const modemsConfig = { |
14 | SMS0: { | 14 | SMS0: { |
15 | url: "http://localhost:8888/" | 15 | url: "http://localhost:8888/" |
16 | } | 16 | } |
17 | } | 17 | } |
18 | 18 | ||
19 | it('should return correct url', function() { | 19 | it('should return correct url', function() { |
20 | modems.getModemUrl('SMS0', modemsConfig).should.equal('http://localhost:8888/'); | 20 | modemSelect.getModemUrl('SMS0', modemsConfig).should.equal('http://localhost:8888/'); |
21 | }) | 21 | }) |
22 | 22 | ||
23 | it ('should handle missing modems', function() { | 23 | it ('should handle missing modems', function() { |
24 | should.not.exists(modems.getModemUrl('SMS0', null)); | 24 | should.not.exists(modemSelect.getModemUrl('SMS0', null)); |
25 | should.not.exists(modems.getModemUrl('SMS0', {})); | 25 | should.not.exists(modemSelect.getModemUrl('SMS0', {})); |
26 | should.not.exists(modems.getModemUrl('SMS1', modemsConfig)); | 26 | should.not.exists(modemSelect.getModemUrl('SMS1', modemsConfig)); |
27 | }) | 27 | }) |
28 | }) | 28 | }) |
29 | 29 | ||
30 | describe('#removeSuffixFromNumber', function() { | 30 | describe('#removeSuffixFromNumber', function() { |
31 | const config = { | 31 | const config = { |
32 | number_suffix: '@phonenumber' | 32 | number_suffix: '@phonenumber' |
33 | } | 33 | } |
34 | 34 | ||
35 | it('should return correct number', function() { | 35 | it('should return correct number', function() { |
36 | modems.removeSuffixFromNumber('08181234@phonenumber', config).should.equal('08181234'); | 36 | modemSelect.removeSuffixFromNumber('08181234@phonenumber', config).should.equal('08181234'); |
37 | }) | 37 | }) |
38 | 38 | ||
39 | it ('should return correct number without suffix in the number', function() { | 39 | it ('should return correct number without suffix in the number', function() { |
40 | modems.removeSuffixFromNumber('08181234', config).should.equal('08181234'); | 40 | modemSelect.removeSuffixFromNumber('08181234', config).should.equal('08181234'); |
41 | }) | 41 | }) |
42 | 42 | ||
43 | it ('should return correct number without suffix in config', function() { | 43 | it ('should return correct number without suffix in config', function() { |
44 | modems.removeSuffixFromNumber('08181234', null).should.equal('08181234'); | 44 | modemSelect.removeSuffixFromNumber('08181234', null).should.equal('08181234'); |
45 | modems.removeSuffixFromNumber('08181234', {}).should.equal('08181234'); | 45 | modemSelect.removeSuffixFromNumber('08181234', {}).should.equal('08181234'); |
46 | modems.removeSuffixFromNumber('08181234@phonenumber', {}).should.equal('08181234'); | 46 | modemSelect.removeSuffixFromNumber('08181234@phonenumber', {}).should.equal('08181234'); |
47 | }) | 47 | }) |
48 | }) | 48 | }) |
49 | 49 | ||
50 | }) | 50 | }) |