Commit d23d98061b4e86274110f2847fa0fa789cd3d25f
1 parent
3f3d02d281
Exists in
master
router-modems
Showing 3 changed files with 39 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'); | ||
22 | |||
21 | const app = express(); | 23 | const app = express(); |
22 | messagingService.setTransport(transport); | 24 | messagingService.setTransport(transport); |
23 | 25 | ||
24 | function apikeyChecker(req, res, next) { | 26 | function apikeyChecker(req, res, next) { |
25 | res.locals.has_valid_apikey = req.params.apikey === config.handler_callback_server.apikey; | 27 | res.locals.has_valid_apikey = req.params.apikey === config.handler_callback_server.apikey; |
26 | if (res.locals.has_valid_apikey) { | 28 | if (res.locals.has_valid_apikey) { |
27 | next(); | 29 | next(); |
28 | } | 30 | } |
29 | else { | 31 | else { |
30 | res.end('APISERVER: Invalid apikey'); | 32 | res.end('APISERVER: Invalid apikey'); |
31 | } | 33 | } |
32 | } | 34 | } |
33 | 35 | ||
34 | function onIncomingSms(req, res) { | 36 | function onIncomingSms(req, res) { |
35 | res.end('OK'); | 37 | res.end('OK'); |
36 | 38 | ||
37 | if (!req.query.number) return; | 39 | if (!req.query.number) return; |
38 | if (req.query.number.indexOf('+') !== 0) return; | 40 | if (req.query.number.indexOf('+') !== 0) return; |
39 | 41 | ||
40 | const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); | 42 | const numberWithSuffix = req.query.number.replace(/^\+/, '') + (config.number_suffix || ''); |
41 | 43 | ||
42 | partnerLastSeen.set(req.query.number, req.query.modem_imsi); | 44 | partnerLastSeen.set(req.query.number, req.query.modem_imsi); |
43 | 45 | ||
44 | history.push({ | 46 | history.push({ |
45 | ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'), | 47 | ts: req.query.ts || moment().format('YYYY-MM-DD HH:mm:ss'), |
46 | modem: { | 48 | modem: { |
47 | name: req.query.modem, | 49 | name: req.query.modem, |
48 | imsi: req.query.modem_imsi, | 50 | imsi: req.query.modem_imsi, |
49 | msisdn: req.query.modem_msisdn, | 51 | msisdn: req.query.modem_msisdn, |
50 | }, | 52 | }, |
51 | direction: 'INCOMING', | 53 | direction: 'INCOMING', |
52 | partner: req.query.number, | 54 | partner: req.query.number, |
53 | message: req.query.msg, | 55 | message: req.query.msg, |
54 | }); | 56 | }); |
55 | 57 | ||
56 | modems.set({ | 58 | modems.set({ |
57 | name: req.query.modem, | 59 | name: req.query.modem, |
58 | imsi: req.query.modem_imsi, | 60 | imsi: req.query.modem_imsi, |
59 | msisdn: req.query.modem_msisdn, | 61 | msisdn: req.query.modem_msisdn, |
60 | device: req.query.modem_device, | 62 | device: req.query.modem_device, |
61 | uptime: req.query.uptime, | 63 | uptime: req.query.uptime, |
62 | reportIp: req.query.report_ip || req.ip, | 64 | reportIp: req.query.report_ip || req.ip, |
63 | reportPort: req.query.report_port, | 65 | reportPort: req.query.report_port, |
64 | reportApikey: req.query.report_apikey, | 66 | reportApikey: req.query.report_apikey, |
65 | reportPathSms: req.query.report_path_sms || '/sms', | 67 | reportPathSms: req.query.report_path_sms || '/sms', |
66 | }); | 68 | }); |
67 | 69 | ||
68 | logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); | 70 | logger.info('APISERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg }); |
69 | messagingService.onIncomingMessage({ | 71 | messagingService.onIncomingMessage({ |
70 | me: req.query.modem, | 72 | me: req.query.modem, |
71 | partner: numberWithSuffix, | 73 | partner: numberWithSuffix, |
72 | msg: req.query.msg | 74 | msg: req.query.msg |
73 | }) | 75 | }) |
74 | } | 76 | } |
75 | 77 | ||
76 | async function pageHistory(req, res) { | 78 | async function pageHistory(req, res) { |
77 | res.json(await history.dump()); | 79 | res.json(await history.dump()); |
78 | } | 80 | } |
79 | 81 | ||
80 | app.use(function(req, res, next) { | 82 | app.use(function(req, res, next) { |
81 | logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url }); | 83 | logger.verbose('APISERVER: Incoming http request', { ip: req.ip, url: req.url }); |
82 | next(); | 84 | next(); |
83 | }) | 85 | }) |
84 | 86 | ||
85 | app.use('/apikey/:apikey', apikeyChecker); | 87 | app.use('/apikey/:apikey', apikeyChecker); |
86 | app.get('/apikey/:apikey/on-sms', onIncomingSms); | 88 | app.get('/apikey/:apikey/on-sms', onIncomingSms); |
87 | app.get('/apikey/:apikey/inbox', onIncomingSms); | 89 | app.get('/apikey/:apikey/inbox', onIncomingSms); |
88 | app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); | 90 | app.get('/apikey/:apikey/on-sms/inbox', onIncomingSms); |
89 | app.get('/apikey/:apikey/history', pageHistory); | 91 | app.get('/apikey/:apikey/history', pageHistory); |
92 | app.use('/modems', routerModems); | ||
90 | 93 | ||
91 | const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null; | 94 | const listenPort = config && config.handler_callback_server ? config.handler_callback_server.listen_port : null; |
92 | listenPort && app.listen(listenPort, () => { | 95 | listenPort && app.listen(listenPort, () => { |
93 | logger.info('HTTP Handler Callback server listening on port ' + listenPort); | 96 | logger.info('HTTP Handler Callback server listening on port ' + listenPort); |
94 | }) | 97 | }) |
lib/apiserver/router-modems.js
File was created | 1 | 'use strict'; | |
2 | |||
3 | const express = require('express'); | ||
4 | const modems = require('../modems2'); | ||
5 | |||
6 | const router = express.Router(); | ||
7 | module.exports = router; | ||
8 | |||
9 | function pageIndex(req, res) { | ||
10 | res.json(modems.dump()); | ||
11 | } | ||
12 | |||
13 | function pageSet(req, res) { | ||
14 | res.end('OK'); | ||
15 | |||
16 | modems.set({ | ||
17 | name: req.query.modem, | ||
18 | imsi: req.query.modem_imsi, | ||
19 | msisdn: req.query.modem_msisdn, | ||
20 | device: req.query.modem_device, | ||
21 | uptime: req.query.uptime, | ||
22 | reportIp: req.query.report_ip || req.ip, | ||
23 | reportPort: req.query.report_port, | ||
24 | reportApikey: req.query.report_apikey, | ||
25 | reportPathSms: req.query.report_path_sms || '/sms', | ||
26 | }); | ||
27 | } | ||
28 | |||
29 | router.get('/', pageIndex); | ||
30 | router.get('/set', pageSet); |
lib/modems2.js
1 | 'use strict'; | 1 | 'use strict'; |
2 | 2 | ||
3 | const modemList = { | 3 | const modemList = { |
4 | by_name: {}, | 4 | by_name: {}, |
5 | by_imsi: {}, | 5 | by_imsi: {}, |
6 | by_msisdn: {}, | 6 | by_msisdn: {}, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | /** | 9 | /** |
10 | * Objek data sebuah modem. | 10 | * Objek data sebuah modem. |
11 | * | 11 | * |
12 | * @typedef {Object} ModemData | 12 | * @typedef {Object} ModemData |
13 | * @property {string} name - nama modem | 13 | * @property {string} name - nama modem |
14 | * @property {string} imsi - IMSI modem | 14 | * @property {string} imsi - IMSI modem |
15 | * @property {string} msisdn - MSISDN modem | 15 | * @property {string} msisdn - MSISDN modem |
16 | * @property {number} uptime - modem uptime in seconds | 16 | * @property {number} uptime - modem uptime in seconds |
17 | * @property {string} device - modem device path | 17 | * @property {string} device - modem device path |
18 | * @property {string} reportIp - IP modem | 18 | * @property {string} reportIp - IP modem |
19 | * @property {number} reportPort - TCP port modem | 19 | * @property {number} reportPort - TCP port modem |
20 | * @property {string} reportApikey - APIKEY modem | 20 | * @property {string} reportApikey - APIKEY modem |
21 | * @property {string} reportPathSms - url path untuk pengiriman SMS | 21 | * @property {string} reportPathSms - url path untuk pengiriman SMS |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Update data sebuah modem berdasarkan nama modem. | 25 | * Update data sebuah modem berdasarkan nama modem. |
26 | * | 26 | * |
27 | * @param {ModemData} val - objek data modem | 27 | * @param {ModemData} val - objek data modem |
28 | */ | 28 | */ |
29 | function touchByName(val) { | 29 | function touchByName(val) { |
30 | if (!val || !val.name) return; | 30 | if (!val || !val.name) return; |
31 | if (typeof val.name !== 'string') return; | 31 | if (typeof val.name !== 'string') return; |
32 | if (!val.name.trim()) return; | 32 | if (!val.name.trim()) return; |
33 | 33 | ||
34 | modemList.by_name[val.name] = val; | 34 | modemList.by_name[val.name] = val; |
35 | } | 35 | } |
36 | /** | 36 | /** |
37 | * Update data sebuah modem berdasarkan IMSI. | 37 | * Update data sebuah modem berdasarkan IMSI. |
38 | * | 38 | * |
39 | * @param {ModemData} val - objek data modem | 39 | * @param {ModemData} val - objek data modem |
40 | */ | 40 | */ |
41 | function touchByIMSI(val) { | 41 | function touchByIMSI(val) { |
42 | if (!val || !val.imsi) return; | 42 | if (!val || !val.imsi) return; |
43 | if (typeof val.imsi !== 'string') return; | 43 | if (typeof val.imsi !== 'string') return; |
44 | if (!val.imsi.trim()) return; | 44 | if (!val.imsi.trim()) return; |
45 | 45 | ||
46 | modemList.by_imsi[val.imsi] = val; | 46 | modemList.by_imsi[val.imsi] = val; |
47 | } | 47 | } |
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Update data sebuah modem berdasarkan MSISDN. | 50 | * Update data sebuah modem berdasarkan MSISDN. |
51 | * | 51 | * |
52 | * @param {ModemData} val - objek data modem | 52 | * @param {ModemData} val - objek data modem |
53 | */ | 53 | */ |
54 | function touchByMSISDN(val) { | 54 | function touchByMSISDN(val) { |
55 | if (!val || !val.msisdn) return; | 55 | if (!val || !val.msisdn) return; |
56 | if (typeof val.msisdn !== 'string') return; | 56 | if (typeof val.msisdn !== 'string') return; |
57 | if (!val.msisdn.trim()) return; | 57 | if (!val.msisdn.trim()) return; |
58 | 58 | ||
59 | modemList.by_msisdn[val.msisdn] = val; | 59 | modemList.by_msisdn[val.msisdn] = val; |
60 | } | 60 | } |
61 | 61 | ||
62 | /** | 62 | /** |
63 | * Update data sebuah modem. | 63 | * Update data sebuah modem. |
64 | * | 64 | * |
65 | * @param {ModemData} val - objek data modem | 65 | * @param {ModemData} val - objek data modem |
66 | * @see ModemData | 66 | * @see ModemData |
67 | */ | 67 | */ |
68 | function touch(val) { | 68 | function touch(val) { |
69 | if (!val || typeof val !== 'object') return; | 69 | if (!val || typeof val !== 'object') return; |
70 | 70 | ||
71 | val._ts = new Date(); | 71 | val._ts = new Date(); |
72 | 72 | ||
73 | if (!val.reportIp) { | 73 | if (!val.reportIp) { |
74 | val.reportIp = '127.0.0.1'; | 74 | val.reportIp = '127.0.0.1'; |
75 | } | 75 | } |
76 | 76 | ||
77 | touchByName(val); | 77 | touchByName(val); |
78 | touchByIMSI(val); | 78 | touchByIMSI(val); |
79 | touchByMSISDN(val); | 79 | touchByMSISDN(val); |
80 | } | 80 | } |
81 | /** | 81 | /** |
82 | * Ambil data sebuah modem. | 82 | * Ambil data sebuah modem. |
83 | * | 83 | * |
84 | * @param {string} selector - selector pencarian, valid jika bernilai salah satu dari: name, imsi, msisdn | 84 | * @param {string} selector - selector pencarian, valid jika bernilai salah satu dari: name, imsi, msisdn |
85 | * @param {string} keyword - kata kunci modem yang ingin diambil | 85 | * @param {string} keyword - kata kunci modem yang ingin diambil |
86 | * @returns {ModemData} data modem terkait | 86 | * @returns {ModemData} data modem terkait |
87 | */ | 87 | */ |
88 | function get(selector, keyword) { | 88 | function get(selector, keyword) { |
89 | if (!selector || !keyword) return null; | 89 | if (!selector || !keyword) return null; |
90 | 90 | ||
91 | return modemList[`by_${selector}`] ? modemList[`by_${selector}`][keyword] : null; | 91 | return modemList[`by_${selector}`] ? modemList[`by_${selector}`][keyword] : null; |
92 | } | 92 | } |
93 | 93 | ||
94 | function dump() { | ||
95 | return modemList; | ||
96 | } | ||
97 | |||
94 | exports.touch = touch; | 98 | exports.touch = touch; |
95 | exports.set = touch; | 99 | exports.set = touch; |
96 | exports.get = get; | ||
100 | exports.get = get; |