webhook-sender.js
3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const MODULE_NAME = 'WEBHOOK-SENDER';
const axios = require('axios');
const moment = require('moment');
const fs = require('fs');
const path = require('path');
const stringify = require('json-stringify-pretty-compact');
const validUrl = require('valid-url');
const config = require('komodo-sdk/config');
const logger = require('tektrans-logger');
const DEFAULT_MAX_RETRY = 10;
const DEFAULT_SLEEP_BEFORE_RETRY_MS = 10 * 1000;
const maxRetry = Number(config.webhook && config.webhook.max_retry)
|| DEFAULT_MAX_RETRY;
const sleepBeforeRetryMs = Number(config.webhook && config.webhook.sleep_before_retry_ms)
|| DEFAULT_SLEEP_BEFORE_RETRY_MS;
const baseDumpDir = path.join('dump', 'webhook-sender');
const DO_WEBHOOK = config.webhook && config.webhook.url && validUrl.isWebUri(config.webhook.url);
if (!fs.existsSync(baseDumpDir)) {
fs.mkdirSync(baseDumpDir, { recursive: true });
}
const sleepMs = (ms) => new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
const dumper = async (xid, webhookType, body) => {
if (!config.webhook || !config.webhook.dump) {
return;
}
try {
const filename = [
[moment().format('YYYYMMDD-HHmmssSSS'), xid].join('_'),
webhookType,
body.request_id && ['reqid', body.request_id].join('_'),
'json',
].filter((item) => item).join('.');
// write dump file
await fs.promises.writeFile(
path.join(baseDumpDir, filename),
stringify({ webhookType, body }),
);
// write last dump file
await fs.promises.writeFile(
path.join(baseDumpDir, ['last', webhookType].join('.')),
stringify({ webhookType, body }),
);
} catch (e) {
logger.warn(`${MODULE_NAME} D3EF00D9: Exception on dumper`, {
xid,
eCode: e.code,
eMessage: e.message || e.toString(),
});
}
};
const sender = async (xid, webhookType, body, retry) => {
if (!DO_WEBHOOK) {
return;
}
try {
logger.verbose(`${MODULE_NAME} 2CA59ED3: Sending webhook`, {
xid,
webhookType,
partner: config.webhook.url,
trxId: body.transaction_id,
request_id: body.request_id,
retried: retry || 0,
});
await axios.post(config.webhook.url, {
webhookType,
body,
});
await dumper(xid, webhookType, body);
logger.verbose(`${MODULE_NAME} 50BE8D98: Webhook sent`, {
xid,
webhookType,
partner: config.webhook.url,
});
} catch (e) {
logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, {
xid,
httpStatusCode: e.response && e.response.status,
eCode: e.code,
eMessage: e.message || e.toString(),
retried: retry || 0,
maxRetry,
});
if ((retry || 0) >= maxRetry) {
logger.warn(`${MODULE_NAME} 4A60B406: Max retry exceeded`, {
xid,
});
return;
}
await sleepMs(sleepBeforeRetryMs);
await sender(xid, webhookType, body, (retry || 0) + 1);
}
};
module.exports = sender;