Commit 6cd19a9c944a38c94a13aba9136c64eb7107379d

Authored by Adhidarma Hadiwinoto
1 parent 3f614b14ac
Exists in master

Typo

Showing 2 changed files with 4 additions and 1 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 routerModems = require('./router-modems'); 21 const routerModems = require('./router-modems');
22 22
23 if (config.handler_callback_server) { 23 if (config.handler_callback_server) {
24 logger.warn('Deprecated config.handler_callback_server. Please migrate it to config.apiserver!'); 24 logger.warn('Deprecated config.handler_callback_server. Please migrate it to config.apiserver!');
25 } 25 }
26 26
27 const app = express(); 27 const app = express();
28 messagingService.setTransport(transport); 28 messagingService.setTransport(transport);
29 29
30 function apikeyChecker(req, res, next) { 30 function apikeyChecker(req, res, next) {
31 res.locals.has_valid_apikey = req.params.apikey === (config.apiserver.apikey || config.handler_callback_server.apikey); 31 res.locals.has_valid_apikey = req.params.apikey === ((config.apiserver && config.apiserver.apikey ? config.apiserver.apikey : null) || config.handler_callback_server.apikey);
32 if (res.locals.has_valid_apikey) { 32 if (res.locals.has_valid_apikey) {
33 next(); 33 next();
34 } 34 }
35 else { 35 else {
36 res.end('APISERVER: Invalid apikey'); 36 res.end('APISERVER: Invalid apikey');
37 } 37 }
38 } 38 }
39 39
40 function onIncomingSms(req, res) { 40 function onIncomingSms(req, res) {
41 res.end('OK'); 41 res.end('OK');
42 42
43 if (!req.query.number) return; 43 if (!req.query.number) return;
44 const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); 44 const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || '');
45 45
46 partnerLastSeen.set(req.query.number, req.query.modem_imsi); 46 partnerLastSeen.set(req.query.number, req.query.modem_imsi);
47 47
48 history.push({ 48 history.push({
49 ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'), 49 ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'),
50 modem: { 50 modem: {
51 name: req.query.modem, 51 name: req.query.modem,
52 imsi: req.query.modem_imsi, 52 imsi: req.query.modem_imsi,
53 msisdn: req.query.modem_msisdn, 53 msisdn: req.query.modem_msisdn,
54 }, 54 },
55 direction: 'INCOMING', 55 direction: 'INCOMING',
56 partner: req.query.number, 56 partner: req.query.number,
57 message: req.query.msg, 57 message: req.query.msg,
58 }); 58 });
59 59
60 /* 60 /*
61 modems.set({ 61 modems.set({
62 name: req.query.modem, 62 name: req.query.modem,
63 device: req.query.modem_device, 63 device: req.query.modem_device,
64 imsi: req.query.modem_imsi, 64 imsi: req.query.modem_imsi,
65 msisdn: req.query.modem_msisdn, 65 msisdn: req.query.modem_msisdn,
66 networkId: req.query.modem.network_id, 66 networkId: req.query.modem.network_id,
67 networkName: req.query.modem_network_name, 67 networkName: req.query.modem_network_name,
68 signalStrength: req.query.modem_signal_strength, 68 signalStrength: req.query.modem_signal_strength,
69 uptime: req.query.uptime, 69 uptime: req.query.uptime,
70 reportIp: req.query.report_ip || req.ip, 70 reportIp: req.query.report_ip || req.ip,
71 reportPort: req.query.report_port, 71 reportPort: req.query.report_port,
72 reportApikey: req.query.report_apikey, 72 reportApikey: req.query.report_apikey,
73 reportPathSms: req.query.report_path_sms || '/sms', 73 reportPathSms: req.query.report_path_sms || '/sms',
74 }); 74 });
75 */ 75 */
76 76
77 logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); 77 logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg });
78 messagingService.onIncomingMessage({ 78 messagingService.onIncomingMessage({
79 me: req.query.modem, 79 me: req.query.modem,
80 partner: numberWithSuffix, 80 partner: numberWithSuffix,
81 partner_raw: req.query.number, 81 partner_raw: req.query.number,
82 msg: req.query.msg, 82 msg: req.query.msg,
83 origin_label: `IMSI_${req.query.modem_imsi || 'UNKNOWN'}`, 83 origin_label: `IMSI_${req.query.modem_imsi || 'UNKNOWN'}`,
84 origin_transport: 'SMS', 84 origin_transport: 'SMS',
85 origin_partner: req.query.number, 85 origin_partner: req.query.number,
86 do_not_forward_to_core: req.query.number.indexOf('+') !== 0, 86 do_not_forward_to_core: req.query.number.indexOf('+') !== 0,
87 }); 87 });
88 } 88 }
89 89
90 async function pageHistory(req, res) { 90 async function pageHistory(req, res) {
91 res.json(await history.dump()); 91 res.json(await history.dump());
92 } 92 }
93 93
94 app.use(function(req, res, next) { 94 app.use(function(req, res, next) {
95 if ( 95 if (
96 req && req.path && typeof req.path === 'string' 96 req && req.path && typeof req.path === 'string'
97 && ( 97 && (
98 req.path.search(/\/modems$/) >= 0 98 req.path.search(/\/modems$/) >= 0
99 || req.path.search(/\/modems\/set$/) >= 0 99 || req.path.search(/\/modems\/set$/) >= 0
100 ) 100 )
101 ) { 101 ) {
102 next(); 102 next();
103 return; 103 return;
104 } 104 }
105 105
106 logger.verbose('APISERVER: Incoming http request', { ip: req.ip, path: req.path, url: req.url }); 106 logger.verbose('APISERVER: Incoming http request', { ip: req.ip, path: req.path, url: req.url });
107 next(); 107 next();
108 }) 108 })
109 109
110 app.use('/apikey/:apikey', apikeyChecker); 110 app.use('/apikey/:apikey', apikeyChecker);
111 app.get('/apikey/:apikey/on-sms', onIncomingSms); 111 app.get('/apikey/:apikey/on-sms', onIncomingSms);
112 app.get('/apikey/:apikey/inbox', onIncomingSms); 112 app.get('/apikey/:apikey/inbox', onIncomingSms);
113 app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); 113 app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms);
114 app.get('/apikey/:apikey/history', pageHistory); 114 app.get('/apikey/:apikey/history', pageHistory);
115 app.use('/apikey/:apikey/modems', routerModems); 115 app.use('/apikey/:apikey/modems', routerModems);
116 116
117 const listenPort = (config && config.apiserver && config.apiserver.listen_port ? config.apiserver.listen_port : null) 117 const listenPort = (config && config.apiserver && config.apiserver.listen_port ? config.apiserver.listen_port : null)
118 || (config && config.handler_callback_server ? config.handler_callback_server.listen_port : null); 118 || (config && config.handler_callback_server ? config.handler_callback_server.listen_port : null);
119 119
120 if (listenPort) { 120 if (listenPort) {
121 app.listen(listenPort, () => { 121 app.listen(listenPort, () => {
122 logger.info('HTTP Handler Callback server listening on port ' + listenPort); 122 logger.info('HTTP Handler Callback server listening on port ' + listenPort);
123 }); 123 });
124 } else { 124 } else {
125 logger.warn('Undefined config.apiserver.listen_port for APISERVER. Not listening for command.'); 125 logger.warn('Undefined config.apiserver.listen_port for APISERVER. Not listening for command.');
126 } 126 }
127 127
1 "use strict"; 1 "use strict";
2 2
3 const MAX_SMS_LENGTH = 160; 3 const MAX_SMS_LENGTH = 160;
4 4
5 const url = require('url'); 5 const url = require('url');
6 const request = require('request'); 6 const request = require('request');
7 const uuidv4 = require('uuid/v4'); 7 const uuidv4 = require('uuid/v4');
8 const moment = require('moment'); 8 const moment = require('moment');
9 9
10 const config = require('komodo-sdk/config'); 10 const config = require('komodo-sdk/config');
11 const logger = require('komodo-sdk/logger'); 11 const logger = require('komodo-sdk/logger');
12 12
13 const messagingService = require('komodo-center-messaging-client-lib'); 13 const messagingService = require('komodo-center-messaging-client-lib');
14 14
15 const modemSelect = require('./modemSelect'); 15 const modemSelect = require('./modemSelect');
16 const modems = require('./modems2'); 16 const modems = require('./modems2');
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 prefixes = require('./prefixes');
19 20
20 function _send(destinationNumber, msg, handlerIMSI) { 21 function _send(destinationNumber, msg, handlerIMSI) {
21 22
22 if (msg.length > 160) { 23 if (msg.length > 160) {
23 logger.info('Splitting message'); 24 logger.info('Splitting message');
24 25
25 const newMsg = msg.slice(0, MAX_SMS_LENGTH); 26 const newMsg = msg.slice(0, MAX_SMS_LENGTH);
26 const remainingMsg = msg.slice(MAX_SMS_LENGTH); 27 const remainingMsg = msg.slice(MAX_SMS_LENGTH);
27 28
28 _send(destinationNumber, newMsg, handlerIMSI); 29 _send(destinationNumber, newMsg, handlerIMSI);
29 setTimeout(() => { 30 setTimeout(() => {
30 _send(destinationNumber, remainingMsg, handlerIMSI); 31 _send(destinationNumber, remainingMsg, handlerIMSI);
31 }, 1000); 32 }, 1000);
32 33
33 return; 34 return;
34 } 35 }
35 36
36 const modem = modems.get('imsi', handlerIMSI); 37 const modem = modems.get('imsi', handlerIMSI);
37 if (!modem) { 38 if (!modem) {
38 logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, modem_imsi: handlerIMSI }); 39 logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, modem_imsi: handlerIMSI });
39 return; 40 return;
40 } 41 }
41 42
42 if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) { 43 if (!modem.reportIp || !modem.reportPort || !modem.reportApikey) {
43 logger.warn('Invalid modem configuration', { modem }); 44 logger.warn('Invalid modem configuration', { modem });
44 return; 45 return;
45 } 46 }
46 47
47 const reqId = uuidv4(); 48 const reqId = uuidv4();
48 49
49 history.push({ 50 history.push({
50 ts: moment().format('YYYY-MM-DD HH:mm:ss'), 51 ts: moment().format('YYYY-MM-DD HH:mm:ss'),
51 modem: { 52 modem: {
52 name: modem.name, 53 name: modem.name,
53 imsi: modem.imsi, 54 imsi: modem.imsi,
54 msisdn: modem.msisdn, 55 msisdn: modem.msisdn,
55 }, 56 },
56 direction: 'OUTGOING', 57 direction: 'OUTGOING',
57 partner: destinationNumber, 58 partner: destinationNumber,
58 message: msg, 59 message: msg,
59 }); 60 });
60 61
61 logger.verbose('TRANSPORT: saving outgoing message'); 62 logger.verbose('TRANSPORT: saving outgoing message');
62 messagingService.onIncomingMessage({ 63 messagingService.onIncomingMessage({
63 me: modem.name, 64 me: modem.name,
64 partner: destinationNumber, 65 partner: destinationNumber,
65 partner_raw: `+${destinationNumber}`.replace(/^\++/, '+'), 66 partner_raw: `+${destinationNumber}`.replace(/^\++/, '+'),
66 msg: msg, 67 msg: msg,
67 origin_label: `IMSI_${modem.imsi || 'UNKNOWN'}`, 68 origin_label: `IMSI_${modem.imsi || 'UNKNOWN'}`,
68 origin_transport: 'SMS', 69 origin_transport: 'SMS',
69 origin_partner: destinationNumber, 70 origin_partner: destinationNumber,
70 do_not_forward_to_core: true, 71 do_not_forward_to_core: true,
71 is_outgoing: true, 72 is_outgoing: true,
72 }); 73 });
73 74
74 const requestOptions = { 75 const requestOptions = {
75 url: url.format({ 76 url: url.format({
76 protocol: 'http', 77 protocol: 'http',
77 hostname: modem.reportIp, 78 hostname: modem.reportIp,
78 port: modem.reportPort, 79 port: modem.reportPort,
79 pathname: modem.reportPathSms || '/sms', 80 pathname: modem.reportPathSms || '/sms',
80 }), 81 }),
81 qs: { 82 qs: {
82 msg: msg, 83 msg: msg,
83 number: destinationNumber, 84 number: destinationNumber,
84 reqid: reqId, 85 reqid: reqId,
85 apikey: modem.reportApikey, 86 apikey: modem.reportApikey,
86 } 87 }
87 } 88 }
88 89
89 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 }); 90 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 });
90 request(requestOptions, function(err, res, body) { 91 request(requestOptions, function(err, res, body) {
91 if (err) { 92 if (err) {
92 logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi }); 93 logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi });
93 94
94 } 95 }
95 else if (res.statusCode != 200) { 96 else if (res.statusCode != 200) {
96 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 }); 97 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 });
97 } 98 }
98 else { 99 else {
99 logger.verbose('Message sent to handler', { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi, response_body: body }); 100 logger.verbose('Message sent to handler', { req_id: reqId, modem_name: modem.name, modem_imsi: modem.imsi, response_body: body });
100 } 101 }
101 }) 102 })
102 103
103 } 104 }
104 105
105 async function send(partner, msg) { 106 async function send(partner, msg) {
106 if (!partner) return; 107 if (!partner) return;
107 108
108 if (typeof msg !== 'string') { 109 if (typeof msg !== 'string') {
109 logger.warn('Message to send is not a string, ignoring message'); 110 logger.warn('Message to send is not a string, ignoring message');
110 return; 111 return;
111 } 112 }
112 113
113 msg = msg.trim(); 114 msg = msg.trim();
114 if (!msg) return; 115 if (!msg) return;
115 116
116 const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config); 117 const destinationNumber = modemSelect.removeSuffixFromNumber(partner, config);
118 const prefixName = await prefixes(destinationNumber);
119 logger.verbose('Destination number prefix lookup', {partner: destinationNumber, prefix: prefixName});
117 120
118 // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin }); 121 // logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin });
119 const handlerIMSI = await partnerLastSeen.get(destinationNumber) ; 122 const handlerIMSI = await partnerLastSeen.get(destinationNumber) ;
120 123
121 if (!handlerIMSI) { 124 if (!handlerIMSI) {
122 logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber }); 125 logger.warn(`Unknown handler for sending message to partner`, { partner, destinationNumber });
123 return; 126 return;
124 } 127 }
125 128
126 _send(destinationNumber, msg, handlerIMSI); 129 _send(destinationNumber, msg, handlerIMSI);
127 } 130 }
128 131
129 exports.send = send; 132 exports.send = send;