unismsgateway 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/lib/lib.d.ts +2 -2
- package/dist/lib/lib.js +2 -1
- package/dist/lib/nest-gateway.d.ts +1 -0
- package/dist/lib/nest-gateway.js +93 -40
- package/dist/lib/platform.d.ts +3 -3
- package/dist/lib/platform.js +13 -8
- package/dist/lib/types.js +40 -0
- package/package.json +1 -1
- package/dist/lib/j;[ ]p;;;j]/ts +0 -44
- package/dist/scripts/test-live.d.ts +0 -11
- package/dist/scripts/test-live.js +0 -191
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -13
- package/dist/src/lib/lib.d.ts +0 -5
- package/dist/src/lib/lib.js +0 -21
- package/dist/src/lib/nest-gateway.d.ts +0 -13
- package/dist/src/lib/nest-gateway.js +0 -198
- package/dist/src/lib/platform.d.ts +0 -13
- package/dist/src/lib/platform.js +0 -90
- package/dist/src/lib/types.js +0 -42
- /package/dist/{src/lib → lib}/hubtel-gateway.d.ts +0 -0
- /package/dist/{src/lib → lib}/hubtel-gateway.js +0 -0
- /package/dist/{src/lib → lib}/route-gateway.d.ts +0 -0
- /package/dist/{src/lib → lib}/route-gateway.js +0 -0
- /package/dist/{src/lib → lib}/types.d.ts +0 -0
package/README.md
CHANGED
|
@@ -463,6 +463,9 @@ Full variable reference (selection, per-gateway credentials, live send): [Live i
|
|
|
463
463
|
|
|
464
464
|
## Changelog
|
|
465
465
|
|
|
466
|
+
### 1.5.2
|
|
467
|
+
- **Build:** TypeScript `rootDir` is now `./src` with `include: ["src/**/*.ts"]` (scripts stay `ts-node`-only). Previously the compiler also picked up `scripts/test-live.ts`, inferred a project root above `src/`, and emitted library code under `dist/src/lib/…` while published entrypoints load `dist/lib/…` — leaving **stale or missing** `dist/lib/nest-gateway.js` (wrong `requestBody` shape). The published `dist/` layout now matches `package.json` `main` and always rebuilds gateway files from current sources.
|
|
468
|
+
|
|
466
469
|
### 1.5.1
|
|
467
470
|
- **Fix (`nest` / all gateways):** `quickSend` now accepts **camelCase** (`from`, `to`, `content`, `type`) as well as PascalCase (`From`, `To`, `Content`, `Type`). Passing only camelCase previously left `Content` undefined, so the nest JSON body omitted `text` and the API returned handshake **1305** (missing or invalid message body). Validation errors throw clear messages when body or sender is empty after trim.
|
|
468
471
|
|
package/dist/lib/lib.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, SendResult, ISmsGateway } from './platform';
|
|
1
|
+
import { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, QuickSendParamsInput, QuickSendParamsCamel, normalizeQuickSendParams, SendResult, ISmsGateway } from './platform';
|
|
2
2
|
export declare function init(settings: IgatewaySettings): smsPlatform;
|
|
3
3
|
export declare function getSmsPlatform(): smsPlatform | null;
|
|
4
4
|
export declare function reset(): void;
|
|
5
|
-
export { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, SendResult, ISmsGateway };
|
|
5
|
+
export { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, QuickSendParamsInput, QuickSendParamsCamel, normalizeQuickSendParams, SendResult, ISmsGateway };
|
package/dist/lib/lib.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.smsPlatform = exports.reset = exports.getSmsPlatform = exports.init = void 0;
|
|
3
|
+
exports.normalizeQuickSendParams = exports.smsPlatform = exports.reset = exports.getSmsPlatform = exports.init = void 0;
|
|
4
4
|
const platform_1 = require("./platform");
|
|
5
5
|
Object.defineProperty(exports, "smsPlatform", { enumerable: true, get: function () { return platform_1.smsPlatform; } });
|
|
6
|
+
Object.defineProperty(exports, "normalizeQuickSendParams", { enumerable: true, get: function () { return platform_1.normalizeQuickSendParams; } });
|
|
6
7
|
let smsPlatformInstance = null;
|
|
7
8
|
function init(settings) {
|
|
8
9
|
smsPlatformInstance = new platform_1.smsPlatform(settings);
|
|
@@ -3,6 +3,7 @@ export declare class NestSmsGateway implements ISmsGateway {
|
|
|
3
3
|
private config;
|
|
4
4
|
constructor(config: NestSmsConfig);
|
|
5
5
|
init(): ISmsGateway;
|
|
6
|
+
private log;
|
|
6
7
|
private makeRequest;
|
|
7
8
|
quickSend(params: QuickSendParams, callback?: Function): Promise<SendResult>;
|
|
8
9
|
getBalance(): Promise<{
|
package/dist/lib/nest-gateway.js
CHANGED
|
@@ -38,106 +38,159 @@ class NestSmsGateway {
|
|
|
38
38
|
this.config = {
|
|
39
39
|
host: config.host || DEFAULT_HOST,
|
|
40
40
|
protocol: config.protocol || DEFAULT_PROTOCOL,
|
|
41
|
-
apiKey: config.apiKey
|
|
41
|
+
apiKey: config.apiKey,
|
|
42
|
+
debug: config.debug || false
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
init() {
|
|
45
46
|
return this;
|
|
46
47
|
}
|
|
48
|
+
log(...args) {
|
|
49
|
+
if (this.config.debug) {
|
|
50
|
+
console.log('[unismsgateway:nest]', ...args);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
47
53
|
makeRequest(endpoint, data) {
|
|
48
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
55
|
return new Promise((resolve, reject) => {
|
|
50
|
-
var _a;
|
|
51
56
|
const postData = data ? JSON.stringify(data) : '';
|
|
52
57
|
const protocol = this.config.protocol || DEFAULT_PROTOCOL;
|
|
53
58
|
const httpModule = protocol === 'https' ? https : http;
|
|
54
59
|
const defaultPort = protocol === 'https' ? 443 : 80;
|
|
60
|
+
const host = this.config.host || DEFAULT_HOST;
|
|
61
|
+
const hostname = host.includes(':') ? host.split(':')[0] : host;
|
|
62
|
+
const port = host.includes(':')
|
|
63
|
+
? parseInt(host.split(':')[1], 10)
|
|
64
|
+
: defaultPort;
|
|
55
65
|
const options = {
|
|
56
|
-
hostname
|
|
57
|
-
port
|
|
58
|
-
? parseInt(this.config.host.split(':')[1])
|
|
59
|
-
: defaultPort,
|
|
66
|
+
hostname,
|
|
67
|
+
port,
|
|
60
68
|
path: `/v5/${endpoint}`,
|
|
61
69
|
method: 'POST',
|
|
70
|
+
// Disable keep-alive connection pooling. Node's global agent reuses
|
|
71
|
+
// sockets across calls; when the server closes an idle socket server-side
|
|
72
|
+
// the next write (i.e. the request body in quickSend) gets ECONNABORTED.
|
|
73
|
+
// agent:false forces a fresh connection for every request.
|
|
74
|
+
agent: false,
|
|
62
75
|
headers: {
|
|
63
|
-
'Host':
|
|
76
|
+
'Host': hostname,
|
|
64
77
|
'Content-Type': 'application/json',
|
|
65
78
|
'Accept': 'application/json',
|
|
66
79
|
'Authorization': `key ${this.config.apiKey}`,
|
|
67
80
|
'Content-Length': Buffer.byteLength(postData)
|
|
68
81
|
}
|
|
69
82
|
};
|
|
83
|
+
this.log(`POST /v5/${endpoint}`, data ? JSON.stringify(data) : '(no body)');
|
|
70
84
|
const req = httpModule.request(options, (res) => {
|
|
71
85
|
let responseBody = '';
|
|
72
86
|
res.on('data', (chunk) => {
|
|
73
87
|
responseBody += chunk;
|
|
74
88
|
});
|
|
75
89
|
res.on('end', () => {
|
|
90
|
+
var _a;
|
|
91
|
+
const statusCode = (_a = res.statusCode) !== null && _a !== void 0 ? _a : 0;
|
|
92
|
+
this.log(`HTTP ${statusCode} response:`, responseBody);
|
|
76
93
|
try {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
resolve(parsed);
|
|
94
|
+
const parsed = JSON.parse(responseBody);
|
|
95
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
96
|
+
resolve({ statusCode, body: parsed });
|
|
80
97
|
}
|
|
81
98
|
else {
|
|
82
|
-
|
|
99
|
+
const err = new Error(`HTTP ${statusCode}: ${responseBody}`);
|
|
100
|
+
err.statusCode = statusCode;
|
|
101
|
+
err.rawBody = responseBody;
|
|
102
|
+
reject(err);
|
|
83
103
|
}
|
|
84
104
|
}
|
|
85
|
-
catch (
|
|
86
|
-
|
|
105
|
+
catch (_b) {
|
|
106
|
+
const err = new Error(`Failed to parse gateway response (HTTP ${statusCode}): ${responseBody}`);
|
|
107
|
+
err.statusCode = statusCode;
|
|
108
|
+
err.rawBody = responseBody;
|
|
109
|
+
reject(err);
|
|
87
110
|
}
|
|
88
111
|
});
|
|
89
112
|
});
|
|
90
113
|
req.on('error', (error) => {
|
|
114
|
+
this.log('Network error:', error.message);
|
|
91
115
|
reject(error);
|
|
92
116
|
});
|
|
93
|
-
|
|
117
|
+
if (postData) {
|
|
118
|
+
req.write(postData);
|
|
119
|
+
}
|
|
94
120
|
req.end();
|
|
95
121
|
});
|
|
96
122
|
});
|
|
97
123
|
}
|
|
98
124
|
quickSend(params, callback) {
|
|
99
|
-
var _a, _b;
|
|
125
|
+
var _a, _b, _c, _d, _e;
|
|
100
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
const endpoint = 'message/sms/send';
|
|
102
127
|
const requestBody = {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
128
|
+
text: params.Content,
|
|
129
|
+
type: (_a = params.Type) !== null && _a !== void 0 ? _a : 0,
|
|
130
|
+
sender: params.From,
|
|
131
|
+
destinations: [String(params.To)]
|
|
107
132
|
};
|
|
133
|
+
this.log('quickSend params:', JSON.stringify(params));
|
|
134
|
+
let result;
|
|
108
135
|
try {
|
|
109
|
-
const response = yield this.makeRequest(
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
const { statusCode, body: response } = yield this.makeRequest('message/sms/send', requestBody);
|
|
137
|
+
const handshakeId = (_b = response.handshake) === null || _b === void 0 ? void 0 : _b.id;
|
|
138
|
+
const handshakeLabel = (_c = response.handshake) === null || _c === void 0 ? void 0 : _c.label;
|
|
139
|
+
const handshakeOk = Number(handshakeId) === 0;
|
|
140
|
+
const responseData = (_d = response.data) !== null && _d !== void 0 ? _d : null;
|
|
141
|
+
const batchId = responseData && typeof responseData === 'object'
|
|
142
|
+
? responseData.batch
|
|
143
|
+
: undefined;
|
|
144
|
+
const firstDest = responseData && typeof responseData === 'object'
|
|
145
|
+
? (_e = responseData.destinations) === null || _e === void 0 ? void 0 : _e[0]
|
|
146
|
+
: undefined;
|
|
147
|
+
let errorMsg;
|
|
148
|
+
if (!handshakeOk) {
|
|
149
|
+
if (handshakeLabel) {
|
|
150
|
+
errorMsg = `API Error [code ${handshakeId}]: ${handshakeLabel}`;
|
|
151
|
+
}
|
|
152
|
+
else if (handshakeId !== undefined && handshakeId !== null) {
|
|
153
|
+
errorMsg = `API Error: handshake code=${handshakeId}`;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
errorMsg = `Unexpected API response: ${JSON.stringify(response)}`;
|
|
157
|
+
}
|
|
117
158
|
}
|
|
118
|
-
|
|
159
|
+
result = {
|
|
160
|
+
success: handshakeOk,
|
|
161
|
+
messageId: batchId || (firstDest === null || firstDest === void 0 ? void 0 : firstDest.id),
|
|
162
|
+
// On failure, expose the full raw response so callers can inspect it.
|
|
163
|
+
data: handshakeOk ? responseData : response,
|
|
164
|
+
error: errorMsg,
|
|
165
|
+
statusCode
|
|
166
|
+
};
|
|
119
167
|
}
|
|
120
168
|
catch (error) {
|
|
169
|
+
const httpErr = error;
|
|
121
170
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
122
|
-
|
|
171
|
+
result = {
|
|
123
172
|
success: false,
|
|
124
|
-
error: errorMessage
|
|
173
|
+
error: errorMessage,
|
|
174
|
+
statusCode: httpErr.statusCode,
|
|
175
|
+
// Preserve whatever raw body we got for inspection.
|
|
176
|
+
data: httpErr.rawBody !== undefined ? httpErr.rawBody : null
|
|
125
177
|
};
|
|
126
|
-
if (callback) {
|
|
127
|
-
callback(result);
|
|
128
|
-
}
|
|
129
|
-
return result;
|
|
130
178
|
}
|
|
179
|
+
this.log('quickSend result:', JSON.stringify(result));
|
|
180
|
+
if (callback) {
|
|
181
|
+
callback(result);
|
|
182
|
+
}
|
|
183
|
+
return result;
|
|
131
184
|
});
|
|
132
185
|
}
|
|
133
186
|
getBalance() {
|
|
134
|
-
var _a, _b;
|
|
187
|
+
var _a, _b, _c, _d;
|
|
135
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
|
|
137
|
-
const response = yield this.makeRequest(
|
|
189
|
+
this.log('getBalance called');
|
|
190
|
+
const { body: response } = yield this.makeRequest('account/balance');
|
|
138
191
|
return {
|
|
139
|
-
balance: ((_a = response.data) === null || _a === void 0 ? void 0 : _a.balance)
|
|
140
|
-
model: ((
|
|
192
|
+
balance: (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.balance) !== null && _b !== void 0 ? _b : 0,
|
|
193
|
+
model: (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.model) !== null && _d !== void 0 ? _d : 'quantity'
|
|
141
194
|
};
|
|
142
195
|
});
|
|
143
196
|
}
|
package/dist/lib/platform.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IgatewaySettings, IgatewayParam, ISmsGateway,
|
|
1
|
+
import { IgatewaySettings, IgatewayParam, ISmsGateway, ISmsGatewayDelegate, QuickSendParamsInput, SendResult } from './types';
|
|
2
2
|
export * from './types';
|
|
3
3
|
export declare class smsPlatform implements ISmsGateway {
|
|
4
4
|
private _settings;
|
|
@@ -7,7 +7,7 @@ export declare class smsPlatform implements ISmsGateway {
|
|
|
7
7
|
private validateSettings;
|
|
8
8
|
private createGateway;
|
|
9
9
|
init(): ISmsGateway;
|
|
10
|
-
quickSend(param:
|
|
11
|
-
getGateway():
|
|
10
|
+
quickSend(param: QuickSendParamsInput, callback?: Function): Promise<SendResult>;
|
|
11
|
+
getGateway(): ISmsGatewayDelegate;
|
|
12
12
|
}
|
|
13
13
|
export { IgatewaySettings, IgatewayParam };
|
package/dist/lib/platform.js
CHANGED
|
@@ -11,9 +11,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.smsPlatform = void 0;
|
|
14
|
-
const hubtel_sms_extended_1 = require("hubtel-sms-extended");
|
|
15
|
-
const routemobilesms_1 = require("routemobilesms");
|
|
16
14
|
const nest_gateway_1 = require("./nest-gateway");
|
|
15
|
+
const hubtel_gateway_1 = require("./hubtel-gateway");
|
|
16
|
+
const route_gateway_1 = require("./route-gateway");
|
|
17
|
+
const types_1 = require("./types");
|
|
17
18
|
__exportStar(require("./types"), exports);
|
|
18
19
|
const GATEWAY_CONFIGS = {
|
|
19
20
|
route: { requiresUsernamePassword: true },
|
|
@@ -47,23 +48,26 @@ class smsPlatform {
|
|
|
47
48
|
const { platformId, param } = this._settings;
|
|
48
49
|
switch (platformId) {
|
|
49
50
|
case 'route':
|
|
50
|
-
return new
|
|
51
|
+
return new route_gateway_1.RouteSmsGateway({
|
|
51
52
|
host: param.host || 'rslr.connectbind.com',
|
|
52
53
|
username: param.username,
|
|
53
54
|
password: param.password,
|
|
54
55
|
protocol: param.protocol || 'http',
|
|
55
|
-
port: param.port || 8080
|
|
56
|
+
port: param.port || 8080,
|
|
57
|
+
debug: param.debug
|
|
56
58
|
});
|
|
57
59
|
case 'hubtel':
|
|
58
|
-
return new
|
|
60
|
+
return new hubtel_gateway_1.HubtelSmsGateway({
|
|
59
61
|
clientId: param.clientId,
|
|
60
|
-
clientSecret: param.clientSecret
|
|
62
|
+
clientSecret: param.clientSecret,
|
|
63
|
+
debug: param.debug
|
|
61
64
|
});
|
|
62
65
|
case 'nest':
|
|
63
66
|
return new nest_gateway_1.NestSmsGateway({
|
|
64
67
|
apiKey: param.apiKey,
|
|
65
68
|
host: param.host,
|
|
66
|
-
protocol: param.protocol
|
|
69
|
+
protocol: param.protocol,
|
|
70
|
+
debug: param.debug
|
|
67
71
|
});
|
|
68
72
|
default:
|
|
69
73
|
throw new Error(`Unsupported platform: ${platformId}`);
|
|
@@ -76,7 +80,8 @@ class smsPlatform {
|
|
|
76
80
|
if (!this._gateway) {
|
|
77
81
|
throw new Error('Gateway not initialized. Call init() first.');
|
|
78
82
|
}
|
|
79
|
-
|
|
83
|
+
const normalized = (0, types_1.normalizeQuickSendParams)(param);
|
|
84
|
+
return this._gateway.quickSend(normalized, callback);
|
|
80
85
|
}
|
|
81
86
|
getGateway() {
|
|
82
87
|
return this._gateway;
|
package/dist/lib/types.js
CHANGED
|
@@ -1,2 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeQuickSendParams = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Maps PascalCase or camelCase quick-send fields to {@link QuickSendParams}.
|
|
6
|
+
* PascalCase wins when both are present.
|
|
7
|
+
*/
|
|
8
|
+
function normalizeQuickSendParams(params) {
|
|
9
|
+
var _a, _b, _c, _d;
|
|
10
|
+
const p = params;
|
|
11
|
+
const from = (_a = p.From) !== null && _a !== void 0 ? _a : p.from;
|
|
12
|
+
const to = (_b = p.To) !== null && _b !== void 0 ? _b : p.to;
|
|
13
|
+
const content = (_c = p.Content) !== null && _c !== void 0 ? _c : p.content;
|
|
14
|
+
const type = (_d = p.Type) !== null && _d !== void 0 ? _d : p.type;
|
|
15
|
+
const contentStr = content == null ? '' : String(content);
|
|
16
|
+
const trimmedBody = contentStr.trim();
|
|
17
|
+
if (trimmedBody === '') {
|
|
18
|
+
throw new Error('quickSend: message body is missing. Pass Content or content with a non-empty string.');
|
|
19
|
+
}
|
|
20
|
+
const fromStr = from == null ? '' : String(from).trim();
|
|
21
|
+
if (fromStr === '') {
|
|
22
|
+
throw new Error('quickSend: sender is missing. Pass From or from with a non-empty string.');
|
|
23
|
+
}
|
|
24
|
+
if (to === null || to === undefined) {
|
|
25
|
+
throw new Error('quickSend: recipient is missing. Pass To or to.');
|
|
26
|
+
}
|
|
27
|
+
const toVal = typeof to === 'number' ? to : String(to).trim();
|
|
28
|
+
let typeNum;
|
|
29
|
+
if (type !== undefined && type !== null) {
|
|
30
|
+
const n = Number(type);
|
|
31
|
+
if (!Number.isNaN(n)) {
|
|
32
|
+
typeNum = n;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
From: fromStr,
|
|
37
|
+
To: toVal,
|
|
38
|
+
Content: trimmedBody,
|
|
39
|
+
Type: typeNum
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.normalizeQuickSendParams = normalizeQuickSendParams;
|
package/package.json
CHANGED
package/dist/lib/j;[ ]p;;;j]/ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export declare type PlatformId = 'route' | 'hubtel' | 'nest';
|
|
2
|
-
export interface QuickSendParams {
|
|
3
|
-
From: string;
|
|
4
|
-
To: string | number;
|
|
5
|
-
Content: string;
|
|
6
|
-
Type?: number;
|
|
7
|
-
}
|
|
8
|
-
export interface SendResult {
|
|
9
|
-
success: boolean;
|
|
10
|
-
messageId?: string;
|
|
11
|
-
data?: any;
|
|
12
|
-
error?: string;
|
|
13
|
-
}
|
|
14
|
-
export interface IgatewayParam {
|
|
15
|
-
host?: string;
|
|
16
|
-
port?: number;
|
|
17
|
-
username?: string;
|
|
18
|
-
password?: string;
|
|
19
|
-
clientId?: string;
|
|
20
|
-
clientSecret?: string;
|
|
21
|
-
apiKey?: string;
|
|
22
|
-
protocol?: 'http' | 'https';
|
|
23
|
-
}
|
|
24
|
-
export interface IgatewaySettings {
|
|
25
|
-
platformId: PlatformId;
|
|
26
|
-
param: IgatewayParam;
|
|
27
|
-
}
|
|
28
|
-
export interface ISmsGateway {
|
|
29
|
-
init(): ISmsGateway;
|
|
30
|
-
quickSend(params: QuickSendParams, callback?: Function): Promise<SendResult>;
|
|
31
|
-
getBalance?(): Promise<any>;
|
|
32
|
-
}
|
|
33
|
-
export interface NestSmsConfig {
|
|
34
|
-
apiKey: string;
|
|
35
|
-
host?: string;
|
|
36
|
-
protocol?: 'http' | 'https';
|
|
37
|
-
}
|
|
38
|
-
export interface NestSendResponse {
|
|
39
|
-
handshake: {
|
|
40
|
-
id: number;
|
|
41
|
-
label: string;
|
|
42
|
-
};
|
|
43
|
-
data?: any;
|
|
44
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live integration test script for unismsgateway.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* 1. Copy .env.example to .env and fill in your credentials.
|
|
6
|
-
* 2. npm run test:live
|
|
7
|
-
*
|
|
8
|
-
* Set TEST_SEND=true in .env (or inline) to actually send an SMS.
|
|
9
|
-
* Without it, only init and balance checks run.
|
|
10
|
-
*/
|
|
11
|
-
export {};
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Live integration test script for unismsgateway.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* 1. Copy .env.example to .env and fill in your credentials.
|
|
7
|
-
* 2. npm run test:live
|
|
8
|
-
*
|
|
9
|
-
* Set TEST_SEND=true in .env (or inline) to actually send an SMS.
|
|
10
|
-
* Without it, only init and balance checks run.
|
|
11
|
-
*/
|
|
12
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
-
if (mod && mod.__esModule) return mod;
|
|
26
|
-
var result = {};
|
|
27
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
-
__setModuleDefault(result, mod);
|
|
29
|
-
return result;
|
|
30
|
-
};
|
|
31
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
32
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
33
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
34
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
35
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
36
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
37
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
const dotenv = __importStar(require("dotenv"));
|
|
42
|
-
dotenv.config();
|
|
43
|
-
const lib_1 = require("../src/lib/lib");
|
|
44
|
-
// ─── Colour helpers ──────────────────────────────────────────────────────────
|
|
45
|
-
const GREEN = '\x1b[32m';
|
|
46
|
-
const RED = '\x1b[31m';
|
|
47
|
-
const YELLOW = '\x1b[33m';
|
|
48
|
-
const CYAN = '\x1b[36m';
|
|
49
|
-
const BOLD = '\x1b[1m';
|
|
50
|
-
const RESET = '\x1b[0m';
|
|
51
|
-
const pass = (msg) => console.log(` ${GREEN}✔${RESET} ${msg}`);
|
|
52
|
-
const fail = (msg) => console.log(` ${RED}✖${RESET} ${msg}`);
|
|
53
|
-
const info = (msg) => console.log(` ${CYAN}ℹ${RESET} ${msg}`);
|
|
54
|
-
const warn = (msg) => console.log(` ${YELLOW}⚠${RESET} ${msg}`);
|
|
55
|
-
const title = (msg) => console.log(`\n${BOLD}${msg}${RESET}`);
|
|
56
|
-
// ─── Env helpers ─────────────────────────────────────────────────────────────
|
|
57
|
-
function env(key) {
|
|
58
|
-
return process.env[key] || undefined;
|
|
59
|
-
}
|
|
60
|
-
function requireEnv(key) {
|
|
61
|
-
const val = process.env[key];
|
|
62
|
-
if (!val)
|
|
63
|
-
throw new Error(`Missing required env var: ${key}`);
|
|
64
|
-
return val;
|
|
65
|
-
}
|
|
66
|
-
// ─── Test counters ───────────────────────────────────────────────────────────
|
|
67
|
-
let passed = 0;
|
|
68
|
-
let failed = 0;
|
|
69
|
-
function runTest(label, fn) {
|
|
70
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
try {
|
|
72
|
-
yield fn();
|
|
73
|
-
passed++;
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
failed++;
|
|
77
|
-
fail(`${label}: ${err instanceof Error ? err.message : String(err)}`);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
// ─── Per-platform tests ───────────────────────────────────────────────────────
|
|
82
|
-
function testPlatform(platformId) {
|
|
83
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
title(`Platform: ${platformId.toUpperCase()}`);
|
|
85
|
-
let platform;
|
|
86
|
-
// 1. Initialisation
|
|
87
|
-
yield runTest('Init / config validation', () => __awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
const param = {};
|
|
89
|
-
switch (platformId) {
|
|
90
|
-
case 'nest':
|
|
91
|
-
param.apiKey = requireEnv('NEST_API_KEY');
|
|
92
|
-
if (env('NEST_HOST'))
|
|
93
|
-
param.host = env('NEST_HOST');
|
|
94
|
-
if (env('NEST_PROTOCOL')) {
|
|
95
|
-
param.protocol = env('NEST_PROTOCOL');
|
|
96
|
-
}
|
|
97
|
-
param.debug = true;
|
|
98
|
-
break;
|
|
99
|
-
case 'hubtel':
|
|
100
|
-
param.clientId = requireEnv('HUBTEL_CLIENT_ID');
|
|
101
|
-
param.clientSecret = requireEnv('HUBTEL_CLIENT_SECRET');
|
|
102
|
-
break;
|
|
103
|
-
case 'route':
|
|
104
|
-
param.username = requireEnv('ROUTE_USERNAME');
|
|
105
|
-
param.password = requireEnv('ROUTE_PASSWORD');
|
|
106
|
-
if (env('ROUTE_HOST'))
|
|
107
|
-
param.host = env('ROUTE_HOST');
|
|
108
|
-
if (env('ROUTE_PORT'))
|
|
109
|
-
param.port = Number(env('ROUTE_PORT'));
|
|
110
|
-
if (env('ROUTE_PROTOCOL')) {
|
|
111
|
-
param.protocol = env('ROUTE_PROTOCOL');
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
platform = (0, lib_1.init)({ platformId, param });
|
|
116
|
-
pass(`Initialized ${platformId} platform`);
|
|
117
|
-
}));
|
|
118
|
-
// 2. Balance check (only nest and hubtel expose getBalance)
|
|
119
|
-
if (platformId === 'nest' || platformId === 'hubtel') {
|
|
120
|
-
yield runTest('getBalance()', () => __awaiter(this, void 0, void 0, function* () {
|
|
121
|
-
const gateway = platform.getGateway();
|
|
122
|
-
if (!gateway.getBalance) {
|
|
123
|
-
warn('getBalance not implemented — skipped');
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
const balance = yield gateway.getBalance();
|
|
127
|
-
pass(`Balance retrieved: ${JSON.stringify(balance)}`);
|
|
128
|
-
}));
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
warn(`getBalance not supported by '${platformId}' — skipped`);
|
|
132
|
-
}
|
|
133
|
-
// 3. Send SMS (opt-in via TEST_SEND=true)
|
|
134
|
-
const shouldSend = env('TEST_SEND') === 'true';
|
|
135
|
-
if (!shouldSend) {
|
|
136
|
-
warn('TEST_SEND is not set to true — skipping live send');
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
yield runTest('quickSend()', () => __awaiter(this, void 0, void 0, function* () {
|
|
140
|
-
const sendParams = {
|
|
141
|
-
From: requireEnv('TEST_FROM'),
|
|
142
|
-
To: requireEnv('TEST_TO'),
|
|
143
|
-
Content: env('TEST_CONTENT') || 'unismsgateway live test — please ignore.'
|
|
144
|
-
};
|
|
145
|
-
info(`Sending from "${sendParams.From}" to "${sendParams.To}"...`);
|
|
146
|
-
const result = yield platform.quickSend(sendParams);
|
|
147
|
-
if (!result.success) {
|
|
148
|
-
throw new Error(result.error || `Send failed: ${JSON.stringify(result)}`);
|
|
149
|
-
}
|
|
150
|
-
pass(`Message sent. Result: ${JSON.stringify(result)}`);
|
|
151
|
-
}));
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
// ─── Entry point ─────────────────────────────────────────────────────────────
|
|
155
|
-
function main() {
|
|
156
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
console.log(`\n${BOLD}═══════════════════════════════════════${RESET}`);
|
|
158
|
-
console.log(`${BOLD} unismsgateway — live test runner ${RESET}`);
|
|
159
|
-
console.log(`${BOLD}═══════════════════════════════════════${RESET}`);
|
|
160
|
-
const platformArg = env('GATEWAY_PLATFORM');
|
|
161
|
-
const platforms = platformArg
|
|
162
|
-
? [platformArg]
|
|
163
|
-
: (env('TEST_ALL') === 'true' ? ['nest', 'hubtel', 'route'] : []);
|
|
164
|
-
if (platforms.length === 0) {
|
|
165
|
-
console.log(`\n${YELLOW}No platform selected.${RESET}`);
|
|
166
|
-
console.log('Set GATEWAY_PLATFORM=nest|hubtel|route in your .env file,');
|
|
167
|
-
console.log('or set TEST_ALL=true to test all configured platforms.\n');
|
|
168
|
-
process.exit(1);
|
|
169
|
-
}
|
|
170
|
-
for (const p of platforms) {
|
|
171
|
-
try {
|
|
172
|
-
yield testPlatform(p);
|
|
173
|
-
}
|
|
174
|
-
catch (_a) {
|
|
175
|
-
// individual test errors already captured above
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// ─── Summary ────────────────────────────────────────────────────────────
|
|
179
|
-
title('Summary');
|
|
180
|
-
if (passed > 0)
|
|
181
|
-
pass(`${passed} check(s) passed`);
|
|
182
|
-
if (failed > 0)
|
|
183
|
-
fail(`${failed} check(s) failed`);
|
|
184
|
-
console.log();
|
|
185
|
-
process.exit(failed > 0 ? 1 : 0);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
main().catch((err) => {
|
|
189
|
-
console.error(`\n${RED}Unexpected error:${RESET}`, err);
|
|
190
|
-
process.exit(1);
|
|
191
|
-
});
|
package/dist/src/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/lib';
|
package/dist/src/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
__exportStar(require("./lib/lib"), exports);
|
package/dist/src/lib/lib.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, QuickSendParamsInput, QuickSendParamsCamel, normalizeQuickSendParams, SendResult, ISmsGateway } from './platform';
|
|
2
|
-
export declare function init(settings: IgatewaySettings): smsPlatform;
|
|
3
|
-
export declare function getSmsPlatform(): smsPlatform | null;
|
|
4
|
-
export declare function reset(): void;
|
|
5
|
-
export { smsPlatform, IgatewaySettings, IgatewayParam, PlatformId, QuickSendParams, QuickSendParamsInput, QuickSendParamsCamel, normalizeQuickSendParams, SendResult, ISmsGateway };
|
package/dist/src/lib/lib.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeQuickSendParams = exports.smsPlatform = exports.reset = exports.getSmsPlatform = exports.init = void 0;
|
|
4
|
-
const platform_1 = require("./platform");
|
|
5
|
-
Object.defineProperty(exports, "smsPlatform", { enumerable: true, get: function () { return platform_1.smsPlatform; } });
|
|
6
|
-
Object.defineProperty(exports, "normalizeQuickSendParams", { enumerable: true, get: function () { return platform_1.normalizeQuickSendParams; } });
|
|
7
|
-
let smsPlatformInstance = null;
|
|
8
|
-
function init(settings) {
|
|
9
|
-
smsPlatformInstance = new platform_1.smsPlatform(settings);
|
|
10
|
-
smsPlatformInstance.init();
|
|
11
|
-
return smsPlatformInstance;
|
|
12
|
-
}
|
|
13
|
-
exports.init = init;
|
|
14
|
-
function getSmsPlatform() {
|
|
15
|
-
return smsPlatformInstance;
|
|
16
|
-
}
|
|
17
|
-
exports.getSmsPlatform = getSmsPlatform;
|
|
18
|
-
function reset() {
|
|
19
|
-
smsPlatformInstance = null;
|
|
20
|
-
}
|
|
21
|
-
exports.reset = reset;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ISmsGateway, QuickSendParams, SendResult, NestSmsConfig } from './types';
|
|
2
|
-
export declare class NestSmsGateway implements ISmsGateway {
|
|
3
|
-
private config;
|
|
4
|
-
constructor(config: NestSmsConfig);
|
|
5
|
-
init(): ISmsGateway;
|
|
6
|
-
private log;
|
|
7
|
-
private makeRequest;
|
|
8
|
-
quickSend(params: QuickSendParams, callback?: Function): Promise<SendResult>;
|
|
9
|
-
getBalance(): Promise<{
|
|
10
|
-
balance: number;
|
|
11
|
-
model: string;
|
|
12
|
-
}>;
|
|
13
|
-
}
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
-
exports.NestSmsGateway = void 0;
|
|
32
|
-
const https = __importStar(require("https"));
|
|
33
|
-
const http = __importStar(require("http"));
|
|
34
|
-
const DEFAULT_HOST = 'api.smsonlinegh.com';
|
|
35
|
-
const DEFAULT_PROTOCOL = 'https';
|
|
36
|
-
class NestSmsGateway {
|
|
37
|
-
constructor(config) {
|
|
38
|
-
this.config = {
|
|
39
|
-
host: config.host || DEFAULT_HOST,
|
|
40
|
-
protocol: config.protocol || DEFAULT_PROTOCOL,
|
|
41
|
-
apiKey: config.apiKey,
|
|
42
|
-
debug: config.debug || false
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
init() {
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
|
-
log(...args) {
|
|
49
|
-
if (this.config.debug) {
|
|
50
|
-
console.log('[unismsgateway:nest]', ...args);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
makeRequest(endpoint, data) {
|
|
54
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
return new Promise((resolve, reject) => {
|
|
56
|
-
const postData = data ? JSON.stringify(data) : '';
|
|
57
|
-
const protocol = this.config.protocol || DEFAULT_PROTOCOL;
|
|
58
|
-
const httpModule = protocol === 'https' ? https : http;
|
|
59
|
-
const defaultPort = protocol === 'https' ? 443 : 80;
|
|
60
|
-
const host = this.config.host || DEFAULT_HOST;
|
|
61
|
-
const hostname = host.includes(':') ? host.split(':')[0] : host;
|
|
62
|
-
const port = host.includes(':')
|
|
63
|
-
? parseInt(host.split(':')[1], 10)
|
|
64
|
-
: defaultPort;
|
|
65
|
-
const options = {
|
|
66
|
-
hostname,
|
|
67
|
-
port,
|
|
68
|
-
path: `/v5/${endpoint}`,
|
|
69
|
-
method: 'POST',
|
|
70
|
-
// Disable keep-alive connection pooling. Node's global agent reuses
|
|
71
|
-
// sockets across calls; when the server closes an idle socket server-side
|
|
72
|
-
// the next write (i.e. the request body in quickSend) gets ECONNABORTED.
|
|
73
|
-
// agent:false forces a fresh connection for every request.
|
|
74
|
-
agent: false,
|
|
75
|
-
headers: {
|
|
76
|
-
'Host': hostname,
|
|
77
|
-
'Content-Type': 'application/json',
|
|
78
|
-
'Accept': 'application/json',
|
|
79
|
-
'Authorization': `key ${this.config.apiKey}`,
|
|
80
|
-
'Content-Length': Buffer.byteLength(postData)
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
this.log(`POST /v5/${endpoint}`, data ? JSON.stringify(data) : '(no body)');
|
|
84
|
-
const req = httpModule.request(options, (res) => {
|
|
85
|
-
let responseBody = '';
|
|
86
|
-
res.on('data', (chunk) => {
|
|
87
|
-
responseBody += chunk;
|
|
88
|
-
});
|
|
89
|
-
res.on('end', () => {
|
|
90
|
-
var _a;
|
|
91
|
-
const statusCode = (_a = res.statusCode) !== null && _a !== void 0 ? _a : 0;
|
|
92
|
-
this.log(`HTTP ${statusCode} response:`, responseBody);
|
|
93
|
-
try {
|
|
94
|
-
const parsed = JSON.parse(responseBody);
|
|
95
|
-
if (statusCode >= 200 && statusCode < 300) {
|
|
96
|
-
resolve({ statusCode, body: parsed });
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
const err = new Error(`HTTP ${statusCode}: ${responseBody}`);
|
|
100
|
-
err.statusCode = statusCode;
|
|
101
|
-
err.rawBody = responseBody;
|
|
102
|
-
reject(err);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (_b) {
|
|
106
|
-
const err = new Error(`Failed to parse gateway response (HTTP ${statusCode}): ${responseBody}`);
|
|
107
|
-
err.statusCode = statusCode;
|
|
108
|
-
err.rawBody = responseBody;
|
|
109
|
-
reject(err);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
req.on('error', (error) => {
|
|
114
|
-
this.log('Network error:', error.message);
|
|
115
|
-
reject(error);
|
|
116
|
-
});
|
|
117
|
-
if (postData) {
|
|
118
|
-
req.write(postData);
|
|
119
|
-
}
|
|
120
|
-
req.end();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
quickSend(params, callback) {
|
|
125
|
-
var _a, _b, _c, _d, _e;
|
|
126
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
-
const requestBody = {
|
|
128
|
-
text: params.Content,
|
|
129
|
-
type: (_a = params.Type) !== null && _a !== void 0 ? _a : 0,
|
|
130
|
-
sender: params.From,
|
|
131
|
-
destinations: [String(params.To)]
|
|
132
|
-
};
|
|
133
|
-
this.log('quickSend params:', JSON.stringify(params));
|
|
134
|
-
let result;
|
|
135
|
-
try {
|
|
136
|
-
const { statusCode, body: response } = yield this.makeRequest('message/sms/send', requestBody);
|
|
137
|
-
const handshakeId = (_b = response.handshake) === null || _b === void 0 ? void 0 : _b.id;
|
|
138
|
-
const handshakeLabel = (_c = response.handshake) === null || _c === void 0 ? void 0 : _c.label;
|
|
139
|
-
const handshakeOk = Number(handshakeId) === 0;
|
|
140
|
-
const responseData = (_d = response.data) !== null && _d !== void 0 ? _d : null;
|
|
141
|
-
const batchId = responseData && typeof responseData === 'object'
|
|
142
|
-
? responseData.batch
|
|
143
|
-
: undefined;
|
|
144
|
-
const firstDest = responseData && typeof responseData === 'object'
|
|
145
|
-
? (_e = responseData.destinations) === null || _e === void 0 ? void 0 : _e[0]
|
|
146
|
-
: undefined;
|
|
147
|
-
let errorMsg;
|
|
148
|
-
if (!handshakeOk) {
|
|
149
|
-
if (handshakeLabel) {
|
|
150
|
-
errorMsg = `API Error [code ${handshakeId}]: ${handshakeLabel}`;
|
|
151
|
-
}
|
|
152
|
-
else if (handshakeId !== undefined && handshakeId !== null) {
|
|
153
|
-
errorMsg = `API Error: handshake code=${handshakeId}`;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
errorMsg = `Unexpected API response: ${JSON.stringify(response)}`;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
result = {
|
|
160
|
-
success: handshakeOk,
|
|
161
|
-
messageId: batchId || (firstDest === null || firstDest === void 0 ? void 0 : firstDest.id),
|
|
162
|
-
// On failure, expose the full raw response so callers can inspect it.
|
|
163
|
-
data: handshakeOk ? responseData : response,
|
|
164
|
-
error: errorMsg,
|
|
165
|
-
statusCode
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
catch (error) {
|
|
169
|
-
const httpErr = error;
|
|
170
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
171
|
-
result = {
|
|
172
|
-
success: false,
|
|
173
|
-
error: errorMessage,
|
|
174
|
-
statusCode: httpErr.statusCode,
|
|
175
|
-
// Preserve whatever raw body we got for inspection.
|
|
176
|
-
data: httpErr.rawBody !== undefined ? httpErr.rawBody : null
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
this.log('quickSend result:', JSON.stringify(result));
|
|
180
|
-
if (callback) {
|
|
181
|
-
callback(result);
|
|
182
|
-
}
|
|
183
|
-
return result;
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
getBalance() {
|
|
187
|
-
var _a, _b, _c, _d;
|
|
188
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
189
|
-
this.log('getBalance called');
|
|
190
|
-
const { body: response } = yield this.makeRequest('account/balance');
|
|
191
|
-
return {
|
|
192
|
-
balance: (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.balance) !== null && _b !== void 0 ? _b : 0,
|
|
193
|
-
model: (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.model) !== null && _d !== void 0 ? _d : 'quantity'
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
exports.NestSmsGateway = NestSmsGateway;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { IgatewaySettings, IgatewayParam, ISmsGateway, ISmsGatewayDelegate, QuickSendParamsInput, SendResult } from './types';
|
|
2
|
-
export * from './types';
|
|
3
|
-
export declare class smsPlatform implements ISmsGateway {
|
|
4
|
-
private _settings;
|
|
5
|
-
private _gateway;
|
|
6
|
-
constructor(settings: IgatewaySettings);
|
|
7
|
-
private validateSettings;
|
|
8
|
-
private createGateway;
|
|
9
|
-
init(): ISmsGateway;
|
|
10
|
-
quickSend(param: QuickSendParamsInput, callback?: Function): Promise<SendResult>;
|
|
11
|
-
getGateway(): ISmsGatewayDelegate;
|
|
12
|
-
}
|
|
13
|
-
export { IgatewaySettings, IgatewayParam };
|
package/dist/src/lib/platform.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.smsPlatform = void 0;
|
|
14
|
-
const nest_gateway_1 = require("./nest-gateway");
|
|
15
|
-
const hubtel_gateway_1 = require("./hubtel-gateway");
|
|
16
|
-
const route_gateway_1 = require("./route-gateway");
|
|
17
|
-
const types_1 = require("./types");
|
|
18
|
-
__exportStar(require("./types"), exports);
|
|
19
|
-
const GATEWAY_CONFIGS = {
|
|
20
|
-
route: { requiresUsernamePassword: true },
|
|
21
|
-
hubtel: { requiresClientCredentials: true },
|
|
22
|
-
nest: { requiresApiKey: true }
|
|
23
|
-
};
|
|
24
|
-
class smsPlatform {
|
|
25
|
-
constructor(settings) {
|
|
26
|
-
this.validateSettings(settings);
|
|
27
|
-
this._settings = settings;
|
|
28
|
-
this._gateway = this.createGateway();
|
|
29
|
-
}
|
|
30
|
-
validateSettings(settings) {
|
|
31
|
-
const validPlatforms = ['route', 'hubtel', 'nest'];
|
|
32
|
-
if (!validPlatforms.includes(settings.platformId)) {
|
|
33
|
-
throw new Error(`Invalid platform ID. Supported platforms: ${validPlatforms.join(', ')}`);
|
|
34
|
-
}
|
|
35
|
-
const config = GATEWAY_CONFIGS[settings.platformId];
|
|
36
|
-
const param = settings.param;
|
|
37
|
-
if (config.requiresApiKey && !param.apiKey) {
|
|
38
|
-
throw new Error(`Platform '${settings.platformId}' requires 'apiKey' in param`);
|
|
39
|
-
}
|
|
40
|
-
if (config.requiresClientCredentials && (!param.clientId || !param.clientSecret)) {
|
|
41
|
-
throw new Error(`Platform '${settings.platformId}' requires 'clientId' and 'clientSecret' in param`);
|
|
42
|
-
}
|
|
43
|
-
if (config.requiresUsernamePassword && (!param.username || !param.password)) {
|
|
44
|
-
throw new Error(`Platform '${settings.platformId}' requires 'username' and 'password' in param`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
createGateway() {
|
|
48
|
-
const { platformId, param } = this._settings;
|
|
49
|
-
switch (platformId) {
|
|
50
|
-
case 'route':
|
|
51
|
-
return new route_gateway_1.RouteSmsGateway({
|
|
52
|
-
host: param.host || 'rslr.connectbind.com',
|
|
53
|
-
username: param.username,
|
|
54
|
-
password: param.password,
|
|
55
|
-
protocol: param.protocol || 'http',
|
|
56
|
-
port: param.port || 8080,
|
|
57
|
-
debug: param.debug
|
|
58
|
-
});
|
|
59
|
-
case 'hubtel':
|
|
60
|
-
return new hubtel_gateway_1.HubtelSmsGateway({
|
|
61
|
-
clientId: param.clientId,
|
|
62
|
-
clientSecret: param.clientSecret,
|
|
63
|
-
debug: param.debug
|
|
64
|
-
});
|
|
65
|
-
case 'nest':
|
|
66
|
-
return new nest_gateway_1.NestSmsGateway({
|
|
67
|
-
apiKey: param.apiKey,
|
|
68
|
-
host: param.host,
|
|
69
|
-
protocol: param.protocol,
|
|
70
|
-
debug: param.debug
|
|
71
|
-
});
|
|
72
|
-
default:
|
|
73
|
-
throw new Error(`Unsupported platform: ${platformId}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
init() {
|
|
77
|
-
return this;
|
|
78
|
-
}
|
|
79
|
-
quickSend(param, callback) {
|
|
80
|
-
if (!this._gateway) {
|
|
81
|
-
throw new Error('Gateway not initialized. Call init() first.');
|
|
82
|
-
}
|
|
83
|
-
const normalized = (0, types_1.normalizeQuickSendParams)(param);
|
|
84
|
-
return this._gateway.quickSend(normalized, callback);
|
|
85
|
-
}
|
|
86
|
-
getGateway() {
|
|
87
|
-
return this._gateway;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
exports.smsPlatform = smsPlatform;
|
package/dist/src/lib/types.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeQuickSendParams = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Maps PascalCase or camelCase quick-send fields to {@link QuickSendParams}.
|
|
6
|
-
* PascalCase wins when both are present.
|
|
7
|
-
*/
|
|
8
|
-
function normalizeQuickSendParams(params) {
|
|
9
|
-
var _a, _b, _c, _d;
|
|
10
|
-
const p = params;
|
|
11
|
-
const from = (_a = p.From) !== null && _a !== void 0 ? _a : p.from;
|
|
12
|
-
const to = (_b = p.To) !== null && _b !== void 0 ? _b : p.to;
|
|
13
|
-
const content = (_c = p.Content) !== null && _c !== void 0 ? _c : p.content;
|
|
14
|
-
const type = (_d = p.Type) !== null && _d !== void 0 ? _d : p.type;
|
|
15
|
-
const contentStr = content == null ? '' : String(content);
|
|
16
|
-
const trimmedBody = contentStr.trim();
|
|
17
|
-
if (trimmedBody === '') {
|
|
18
|
-
throw new Error('quickSend: message body is missing. Pass Content or content with a non-empty string.');
|
|
19
|
-
}
|
|
20
|
-
const fromStr = from == null ? '' : String(from).trim();
|
|
21
|
-
if (fromStr === '') {
|
|
22
|
-
throw new Error('quickSend: sender is missing. Pass From or from with a non-empty string.');
|
|
23
|
-
}
|
|
24
|
-
if (to === null || to === undefined) {
|
|
25
|
-
throw new Error('quickSend: recipient is missing. Pass To or to.');
|
|
26
|
-
}
|
|
27
|
-
const toVal = typeof to === 'number' ? to : String(to).trim();
|
|
28
|
-
let typeNum;
|
|
29
|
-
if (type !== undefined && type !== null) {
|
|
30
|
-
const n = Number(type);
|
|
31
|
-
if (!Number.isNaN(n)) {
|
|
32
|
-
typeNum = n;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
From: fromStr,
|
|
37
|
-
To: toVal,
|
|
38
|
-
Content: trimmedBody,
|
|
39
|
-
Type: typeNum
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
exports.normalizeQuickSendParams = normalizeQuickSendParams;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|