Commit a9aef2698af6df3b6134632af50b65f7d08afe62

Authored by Adhidarma Hadiwinoto
1 parent 432f85471d
Exists in master

Separate webhook sender

Showing 6 changed files with 123 additions and 80 deletions Side-by-side Diff

... ... @@ -8,7 +8,6 @@
8 8 "partner": {
9 9 "trust_proxy": ["loopback", "linklocal"],
10 10 "port": 25614,
11   - "# webhook": "http://PLEASE_CHANGE_ME/PLEASE_CHANGE_ME",
12 11 "dump": false
13 12 },
14 13 "core": {
... ... @@ -27,6 +26,11 @@
27 26 "max_retry": 10
28 27 },
29 28  
  29 + "webhook": {
  30 + "url": null,
  31 + "dump": false
  32 + },
  33 +
30 34 "terminals_with_location": [],
31 35  
32 36 "# cluster": "Isi dengan boolean atau angka jumlah anak yang akan dibuat. Jika diisi boolean true, jumlah anak akan dihitung otomatis",
lib/core-callback/sender.js
... ... @@ -7,6 +7,8 @@ const logger = require('tektrans-logger');
7 7 const dumper = require('./dumper/sender');
8 8 const matrix = require('../matrix');
9 9  
  10 +const webhookSender = require('../webhook-sender');
  11 +
10 12 const HTTP_TIMEOUT = Number(
11 13 config.callback_sender && config.callback_sender.http_timeout_ms,
12 14 ) || 30 * 1000;
... ... @@ -180,45 +182,6 @@ const sender = async (data, xid, retry) => {
180 182 delete matrix.callback_sender.active_sending[xid];
181 183 }
182 184  
183   - if (config.listener.partner.webhook) {
184   - try {
185   - const webhookType = 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK';
186   -
187   - logger.verbose(`${MODULE_NAME} E21E3DC6: Sending webhook`, {
188   - xid,
189   - webhookType,
190   - partner: config.listener.partner.webhook,
191   - trxId: data.transaction_id && data.transaction_id.toString(),
192   - request_id: data.request_id && data.request_id.toString(),
193   - product_name: data.product_name,
194   - destination: data.destination,
195   - rc: data.rc,
196   - });
197   -
198   - axios.post(config.listener.partner.webhook, {
199   - webhookType: 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK',
200   - body: params,
201   - });
202   -
203   - logger.verbose(`${MODULE_NAME} 26BCA07F: Webhook sent`, {
204   - xid,
205   - webhookType,
206   - partner: config.listener.partner.webhook,
207   - trxId: data.transaction_id && data.transaction_id.toString(),
208   - request_id: data.request_id && data.request_id.toString(),
209   - product_name: data.product_name,
210   - destination: data.destination,
211   - rc: data.rc,
212   - });
213   - } catch (e) {
214   - logger.warn(`${MODULE_NAME} F722520A: Exception on calling webhook`, {
215   - xid,
216   - eCode: e.code,
217   - eMessage: e.message || e.toString(),
218   - });
219   - }
220   - }
221   -
222 185 dumper(
223 186 xid,
224 187 isHttpPost ? 'POST' : 'GET',
... ... @@ -227,6 +190,9 @@ const sender = async (data, xid, retry) => {
227 190 responseToDump,
228 191 errorResponseToDump,
229 192 );
  193 +
  194 + const webhookType = 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK';
  195 + webhookSender(xid, webhookType, params);
230 196 }
231 197 };
232 198  
lib/partner-listener/routers/topup.js
1 1 const MODULE_NAME = 'PARTNER-LISTENER.ROUTER.TOPUP';
2 2  
3 3 const express = require('express');
4   -const axios = require('axios');
5 4  
6 5 const config = require('komodo-sdk/config');
7 6 const logger = require('tektrans-logger');
... ... @@ -9,6 +8,7 @@ const coreapi = require('komodo-sdk/coreapi');
9 8 // const coreapi = require('../../coreapi');
10 9 const matrix = require('../../matrix');
11 10 const dumper = require('../dumper');
  11 +const webhookSender = require('../../webhook-sender');
