Compare View

switch
from
...
to
 
Commits (3)

Changes

Showing 9 changed files Side-by-side Diff

lib/apiserver/index.js
... ... @@ -16,6 +16,7 @@ const logger = require('komodo-sdk/logger');
16 16 const transport = require('../transport');
17 17 const partnerLastSeen = require('../partner-last-seen');
18 18 const history = require('../history');
  19 +const modems = require('../modems2');
19 20  
20 21 const app = express();
21 22 messagingService.setTransport(transport);
... ... @@ -52,6 +53,15 @@ function onIncomingSms(req, res) {
52 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 65 logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg });
56 66 messagingService.onIncomingMessage({
57 67 me: req.query.modem,
... ... @@ -0,0 +1,34 @@
  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;
0 35 \ No newline at end of file
... ... @@ -0,0 +1,91 @@
  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;
0 92 \ No newline at end of file
lib/partner-last-seen.js
1 1 "use strict";
2 2  
3   -const REDIS_TTL_SECS = 3600 * 24 * 7;
  3 +const REDIS_TTL_SECS = 3600 * 24 * 31;
4 4  
5 5 const config = require('komodo-sdk/config');
6 6 // const logger = require('komodo-sdk/logger');
1 1 "use strict";
2 2  
  3 +const url = require('url');
3 4 const request = require('request');
4 5 const uuidv4 = require('uuid/v4');
5 6 const moment = require('moment');
... ... @@ -7,60 +8,13 @@ const moment = require('moment');
7 8 const config = require('komodo-sdk/config');
8 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 13 const partnerLastSeen = require('./partner-last-seen');
12 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 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 18 if (msg.length > 160) {
65 19 const newMsg = msg.slice(0, 160);
66 20 const remainingMsg = msg.slice(160);
... ... @@ -73,14 +27,14 @@ function _send(destinationNumber, msg, handlerName) {
73 27 return;
74 28 }
75 29  
76   - const modem = modems.getModemConfig(handlerName, config.modems);
  30 + const modem = modems.get('name', handlerName);
77 31 if (!modem) {
78 32 logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, handler_name: handlerName });
79 33 return;
80 34 }
81 35  
82   - if (!modem.url || !modem.apikey) {
83   - logger.warn('Invalid modem configuration', { config: modem, handler_name: handlerName });
  36 + if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) {
  37 + logger.warn('Invalid modem configuration', { modem });
84 38 return;
85 39 }
86 40  
... ... @@ -96,14 +50,17 @@ function _send(destinationNumber, msg, handlerName) {
96 50 message: msg,
97 51 });
98 52  
99   -
100 53 const requestOptions = {
101   - url: modem.url,
  54 + url: url.format({
  55 + protocol: 'http',
  56 + hostname: modem.reportIp,
  57 + port: modem.reportPort,
  58 + }),
102 59 qs: {
103 60 msg: msg,
104 61 number: destinationNumber,
105 62 reqid: reqId,
106   - apikey: modem.apikey
  63 + apikey: modem.reportApikey
107 64 }
108 65 }
109 66  
... ... @@ -123,7 +80,7 @@ function _send(destinationNumber, msg, handlerName) {
123 80  
124 81 }
125 82  
126   -async function send(partner, msg, origin) {
  83 +async function send(partner, msg) {
127 84 if (!partner) return;
128 85  
129 86 if (typeof msg !== 'string') {
... ... @@ -134,10 +91,15 @@ async function send(partner, msg, origin) {
134 91 msg = msg.trim();
135 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 });
  97 + let handlerName = await partnerLastSeen.get(destinationNumber) ;
138 98  
139   - logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin });
140   - let handlerName = ( await _getApproriateHandler(destinationNumber) );
  99 + if (!handlerName) {
  100 + logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber });
  101 + return;
  102 + }
141 103  
142 104 _send(destinationNumber, msg, handlerName);
143 105 }
1 1 {
2 2 "name": "komodo-center-sms",
3   - "version": "0.9.14",
  3 + "version": "0.9.15",
4 4 "lockfileVersion": 1,
5 5 "requires": true,
6 6 "dependencies": {
1 1 {
2 2 "name": "komodo-center-sms",
3   - "version": "0.9.14",
  3 + "version": "0.9.15",
4 4 "description": "SMS center for Komodo",
5 5 "main": "index.js",
6 6 "scripts": {
... ... @@ -4,9 +4,9 @@
4 4  
5 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 11 describe('#getModemUrl', function() {
12 12  
... ... @@ -17,13 +17,13 @@ describe('#modems', function() {
17 17 }
18 18  
19 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 23 it ('should handle missing modems', function() {
24   - should.not.exists(modems.getModemUrl('SMS0', null));
25   - should.not.exists(modems.getModemUrl('SMS0', {}));
26   - should.not.exists(modems.getModemUrl('SMS1', modemsConfig));
  24 + should.not.exists(modemSelect.getModemUrl('SMS0', null));
  25 + should.not.exists(modemSelect.getModemUrl('SMS0', {}));
  26 + should.not.exists(modemSelect.getModemUrl('SMS1', modemsConfig));
27 27 })
28 28 })
29 29  
... ... @@ -33,17 +33,17 @@ describe('#modems', function() {
33 33 }
34 34  
35 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 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 43 it ('should return correct number without suffix in config', function() {
44   - modems.removeSuffixFromNumber('08181234', null).should.equal('08181234');
45   - modems.removeSuffixFromNumber('08181234', {}).should.equal('08181234');
46   - modems.removeSuffixFromNumber('08181234@phonenumber', {}).should.equal('08181234');
  44 + modemSelect.removeSuffixFromNumber('08181234', null).should.equal('08181234');
  45 + modemSelect.removeSuffixFromNumber('08181234', {}).should.equal('08181234');
  46 + modemSelect.removeSuffixFromNumber('08181234@phonenumber', {}).should.equal('08181234');
47 47 })
48 48 })
49 49