Commit 00208dea14cae319fd0851c773b947d4f86e8ae4

Authored by Adhidarma Hadiwinoto
1 parent 4c826b27e1
Exists in master

messageExtractor buat extract price dan endingBalance

Showing 4 changed files with 150 additions and 4 deletions Side-by-side Diff

lib/message-extractor.js
... ... @@ -0,0 +1,50 @@
  1 +/* eslint-disable no-console */
  2 +const MODULE_NAME = 'MESSAGE-PARSER.FINDER';
  3 +
  4 +/**
  5 + * Mencari nilai berdasarkan array of pattern
  6 + * @date 2021-07-05
  7 + * @param {Array} rules
  8 + * @param {string} originalMessage
  9 + * @param {any} isDebug
  10 + * @returns {string} string yang sesuai pattern, null jika tidak ditemukan
  11 + */
  12 +module.exports = (rules, originalMessage, isDebug) => {
  13 + if (!Array.isArray(rules)) return null;
  14 + if (typeof originalMessage !== 'string') return null;
  15 +
  16 + const msg = originalMessage.trim();
  17 +
  18 + if (!rules || !msg) return null;
  19 +
  20 + const ruleCount = rules.length;
  21 + for (let i = 0; i < ruleCount; i += 1) {
  22 + const rule = rules[i];
  23 +
  24 + // eslint-disable-next-line no-continue
  25 + if (rule.disable || rule.disabled) continue;
  26 +
  27 + const re = new RegExp(rule.pattern, rule.flags || '');
  28 +
  29 + const matches = msg.match(re);
  30 + let result = matches && matches[rule.idx];
  31 +
  32 + if (result && rule.postprocessing && typeof rule.postprocessing === 'function') {
  33 + result = rule.postprocessing(result);
  34 + }
  35 +
  36 + if (result) {
  37 + if (isDebug) {
  38 + console.log(`${MODULE_NAME} 9FAF9286: Found matches`, { isDebug, result, rule });
  39 + }
  40 +
  41 + return result;
  42 + }
  43 + }
  44 +
  45 + if (isDebug) {
  46 + console.log(`${MODULE_NAME} 0240860D: Matches not found`, { isDebug });
  47 + }
  48 +
  49 + return null;
  50 +};