12 12  
13 13 const router = express.Router();
14 14 module.exports = router;
... ... @@ -151,40 +151,10 @@ async function pageIndex(req, res) {
151 151  
152 152 res.json(responseToPartner);
153 153  
154   - if (config.listener.partner.webhook) {
155   - try {
156   - const webhookType = 'KOMODO-CENTER-HTTPGETX.PARTNER-LISTENER.DIRECT-RESPONSE';
157   -
158   - logger.verbose(`${MODULE_NAME} 2CA59ED3: Sending webhook`, {
159   - xid,
160   - webhookType,
161   - partner: config.listener.partner.webhook,
162   - trxId: coreResponse.transaction_id,
163   - request_id: req.body.request_id || req.query.request_id,
164   - });
165   -
166   - axios.post(config.listener.partner.webhook, {
167   - webhookType,
168   - body: responseToPartner,
169   - });
170   -
171   - logger.verbose(`${MODULE_NAME} 50BE8D98: Webhook sent`, {
172   - xid,
173   - webhookType,
174   - partner: config.listener.partner.webhook,
175   - trxId: coreResponse.transaction_id,
176   - request_id: req.body.request_id || req.query.request_id,
177   - });
178   - } catch (e) {
179   - logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, {
180   - xid,
181   - eCode: e.code,
182   - eMessage: e.message || e.toString(),
183   - });
184   - }
185   - }
186   -
187 154 dumper(xid, req, responseToPartner);
  155 +
  156 + const webhookType = 'KOMODO-CENTER-HTTPGETX.PARTNER-LISTENER.DIRECT-RESPONSE';
  157 + webhookSender(xid, webhookType, responseToPartner);
188 158 }
189 159  
190 160 // router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); });
lib/webhook-sender.js
... ... @@ -0,0 +1,89 @@
  1 +const MODULE_NAME = 'WEBHOOK-SENDER';
  2 +
  3 +const axios = require('axios');
  4 +const moment = require('moment');
  5 +const fs = require('fs');
  6 +const path = require('path');
  7 +const stringify = require('json-stringify-pretty-compact');
  8 +const config = require('komodo-sdk/config');
  9 +const logger = require('tektrans-logger');
  10 +
  11 +const DEFAULT_MAX_RETRY = 10;
  12 +const DEFAULT_SLEEP_BEFORE_RETRY_MS = 10 * 1000;
  13 +
  14 +const maxRetry = Number(config.webhook && config.webhook.max_retry)
  15 + || DEFAULT_MAX_RETRY;
  16 +const sleepBeforeRetryMs = Number(config.webhook && config.webhook.sleep_before_retry_ms)
  17 + || DEFAULT_SLEEP_BEFORE_RETRY_MS;
  18 +
  19 +const baseDumpDir = path.join('dump', 'webhook-sender');
  20 +if (!fs.existsSync(baseDumpDir)) {
  21 + fs.mkdirSync(baseDumpDir, { recursive: true });
  22 +}
  23 +const lastDumpFileName = path.join(baseDumpDir, 'last');
  24 +
  25 +const dumper = async (xid, webhookType, body) => {
  26 + if (!config.webhook || !config.webhook.dump) {
  27 + return;
  28 + }
  29 +
  30 + await fs.promises.writeFile(
  31 + path.join(baseDumpDir, [moment().format('YYYYMMDD-HHmmssSSS'), xid].join('_')),
  32 + stringify({ webhookType, body }),
  33 + );
  34 +
  35 + await fs.promises.writeFile(
  36 + lastDumpFileName,
  37 + stringify({ webhookType, body }),
  38 + );
  39 +};
  40 +
  41 +const sender = async (xid, webhookType, body, retry) => {
  42 + if (!config.webhook || !config.webhook.url) {
  43 + return;
  44 + }
  45 +
  46 + try {
  47 + logger.verbose(`${MODULE_NAME} 2CA59ED3: Sending webhook`, {
  48 + xid,
  49 + webhookType,
  50 + partner: config.webhook.url,
  51 + trxId: body.transaction_id,
  52 + request_id: body.request_id,
  53 + });
  54 +
  55 + axios.post(config.listener.partner.webhook, {
  56 + webhookType,
  57 + body,
  58 + });
  59 +
  60 + await dumper(xid, webhookType, body);
  61 +
  62 + logger.verbose(`${MODULE_NAME} 50BE8D98: Webhook sent`, {
  63 + xid,
  64 + webhookType,
  65 + partner: config.listener.partner.webhook,
  66 + });
  67 + } catch (e) {
  68 + logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, {
  69 + xid,
  70 + eCode: e.code,
  71 + eMessage: e.message || e.toString(),
  72 + retried: retry || 0,
  73 + maxRetry,
  74 + });
  75 +
  76 + if ((retry || 0) >= maxRetry) {
  77 + logger.warn(`${MODULE_NAME} 4A60B406: Max retry exceeded`, {
  78 + xid,
  79 + });
  80 +
  81 + return;
  82 + }
  83 +
  84 + setTimeout(() => {
  85 + sender(xid, webhookType, body, (retry || 0) + 1);
  86 + }, sleepBeforeRetryMs);
  87 + }
  88 +};
  89 +module.exports = sender;
