Commit 8d90a3941f5d340bca2ef964ee8497b16e857cf1
1 parent
a332cb4bf5
Exists in
master
Add xid on messages-archives.insert
Showing 2 changed files with 9 additions and 8 deletions Inline Diff
lib/http-listener.js
1 | const MODULE_NAME = 'HTTP-LISTENER'; | 1 | const MODULE_NAME = 'HTTP-LISTENER'; |
2 | 2 | ||
3 | const express = require('express'); | 3 | const express = require('express'); |
4 | const ipfilter = require('express-ipfilter').IpFilter; | 4 | const ipfilter = require('express-ipfilter').IpFilter; |
5 | const removeAccents = require('remove-accents'); | 5 | const removeAccents = require('remove-accents'); |
6 | const uniqid = require('uniqid'); | 6 | const uniqid = require('uniqid'); |
7 | 7 | ||
8 | const config = require('komodo-sdk/config'); | 8 | const config = require('komodo-sdk/config'); |
9 | const logger = require('tektrans-logger'); | 9 | const logger = require('tektrans-logger'); |
10 | 10 | ||
11 | const commandHandler = require('./command-handler'); | 11 | const commandHandler = require('./command-handler'); |
12 | const messagesArchive = require('./messages-archive'); | 12 | const messagesArchive = require('./messages-archive'); |
13 | 13 | ||
14 | const app = express(); | 14 | const app = express(); |
15 | const port = (config && config.listener && config.listener.http | 15 | const port = (config && config.listener && config.listener.http |
16 | && config.listener.http.port && config.listener.http.port | 16 | && config.listener.http.port && config.listener.http.port |
17 | ) || 32979; | 17 | ) || 32979; |
18 | 18 | ||
19 | /** | 19 | /** |
20 | * Handler utama. | 20 | * Handler utama. |
21 | * | 21 | * |
22 | * @param {object} req - Express request object | 22 | * @param {object} req - Express request object |
23 | * @param {object} req.query - Express query string object | 23 | * @param {object} req.query - Express query string object |
24 | * @param {string} [req.query.partner] - Partner (pengirim atau penerima) | 24 | * @param {string} [req.query.partner] - Partner (pengirim atau penerima) |
25 | * @param {string} [req.query.from] - Pengirim, OBSOLETED: gunakan parameter partner | 25 | * @param {string} [req.query.from] - Pengirim, OBSOLETED: gunakan parameter partner |
26 | * @param {string} [req.query.from_raw] - Pengirim tanpa suffix (raw), OBSOLETED by partner_raw | 26 | * @param {string} [req.query.from_raw] - Pengirim tanpa suffix (raw), OBSOLETED by partner_raw |
27 | * @param {string} [req.query.to] - Tujuan, jika is_outgoing, OBSOLETED: gunakan parameter partner | 27 | * @param {string} [req.query.to] - Tujuan, jika is_outgoing, OBSOLETED: gunakan parameter partner |
28 | * @param {string} req.query.msg - Isi pesan | 28 | * @param {string} req.query.msg - Isi pesan |
29 | * @param {string} req.query.origin - Nama origin | 29 | * @param {string} req.query.origin - Nama origin |
30 | * @param {string} [req.query.origin_label] - Nama origin untuk ditulis di histori pesan | 30 | * @param {string} [req.query.origin_label] - Nama origin untuk ditulis di histori pesan |
31 | * @param {string} [req.query.do_not_forward_to_core] - Apakah teruskan pesan ke CORE | 31 | * @param {string} [req.query.do_not_forward_to_core] - Apakah teruskan pesan ke CORE |
32 | * @param {string} [req.query.is_outgoing] - Apakah pesan keluar | 32 | * @param {string} [req.query.is_outgoing] - Apakah pesan keluar |
33 | * @param {object} res - Express response object | 33 | * @param {object} res - Express response object |
34 | */ | 34 | */ |
35 | function mainHandler(req, res) { | 35 | function mainHandler(req, res) { |
36 | if (!req.body) req.body = {}; | 36 | if (!req.body) req.body = {}; |
37 | 37 | ||
38 | const { xid } = res.locals; | 38 | const { xid } = res.locals; |
39 | 39 | ||
40 | logger.verbose(`${MODULE_NAME} 72AFD326: Got a request`, { | 40 | logger.verbose(`${MODULE_NAME} 72AFD326: Got a request`, { |
41 | xid, | 41 | xid, |
42 | query: req.query, | 42 | query: req.query, |
43 | body: req.body, | 43 | body: req.body, |
44 | }); | 44 | }); |
45 | 45 | ||
46 | if ( | 46 | if ( |
47 | (!req.body.partner && !req.query.partner) | 47 | (!req.body.partner && !req.query.partner) |
48 | && ( | 48 | && ( |
49 | (!req.query.is_outgoing && !req.body.is_outgoing && !req.query.from && !req.body.from) | 49 | (!req.query.is_outgoing && !req.body.is_outgoing && !req.query.from && !req.body.from) |
50 | || ((req.query.is_outgoing || req.body.is_outgoing) && !req.query.to && !req.body.to) | 50 | || ((req.query.is_outgoing || req.body.is_outgoing) && !req.query.to && !req.body.to) |
51 | ) | 51 | ) |
52 | ) { | 52 | ) { |
53 | logger.warn(`${MODULE_NAME} D254B7B454DB: Undefined parameter partner or from or to`, { | 53 | logger.warn(`${MODULE_NAME} D254B7B454DB: Undefined parameter partner or from or to`, { |
54 | xid, | 54 | xid, |
55 | partner: req.body.partner || req.query.partner, | 55 | partner: req.body.partner || req.query.partner, |
56 | is_outgoing: req.body.is_outgoing || req.query.is_outgoing, | 56 | is_outgoing: req.body.is_outgoing || req.query.is_outgoing, |
57 | from: req.body.from || req.query.from, | 57 | from: req.body.from || req.query.from, |
58 | to: req.body.to || req.query.to, | 58 | to: req.body.to || req.query.to, |
59 | }); | 59 | }); |
60 | res.end('ERROR. Undefined parameter: partner or from or to'); | 60 | res.end('ERROR. Undefined parameter: partner or from or to'); |
61 | return; | 61 | return; |
62 | } | 62 | } |
63 | 63 | ||
64 | // message cleansing | 64 | // message cleansing |
65 | const msg = removeAccents(req.query.msg || req.body.msg || '') | 65 | const msg = removeAccents(req.query.msg || req.body.msg || '') |
66 | .replace(/[\u{0080}-\u{FFFF}]/gu, '') | 66 | .replace(/[\u{0080}-\u{FFFF}]/gu, '') |
67 | .trim(); | 67 | .trim(); |
68 | 68 | ||
69 | if (!msg) { | 69 | if (!msg) { |
70 | logger.warn(`${MODULE_NAME} #92996A497D12: Undefined parameter msg`, { | 70 | logger.warn(`${MODULE_NAME} #92996A497D12: Undefined parameter msg`, { |
71 | xid, | 71 | xid, |
72 | }); | 72 | }); |
73 | 73 | ||
74 | if (config.do_not_reply_warning_on_empty_message) { | 74 | if (config.do_not_reply_warning_on_empty_message) { |
75 | res.end('OK'); | 75 | res.end('OK'); |
76 | } else { | 76 | } else { |
77 | res.end(`ERROR. Undefined parameter: msg. XID: ${xid}`); | 77 | res.end(`ERROR. Undefined parameter: msg. XID: ${xid}`); |
78 | } | 78 | } |
79 | 79 | ||
80 | return; | 80 | return; |
81 | } | 81 | } |
82 | 82 | ||
83 | logger.verbose( | 83 | logger.verbose( |
84 | `${MODULE_NAME} 1E9D2388: Saving message history`, | 84 | `${MODULE_NAME} 1E9D2388: Saving message history`, |
85 | { | 85 | { |
86 | xid, | 86 | xid, |
87 | direction: req.body.is_outgoing || req.query.is_outgoing ? 'outgoing' : 'incoming', | 87 | direction: req.body.is_outgoing || req.query.is_outgoing ? 'outgoing' : 'incoming', |
88 | transport: req.body.origin_transport || req.query.origin_transport, | 88 | transport: req.body.origin_transport || req.query.origin_transport, |
89 | partner: req.body.partner || req.query.partner || req.body.from || req.query.from | 89 | partner: req.body.partner || req.query.partner || req.body.from || req.query.from |
90 | || req.body.to || req.query.to, | 90 | || req.body.to || req.query.to, |
91 | msg, | 91 | msg, |
92 | }, | 92 | }, |
93 | ); | 93 | ); |
94 | 94 | ||
95 | messagesArchive.insert( | 95 | messagesArchive.insert( |
96 | xid, | ||
96 | { | 97 | { |
97 | origin_label: req.body.origin_label || req.query.origin_label | 98 | origin_label: req.body.origin_label || req.query.origin_label |
98 | || req.body.origin || req.query.origin, | 99 | || req.body.origin || req.query.origin, |
99 | origin_transport: req.body.origin_transport || req.query.origin_transport, | 100 | origin_transport: req.body.origin_transport || req.query.origin_transport, |
100 | partner: req.body.partner_raw || req.query.partner_raw | 101 | partner: req.body.partner_raw || req.query.partner_raw |
101 | || req.body.from_raw || req.query.from_raw | 102 | || req.body.from_raw || req.query.from_raw |
102 | || req.body.from || req.query.from | 103 | || req.body.from || req.query.from |
103 | || req.body.to || req.query.to || req.body.partner || req.query.partner, | 104 | || req.body.to || req.query.to || req.body.partner || req.query.partner, |
104 | msg, | 105 | msg, |
105 | }, | 106 | }, |
106 | (req.body.is_outgoing || req.query.is_outgoing) ? messagesArchive.DIRECTION_OUTGOING | 107 | (req.body.is_outgoing || req.query.is_outgoing) ? messagesArchive.DIRECTION_OUTGOING |
107 | : messagesArchive.DIRECTION_INCOMING, | 108 | : messagesArchive.DIRECTION_INCOMING, |
108 | ); | 109 | ); |
109 | 110 | ||
110 | if ( | 111 | if ( |
111 | req.body.do_not_forward_to_core || req.query.do_not_forward_to_core | 112 | req.body.do_not_forward_to_core || req.query.do_not_forward_to_core |
112 | || req.body.is_outgoing || req.query.is_outgoing | 113 | || req.body.is_outgoing || req.query.is_outgoing |
113 | ) { | 114 | ) { |
114 | logger.verbose('Ignoring message', { | 115 | logger.verbose('Ignoring message', { |
115 | xid, | 116 | xid, |
116 | from: req.body.from || req.query.from, | 117 | from: req.body.from || req.query.from, |
117 | msg, | 118 | msg, |
118 | do_not_forward_to_core: req.body.do_not_forward_to_core | 119 | do_not_forward_to_core: req.body.do_not_forward_to_core |
119 | || req.query.do_not_forward_to_core, | 120 | || req.query.do_not_forward_to_core, |
120 | }); | 121 | }); |
121 | 122 | ||
122 | res.end('OK'); | 123 | res.end('OK'); |
123 | return; | 124 | return; |
124 | } | 125 | } |
125 | 126 | ||
126 | if (!req.query.report_port && !req.body.report_port) { | 127 | if (!req.query.report_port && !req.body.report_port) { |
127 | res.end('ERROR. Undefined parameter: report_port'); | 128 | res.end('ERROR. Undefined parameter: report_port'); |
128 | return; | 129 | return; |
129 | } | 130 | } |
130 | 131 | ||
131 | const params = { | 132 | const params = { |
132 | origin: req.body.origin || req.query.origin || 'MESSAGING', | 133 | origin: req.body.origin || req.query.origin || 'MESSAGING', |
133 | origin_transport: req.body.origin_transport || req.query.origin_transport, | 134 | origin_transport: req.body.origin_transport || req.query.origin_transport, |
134 | report_ip: req.body.report_ip || req.query.report_ip || req.ip, | 135 | report_ip: req.body.report_ip || req.query.report_ip || req.ip, |
135 | report_port: req.body.report_port || req.query.report_port, | 136 | report_port: req.body.report_port || req.query.report_port, |
136 | from: req.body.partner || req.query.partner || req.body.from || req.query.from, | 137 | from: req.body.partner || req.query.partner || req.body.from || req.query.from, |
137 | msg, | 138 | msg, |
138 | }; | 139 | }; |
139 | 140 | ||
140 | commandHandler(msg, params, (err, coreResponseObject, responseParams) => { | 141 | commandHandler(msg, params, (err, coreResponseObject, responseParams) => { |
141 | if (err) { | 142 | if (err) { |
142 | res.end(`ERROR. ${err.message || err}`); | 143 | res.end(`ERROR. ${err.message || err}`); |
143 | } else if (coreResponseObject) { | 144 | } else if (coreResponseObject) { |
144 | res.json(coreResponseObject); | 145 | res.json(coreResponseObject); |
145 | } else { | 146 | } else { |
146 | res.end(responseParams.body); | 147 | res.end(responseParams.body); |
147 | } | 148 | } |
148 | }); | 149 | }); |
149 | } | 150 | } |
150 | 151 | ||
151 | if (config.ip_whitelist && config.ip_whitelist.length) { | 152 | if (config.ip_whitelist && config.ip_whitelist.length) { |
152 | app.use(ipfilter(config.ip_whitelist, { mode: 'allow', log: false })); | 153 | app.use(ipfilter(config.ip_whitelist, { mode: 'allow', log: false })); |
153 | } | 154 | } |
154 | 155 | ||
155 | app.use((req, res, next) => { | 156 | app.use((req, res, next) => { |
156 | const xid = uniqid(); | 157 | const xid = uniqid(); |
157 | res.locals.xid = xid; | 158 | res.locals.xid = xid; |
158 | 159 | ||
159 | logger.verbose(`${MODULE_NAME} 83DF8231: Got a request`, { | 160 | logger.verbose(`${MODULE_NAME} 83DF8231: Got a request`, { |
160 | xid, | 161 | xid, |
161 | ip: req.ip, | 162 | ip: req.ip, |
162 | method: req.method, | 163 | method: req.method, |
163 | requestContentType: req.get('content-type'), | 164 | requestContentType: req.get('content-type'), |
164 | url: req.url, | 165 | url: req.url, |
165 | }); | 166 | }); |
166 | 167 | ||
167 | next(); | 168 | next(); |
168 | }); | 169 | }); |
169 | 170 | ||
170 | app.get('/', mainHandler); | 171 | app.get('/', mainHandler); |
171 | app.post( | 172 | app.post( |
172 | '/', | 173 | '/', |
173 | express.urlencoded({ extended: true }), | 174 | express.urlencoded({ extended: true }), |
174 | express.json(), | 175 | express.json(), |
175 | mainHandler, | 176 | mainHandler, |
176 | ); | 177 | ); |
177 | 178 | ||
178 | app.listen(port, () => { | 179 | app.listen(port, () => { |
179 | logger.info('HTTP-LISTENER: started', { | 180 | logger.info('HTTP-LISTENER: started', { |
180 | port, app_env: app.get('env'), | 181 | port, app_env: app.get('env'), |
181 | }); | 182 | }); |
182 | }); | 183 | }); |
183 | 184 |
lib/messages-archive.js
1 | const redis = require('redis'); | 1 | const redis = require('redis'); |
2 | 2 | ||
3 | const config = require('komodo-sdk/config'); | 3 | const config = require('komodo-sdk/config'); |
4 | const logger = require('tektrans-logger'); | 4 | const logger = require('tektrans-logger'); |
5 | const db = require('./db-mysql'); | 5 | const db = require('./db-mysql'); |
6 | 6 | ||
7 | const DIRECTION_INCOMING = 0; | 7 | const DIRECTION_INCOMING = 0; |
8 | const DIRECTION_OUTGOING = 1; | 8 | const DIRECTION_OUTGOING = 1; |
9 | 9 | ||
10 | let redisClient; | 10 | let redisClient; |
11 | 11 | ||
12 | if (!config.redis) { | 12 | if (!config.redis) { |
13 | logger.warn('Undefined config.redis, messages counter will not work! #05A778E21D7E'); | 13 | logger.warn('Undefined config.redis, messages counter will not work! #05A778E21D7E'); |
14 | } else { | 14 | } else { |
15 | redisClient = redis.createClient(config.redis); | 15 | redisClient = redis.createClient(config.redis); |
16 | } | 16 | } |
17 | 17 | ||
18 | if (!redisClient) { | 18 | if (!redisClient) { |
19 | logger.warn('Undefined redisClient, messages counter will not work! #1D3EC165E8D9'); | 19 | logger.warn('Undefined redisClient, messages counter will not work! #1D3EC165E8D9'); |
20 | } | 20 | } |
21 | 21 | ||
22 | function composeRedisCounterKeyword(origin, direction) { | 22 | function composeRedisCounterKeyword(origin, direction) { |
23 | const directionLabel = direction == DIRECTION_OUTGOING ? 'OUT' : 'IN'; | 23 | const directionLabel = Number(direction) === DIRECTION_OUTGOING ? 'OUT' : 'IN'; |
24 | return `CALMA_MESSAGE_COUNTER_${origin}_${directionLabel}`; | 24 | return `CALMA_MESSAGE_COUNTER_${origin}_${directionLabel}`; |
25 | } | 25 | } |
26 | 26 | ||
27 | function incrementCounter(origin, direction) { | 27 | function incrementCounter(origin, direction) { |
28 | if (!redisClient) { | 28 | if (!redisClient) { |
29 | logger.warn('Undefined redisClient, not incrementing messages counter! #FF8E765E12E2'); | 29 | logger.warn('Undefined redisClient, not incrementing messages counter! #FF8E765E12E2'); |
30 | } else { | 30 | } else { |
31 | redisClient.INCR(composeRedisCounterKeyword(origin, direction), () => {}); | 31 | redisClient.INCR(composeRedisCounterKeyword(origin, direction), () => {}); |
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Menyimpan pesan ke dalam archive histori pesan di database | 36 | * Menyimpan pesan ke dalam archive histori pesan di database |
37 | * | 37 | * |
38 | * @param {object} params - objek pesan yang akan disimpan | 38 | * @param {object} params - objek pesan yang akan disimpan |
39 | * @param {string} [params.origin_label] - label origin | 39 | * @param {string} [params.origin_label] - label origin |
40 | * @param {string} [params.origin=UNKNOWN] - digunakan sebagai label origin jika tdk ditentukan | 40 | * @param {string} [params.origin=UNKNOWN] - digunakan sebagai label origin jika tdk ditentukan |
41 | * @param {string} [params.origin_transport=UNKNOWN] - transport, misal SMS, TELEGRAM | 41 | * @param {string} [params.origin_transport=UNKNOWN] - transport, misal SMS, TELEGRAM |
42 | * @param {string} params.partner - pengirim / penerima | 42 | * @param {string} params.partner - pengirim / penerima |
43 | * @param {string} [params.msg] - isi pesan | 43 | * @param {string} [params.msg] - isi pesan |
44 | * @param {string} [params.message] - isi pesan, jika params.msg tidak terdefinisi | 44 | * @param {string} [params.message] - isi pesan, jika params.msg tidak terdefinisi |
45 | * @param {number} direction - 0: incoming, 1: outgoing | 45 | * @param {number} direction - 0: incoming, 1: outgoing |
46 | */ | 46 | */ |
47 | function insert(params, direction) { | 47 | function insert(xid, params, direction) { |
48 | incrementCounter( | 48 | incrementCounter( |
49 | params.origin_label || params.origin, | 49 | params.origin_label || params.origin, |
50 | direction | 50 | direction, |
51 | ); | 51 | ); |
52 | 52 | ||
53 | if (!db.pool) { | 53 | if (!db.pool) { |
54 | logger.warn('MESSAGE-ARCHIVE: DB POOL is not ready to insert message history'); | 54 | logger.warn('MESSAGE-ARCHIVE: DB POOL is not ready to insert message history', { xid }); |
55 | return; | 55 | return; |
56 | } | 56 | } |
57 | 57 | ||
58 | const query = `INSERT INTO messages SET ?`; | 58 | const query = 'INSERT INTO messages SET ?'; |
59 | const values = [{ | 59 | const values = [{ |
60 | origin_label: (params.origin_label || params.origin || 'UNKNOWN').trim(), | 60 | origin_label: (params.origin_label || params.origin || 'UNKNOWN').trim(), |
61 | origin_transport: (params.origin_transport || 'UNKNOWN').trim(), | 61 | origin_transport: (params.origin_transport || 'UNKNOWN').trim(), |
62 | direction, | 62 | direction, |
63 | partner: params.partner.trim(), | 63 | partner: params.partner.trim(), |
64 | message: (params.msg || params.message).trim(), | 64 | message: (params.msg || params.message).trim(), |
65 | }]; | 65 | }]; |
66 | 66 | ||
67 | db.pool.query(query, values, async (err) => { | 67 | db.pool.query(query, values, async (err) => { |
68 | if (err) { | 68 | if (err) { |
69 | const fullQuery = await db.format(query, values); | 69 | const fullQuery = await db.format(query, values); |
70 | logger.warn(`MESSAGES-ARCHIVE: DB ERROR on inserting message. ${err.toString()}`, { query: fullQuery }); | 70 | logger.warn(`MESSAGES-ARCHIVE: DB ERROR on inserting message. ${err.toString()}`, { xid, query: fullQuery }); |
71 | } | 71 | } |
72 | }); | 72 | }); |
73 | } | 73 | } |
74 | 74 | ||
75 | exports.insert = insert; | 75 | exports.insert = insert; |
76 | exports.DIRECTION_INCOMING = DIRECTION_INCOMING; | 76 | exports.DIRECTION_INCOMING = DIRECTION_INCOMING; |
77 | exports.DIRECTION_OUTGOING = DIRECTION_OUTGOING; | ||
77 | exports.DIRECTION_OUTGOING = DIRECTION_OUTGOING; |