Commit 03f73469d9d7d21b16664e680138449d2f9bc98c

Authored by Adhidarma Hadiwinoto
1 parent c6c4d8d275
Exists in master

Partner last seen by IMSI

Showing 2 changed files with 19 additions and 15 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 const modems = require('../modems2');
20 20
21 const app = express(); 21 const app = express();
22 messagingService.setTransport(transport); 22 messagingService.setTransport(transport);
23 23
24 function apikeyChecker(req, res, next) { 24 function apikeyChecker(req, res, next) {
25 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;
26 if (res.locals.has_valid_apikey) { 26 if (res.locals.has_valid_apikey) {
27 next(); 27 next();
28 } 28 }
29 else { 29 else {
30 res.end('APISERVER: Invalid apikey'); 30 res.end('APISERVER: Invalid apikey');
31 } 31 }
32 } 32 }
33 33
34 function onIncomingSms(req, res) { 34 function onIncomingSms(req, res) {
35 res.end('OK'); 35 res.end('OK');
36 36
37 if (!req.query.number) return; 37 if (!req.query.number) return;
38 if (req.query.number.indexOf('+') !== 0) return; 38 if (req.query.number.indexOf('+') !== 0) return;
39 39
40 const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); 40 const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || '');
41 41
42 partnerLastSeen.set(req.query.number, req.query.modem); 42 partnerLastSeen.set(req.query.number, req.query.modem_imsi);
43 43
44 history.push({ 44 history.push({
45 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'),
46 modem: { 46 modem: {
47 name: req.query.modem, 47 name: req.query.modem,
48 imsi: req.query.modem_imsi, 48 imsi: req.query.modem_imsi,
49 msisdn: req.query.modem_msisdn, 49 msisdn: req.query.modem_msisdn,
50 }, 50 },
51 direction: 'INCOMING', 51 direction: 'INCOMING',
52 partner: req.query.number, 52 partner: req.query.number,
53 message: req.query.msg, 53 message: req.query.msg,
54 }); 54 });
55 55
56 modems.set({ 56 modems.set({
57 name: req.query.modem, 57 name: req.query.modem,
58 imsi: req.query.modem_imsi, 58 imsi: req.query.modem_imsi,
59 msisdn: req.query.modem_msisdn, 59 msisdn: req.query.modem_msisdn,
60 device: req.query.modem_device, 60 device: req.query.modem_device,
61 uptime: req.query.uptime, 61 uptime: req.query.uptime,
62 reportIp: req.query.report_ip || req.ip, 62 reportIp: req.query.report_ip || req.ip,
63 reportPort: req.query.report_port, 63 reportPort: req.query.report_port,
64 reportApikey: req.query.report_apikey, 64 reportApikey: req.query.report_apikey,
65 reportPathSms: req.query.report_path_sms || '/sms', 65 reportPathSms: req.query.report_path_sms || '/sms',
66 }); 66 });
67 67
68 logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); 68 logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg });
69 messagingService.onIncomingMessage({ 69 messagingService.onIncomingMessage({
70 me: req.query.modem, 70 me: req.query.modem,
71 partner: numberWithSuffix, 71 partner: numberWithSuffix,
72 msg: req.query.msg 72 msg: req.query.msg
73 }) 73 })
74 } 74 }
75 75
76 async function pageHistory(req, res) { 76 async function pageHistory(req, res) {
77 res.json(await history.dump()); 77 res.json(await history.dump());
78 } 78 }
79 79
80 app.use(function(req, res, next) { 80 app.use(function(req, res, next) {
81 logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url }); 81 logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url });
82 next(); 82 next();
83 }) 83 })
84 84
85 app.use('/apikey/:apikey', apikeyChecker); 85 app.use('/apikey/:apikey', apikeyChecker);
86 app.get('/apikey/:apikey/on-sms', onIncomingSms); 86 app.get('/apikey/:apikey/on-sms', onIncomingSms);
87 app.get('/apikey/:apikey/inbox', onIncomingSms); 87 app.get('/apikey/:apikey/inbox', onIncomingSms);
88 app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); 88 app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms);
89 app.get('/apikey/:apikey/history', pageHistory); 89 app.get('/apikey/:apikey/history', pageHistory);
90 90
91 const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null; 91 const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null;
92 listenPort && app.listen(listenPort, () => { 92 listenPort && app.listen(listenPort, () => {
93 logger.info('HTTP Handler Callback server listening on port ' + listenPort); 93 logger.info('HTTP Handler Callback server listening on port ' + listenPort);
94 }) 94 })
1 "use strict"; 1 "use strict";
2 2
3 const url = require('url'); 3 const url = require('url');
4 const request = require('request'); 4 const request = require('request');
5 const uuidv4 = require('uuid/v4'); 5 const uuidv4 = require('uuid/v4');
6 const moment = require('moment'); 6 const moment = require('moment');
7 7
8 const config = require('komodo-sdk/config'); 8 const config = require('komodo-sdk/config');
9 const logger = require('komodo-sdk/logger'); 9 const logger = require('komodo-sdk/logger');
10 10
11 const modemSelect = require('./modemSelect'); 11 const modemSelect = require('./modemSelect');
12 const modems = require('./modems2'); 12 const modems = require('./modems2');
13 const partnerLastSeen = require('./partner-last-seen'); 13 const partnerLastSeen = require('./partner-last-seen');
14 const history = require('./history'); 14 const history = require('./history');
15 15
16 function _send(destinationNumber, msg, handlerName) { 16 function _send(destinationNumber, msg, handlerIMSI) {
17 17
18 if (msg.length > 160) { 18 if (msg.length > 160) {
19 logger.info('Splitting message');
20
19 const newMsg = msg.slice(0, 160); 21 const newMsg = msg.slice(0, 160);
20 const remainingMsg = msg.slice(160); 22 const remainingMsg = msg.slice(160);
21 23
22 _send(destinationNumber, newMsg, handlerName); 24 _send(destinationNumber, newMsg, handlerIMSI);
23 setTimeout(() => { 25 setTimeout(() => {
24 _send(destinationNumber, remainingMsg, handlerName); 26 _send(destinationNumber, remainingMsg, handlerIMSI);
25 }, 2000); 27 }, 1000);
26 28
27 return; 29 return;
28 } 30 }
29 31
30 const modem = modems.get('name', handlerName); 32 const modem = modems.get('imsi', handlerIMSI);
31 if (!modem) { 33 if (!modem) {
32 logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, handler_name: handlerName }); 34 logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, modem_imsi: handlerIMSI });
33 return; 35 return;
34 } 36 }
35 37
36 if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) { 38 if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) {
37 logger.warn('Invalid modem configuration', { modem }); 39 logger.warn('Invalid modem configuration', { modem });
38 return; 40 return;
39 } 41 }
40 42
41 const reqId = uuidv4(); 43 const reqId = uuidv4();
42 44
43 history.push({ 45 history.push({
44 ts: moment().format('YYYY-MM-DD HH:mm:ss'), 46 ts: moment().format('YYYY-MM-DD HH:mm:ss'),
45 modem: { 47 modem: {
46 name: handlerName, 48 name: modem.name,
49 imsi: modem.imsi,
50 msisdn: modem.msisdn,
47 }, 51 },
48 direction: 'OUTGOING', 52 direction: 'OUTGOING',
49 partner: destinationNumber, 53 partner: destinationNumber,
50 message: msg, 54 message: msg,
51 }); 55 });
52 56
53 const requestOptions = { 57 const requestOptions = {
54 url: url.format({ 58 url: url.format({
55 protocol: 'http', 59 protocol: 'http',
56 hostname: modem.reportIp, 60 hostname: modem.reportIp,
57 port: modem.reportPort, 61 port: modem.reportPort,
58 pathname: modem.reportPathSms || '/sms', 62 pathname: modem.reportPathSms || '/sms',
59 }), 63 }),
60 qs: { 64 qs: {
61 msg: msg, 65 msg: msg,
62 number: destinationNumber, 66 number: destinationNumber,
63 reqid: reqId, 67 reqid: reqId,
64 apikey: modem.reportApikey, 68 apikey: modem.reportApikey,
65 } 69 }
66 } 70 }
67 71
68 logger.info('Sending message to modem handler', { req_id: reqId, destination_number: destinationNumber, msg: msg, msg_length: msg.length, handler_name: handlerName }); 72 logger.info('Sending message to modem handler', { req_id: reqId, destination_number: destinationNumber, msg: msg, msg_length: msg.length, modem_name: modem.name, modem_imsi: modem.imsi });
69 request(requestOptions, function(err, res, body) { 73 request(requestOptions, function(err, res, body) {
70 if (err) { 74 if (err) {
71 logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, handler_name: handlerName }); 75 logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi });
72 76
73 } 77 }
74 else if (res.statusCode != 200) { 78 else if (res.statusCode != 200) {
75 logger.warn('Modem handler not responding with HTTP status code 200.', { http_status_code: res.statusCode, req_id: reqId, handler_name: handlerName }); 79 logger.warn('Modem handler not responding with HTTP status code 200.', { http_status_code: res.statusCode, req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi });
76 } 80 }
77 else { 81 else {
78 logger.verbose('Message sent to handler', { req_id: reqId, handler_name: handlerName, response_body: body }); 82 logger.verbose('Message sent to handler', { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi, response_body: body });
79 } 83 }
80 }) 84 })
81 85
82 } 86 }
83 87
84 async function send(partner, msg) { 88 async function send(partner, msg) {
85 if (!partner) return; 89 if (!partner) return;
86 90
87 if (typeof msg !== 'string') { 91 if (typeof msg !== 'string') {
88 logger.warn('Message to send is not a string, ignoring message'); 92 logger.warn('Message to send is not a string, ignoring message');
89 return; 93 return;
90 } 94 }
91 95
92 msg = msg.trim(); 96 msg = msg.trim();
93 if (!msg) return; 97 if (!msg) return;
94 98
95 const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config); 99 const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config);
96 100
97 // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin }); 101 // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin });
98 let handlerName = await partnerLastSeen.get(destinationNumber) ; 102 const handlerIMSI = await partnerLastSeen.get(destinationNumber) ;
99 103
100 if (!handlerName) { 104 if (!handlerIMSI) {
101 logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber }); 105 logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber });
102 return; 106 return;
103 } 107 }
104 108
105 _send(destinationNumber, msg, handlerName); 109 _send(destinationNumber, msg, handlerIMSI);
106 } 110 }
107 111
108 exports.send = send; 112 exports.send = send;