... ... @@ -13,6 +13,7 @@
13 13 "express": "^4.17.1",
14 14 "express-rate-limit": "^6.6.0",
15 15 "join-path": "^1.1.1",
  16 + "json-stringify-pretty-compact": "^4.0.0",
16 17 "komodo-sdk": "^1.45.6",
17 18 "mkdirp": "^1.0.4",
18 19 "moment": "^2.24.0",
... ... @@ -2087,9 +2088,10 @@
2087 2088 "dev": true
2088 2089 },
2089 2090 "node_modules/json-stringify-pretty-compact": {
2090   - "version": "3.0.0",
2091   - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz",
2092   - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA=="
  2091 + "version": "4.0.0",
  2092 + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
  2093 + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==",
  2094 + "license": "MIT"
2093 2095 },
2094 2096 "node_modules/json-stringify-safe": {
2095 2097 "version": "5.0.1",
... ... @@ -2148,6 +2150,12 @@
2148 2150 "sd-notify": "^2.8.0"
2149 2151 }
2150 2152 },
  2153 + "node_modules/komodo-sdk/node_modules/json-stringify-pretty-compact": {
  2154 + "version": "3.0.0",
  2155 + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz",
  2156 + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==",
  2157 + "license": "MIT"
  2158 + },
2151 2159 "node_modules/komodo-sdk/node_modules/uniqid": {
2152 2160 "version": "4.1.1",
2153 2161 "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
... ... @@ -6327,9 +6335,9 @@
6327 6335 "dev": true
6328 6336 },
6329 6337 "json-stringify-pretty-compact": {
6330   - "version": "3.0.0",
6331   - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz",
6332   - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA=="
  6338 + "version": "4.0.0",
  6339 + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
  6340 + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q=="
6333 6341 },
6334 6342 "json-stringify-safe": {
6335 6343 "version": "5.0.1",
... ... @@ -6383,6 +6391,11 @@
6383 6391 "uuid": "^3.4.0"
6384 6392 },
6385 6393 "dependencies": {
  6394 + "json-stringify-pretty-compact": {
  6395 + "version": "3.0.0",
  6396 + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz",
  6397 + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA=="
  6398 + },
6386 6399 "uniqid": {
6387 6400 "version": "4.1.1",
6388 6401 "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
... ... @@ -33,6 +33,7 @@
33 33 "express": "^4.17.1",
34 34 "express-rate-limit": "^6.6.0",
35 35 "join-path": "^1.1.1",
  36 + "json-stringify-pretty-compact": "^4.0.0",
36 37 "komodo-sdk": "^1.45.6",
37 38 "mkdirp": "^1.0.4",
38 39 "moment": "^2.24.0",