... ... @@ -8,6 +8,8 @@ const parseXml = require(&#39;./parse-xml&#39;);
8 8  
9 9 const report = require('./report');
10 10 const translateRc = require('./translate-rc');
  11 +const messageExtractor = require('./message-extractor');
  12 +const patternRules = require('./pattern-rules');
11 13  
12 14 module.exports = (xid, trxIdFromCaller, xml, isCallback) => {
13 15 logger.verbose(`${MODULE_NAME} 58547863: Processing XML message`, { xid, isCallback });
... ... @@ -72,9 +74,8 @@ module.exports = (xid, trxIdFromCaller, xml, isCallback) =&gt; {
72 74 const responseCodeField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.responseCode) || 'RESPONSECODE';
73 75 const responseCodeFromResponse = params[responseCodeField];
74 76  
75   - // eslint-disable-next-line max-len
76   - // const messageField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.message) || 'MESSAGE';
77   - // const messageFromResponse = params[messageField];
  77 + const messageField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.message) || 'MESSAGE';
  78 + const messageFromResponse = params[messageField];
78 79  
79 80 const snField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.sn) || 'SN';
80 81 const snFromResponse = params[snField];
... ... @@ -87,12 +88,22 @@ module.exports = (xid, trxIdFromCaller, xml, isCallback) =&gt; {
87 88  
88 89 const rc = translateRc(xid, responseCodeFromResponse) || '68';
89 90  
90   - const sn = (rc === '00' && snFromResponse) || null;
  91 + const sn = (
  92 + rc === '00' && (
  93 + snFromResponse
  94 + || messageExtractor(patternRules.sn, messageFromResponse)
  95 + )
  96 + ) || null;
  97 +
  98 + const amount = Number(messageExtractor(patternRules.price, messageFromResponse) || '') || null;
  99 + const balance = Number(messageExtractor(patternRules.balance, messageFromResponse) || '') || null;
91 100  
92 101 report(xid, {
93 102 trx_id: trxId.toString(),
94 103 rc,
95 104 sn,
  105 + amount,
  106 + balance,
96 107 message: {
97 108 xid,
98 109 responseType: isCallback ? 'CALLBACK' : 'DIRECT-RESPONSE',
lib/pattern-rules.js
... ... @@ -0,0 +1,28 @@
  1 +/**
  2 + * Rule pattern to be used by message extractor
  3 + */
  4 +module.exports = {
  5 + sn: [
  6 + {
  7 + pattern: '(?:^|,|\\.|;|\\s)SN\\s*[=: ]\\s*(.+?)(?:;|$)',
  8 + idx: 1,
  9 + disable: false,
  10 + },
  11 + ],
  12 + price: [
  13 + {
  14 + pattern: '(?:,|\\.|;|\\s)(?:HRG|HARGA)\\s*[=: ]\\s*(?:RP)*\\s*(([0-9]|\\.||,)+)',
  15 + idx: 1,
  16 + disable: false,
  17 + postprocessing: (val) => (val || '').replace(/[,.]/g, ''),
  18 + },
  19 + ],
  20 + balance: [
  21 + {
  22 + pattern: '(?:,|\\.|;|\\s)SAL(?:DO)*\\s*[=: ]\\s*(?:RP)*\\s*(([0-9]|\\.||,)+)',
  23 + idx: 1,
  24 + disable: false,
  25 + postprocessing: (val) => (val || '').replace(/[,.]/g, ''),
  26 + },
  27 + ],
  28 +};
test/message-extractor.js
... ... @@ -0,0 +1,57 @@
  1 +/* global describe it */
  2 +
  3 +// eslint-disable-next-line no-unused-vars
  4 +const should = require('should');
  5 +const finder = require('../lib/message-extractor');
  6 +const organicRules = require('../lib/pattern-rules');
  7 +
  8 +describe('#message-extractor', () => {
  9 + it('should handle garbage input', () => {
  10 + should.not.exists(finder(null, null, '39A9909D'));
  11 + should.not.exists(finder(null, '', '8C046E19'));
  12 + should.not.exists(finder(null, 'ada', '4154D1DC'));
  13 + should.not.exists(finder([], 'ada'), '5511A78C');
  14 + });
  15 +
  16 + it('should return correct sn', () => {
  17 + finder(
  18 + organicRules.sn,
  19 + 'SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5;05/07/21 19:05 TRANSAKSI PLNB50 KE 14336230686, (ISO00) BERHASIL. SAL=RP 75.856.585 ,HRG=RP 50.020 ,ID=91280176,SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5@,REQID=2794362 *Channel Telegram : https://t.me/metroreloadinfoh2h',
  20 + false,
  21 + ).should.equal('3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5', 'ST24 metro-reload 5B164B64');
  22 +
  23 + finder(
  24 + organicRules.sn,
  25 + 'ISI TS10 KE 082324881979 , SUKSES. SAL=489700,HRG=10300,ID=1625459089388,SN=0061003777417733',
  26 + false,
  27 + ).should.equal('0061003777417733', 'PLINK 00FC0A03');
  28 + });
  29 +
  30 + it('should return correct price', () => {
  31 + finder(
  32 + organicRules.price,
  33 + 'SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5;05/07/21 19:05 TRANSAKSI PLNB50 KE 14336230686, (ISO00) BERHASIL. SAL=RP 75.856.585 ,HRG=RP 50.020 ,ID=91280176,SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5@,REQID=2794362 *Channel Telegram : https://t.me/metroreloadinfoh2h',
  34 + false,
  35 + ).should.equal('50020', 'ST24 metro-reload 572DAAE1');
  36 +
  37 + finder(
  38 + organicRules.price,
  39 + 'ISI TS10 KE 082324881979 , SUKSES. SAL=489700,HRG=10300,ID=1625459089388,SN=0061003777417733',
  40 + false,
  41 + ).should.equal('10300', 'PLINK DB7F7B1C');
  42 + });
  43 +
  44 + it('should return correct ending balance', () => {
  45 + finder(
  46 + organicRules.balance,
  47 + 'SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5;05/07/21 19:05 TRANSAKSI PLNB50 KE 14336230686, (ISO00) BERHASIL. SAL=RP 75.856.585 ,HRG=RP 50.020 ,ID=91280176,SN=3438-2805-5518-4885-2577/A HANIS SACHRA/R1 /1300 VA/31,5@,REQID=2794362 *Channel Telegram : https://t.me/metroreloadinfoh2h',
  48 + false,
  49 + ).should.equal('75856585', 'ST24 metro-reload 5E6CA14F');
  50 +
  51 + finder(
  52 + organicRules.balance,
  53 + 'ISI TS10 KE 082324881979 , SUKSES. SAL=489700,HRG=10300,ID=1625459089388,SN=0061003777417733',
  54 + false,
  55 + ).should.equal('489700', 'PLINK 29C24CEA');
  56 + });
  57 +});