notifications-node-client 8.2.1 → 8.3.0
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/.dockerignore +1 -0
- package/CHANGELOG.md +5 -0
- package/Dockerfile +3 -0
- package/Makefile +1 -0
- package/client/api_client.js +60 -67
- package/client/notification.js +289 -265
- package/package.json +8 -3
- package/spec/integration/test.js +2 -2
- package/spec/types-test.ts +153 -0
- package/tsconfig.json +18 -0
package/.dockerignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
**/.git/*
|
package/CHANGELOG.md
CHANGED
package/Dockerfile
CHANGED
|
@@ -6,9 +6,12 @@ RUN \
|
|
|
6
6
|
echo "Install base packages" \
|
|
7
7
|
&& apt-get update \
|
|
8
8
|
&& apt-get install -y --no-install-recommends \
|
|
9
|
+
awscli \
|
|
9
10
|
make \
|
|
10
11
|
gnupg \
|
|
12
|
+
jq \
|
|
11
13
|
&& echo "Clean up" \
|
|
12
14
|
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
|
13
15
|
|
|
14
16
|
WORKDIR /var/project
|
|
17
|
+
COPY . .
|
package/Makefile
CHANGED
package/client/api_client.js
CHANGED
|
@@ -4,13 +4,12 @@ var defaultRestClient = require('axios').default,
|
|
|
4
4
|
version = require('../package.json').version;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @param apiKeyId
|
|
10
|
-
*
|
|
7
|
+
* @param {string} apiKeyOrUrl - API key (1 arg), or base URL (2-3 args)
|
|
8
|
+
* @param {string} [serviceIdOrApiKey] - API key (2 args), or service ID (3 args)
|
|
9
|
+
* @param {string} [apiKeyId] - API key (3 args)
|
|
11
10
|
* @constructor
|
|
12
11
|
*/
|
|
13
|
-
function ApiClient() {
|
|
12
|
+
function ApiClient(apiKeyOrUrl, serviceIdOrApiKey, apiKeyId) {
|
|
14
13
|
|
|
15
14
|
this.proxy = null;
|
|
16
15
|
this.restClient = defaultRestClient;
|
|
@@ -56,67 +55,61 @@ function createToken(requestMethod, requestPath, apiKeyId, serviceId) {
|
|
|
56
55
|
return createGovukNotifyToken(requestMethod, requestPath, apiKeyId, serviceId);
|
|
57
56
|
}
|
|
58
57
|
|
|
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
|
-
* @param {object} an axios instance
|
|
116
|
-
*/
|
|
117
|
-
setClient: function(restClient){
|
|
118
|
-
this.restClient = restClient;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
58
|
+
/**
|
|
59
|
+
* @param {string} path
|
|
60
|
+
* @param {import('axios').AxiosRequestConfig} [additionalOptions]
|
|
61
|
+
* @returns {Promise<import('axios').AxiosResponse>}
|
|
62
|
+
*/
|
|
63
|
+
ApiClient.prototype.get = function(path, additionalOptions) {
|
|
64
|
+
var options = {
|
|
65
|
+
method: 'get',
|
|
66
|
+
url: this.urlBase + path,
|
|
67
|
+
headers: {
|
|
68
|
+
'Authorization': 'Bearer ' + createToken('GET', path, this.apiKeyId, this.serviceId),
|
|
69
|
+
'User-Agent': 'NOTIFY-API-NODE-CLIENT/' + version
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
Object.assign(options, additionalOptions)
|
|
73
|
+
if(this.proxy !== null) options.proxy = this.proxy;
|
|
74
|
+
|
|
75
|
+
return this.restClient(options);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {string} path
|
|
80
|
+
* @param {object} data
|
|
81
|
+
* @returns {Promise<import('axios').AxiosResponse>}
|
|
82
|
+
*/
|
|
83
|
+
ApiClient.prototype.post = function(path, data){
|
|
84
|
+
var options = {
|
|
85
|
+
method: 'post',
|
|
86
|
+
url: this.urlBase + path,
|
|
87
|
+
data: data,
|
|
88
|
+
headers: {
|
|
89
|
+
'Authorization': 'Bearer ' + createToken('GET', path, this.apiKeyId, this.serviceId),
|
|
90
|
+
'User-Agent': 'NOTIFY-API-NODE-CLIENT/' + version
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
if(this.proxy !== null) options.proxy = this.proxy;
|
|
95
|
+
|
|
96
|
+
return this.restClient(options);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {import('axios').AxiosProxyConfig} proxyConfig
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
ApiClient.prototype.setProxy = function(proxyConfig){
|
|
104
|
+
this.proxy = proxyConfig
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param {import('axios').AxiosInstance} restClient
|
|
109
|
+
* @returns {void}
|
|
110
|
+
*/
|
|
111
|
+
ApiClient.prototype.setClient = function(restClient){
|
|
112
|
+
this.restClient = restClient;
|
|
113
|
+
};
|
|
121
114
|
|
|
122
115
|
module.exports = ApiClient;
|
package/client/notification.js
CHANGED
|
@@ -1,14 +1,72 @@
|
|
|
1
1
|
var ApiClient = require('./api_client');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
4
|
+
* @typedef {"sms" | "letter" | "email"} NotificationType
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {"first" | "second" | "economy" | "europe" | "rest-of-world"} PostageType
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} TemplateRef
|
|
13
|
+
* @property {string} id
|
|
14
|
+
* @property {number} version
|
|
15
|
+
* @property {string} uri
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object} NotificationResponse
|
|
20
|
+
* @property {string} id
|
|
21
|
+
* @property {string} [reference]
|
|
22
|
+
* @property {NotificationType} type
|
|
23
|
+
* @property {string} status
|
|
24
|
+
* @property {{id: string, name: string, version: number}} template
|
|
25
|
+
* @property {string} body
|
|
26
|
+
* @property {string} created_at
|
|
27
|
+
* @property {string} [created_by_name]
|
|
28
|
+
* @property {string} [sent_at]
|
|
29
|
+
* @property {string} [completed_at]
|
|
30
|
+
* @property {string} [scheduled_for]
|
|
31
|
+
* @property {string} [one_click_unsubscribe]
|
|
32
|
+
* @property {boolean} is_cost_data_ready
|
|
33
|
+
* @property {number} [cost_in_pounds]
|
|
34
|
+
* @property {{billable_sheets_of_paper?: number, postage?: string} | {billable_sms_fragments?: number, international_rate_multiplier?: number, sms_rate?: number}} [cost_details]
|
|
35
|
+
* @property {string} [email_address]
|
|
36
|
+
* @property {string} [phone_number]
|
|
37
|
+
* @property {string} [subject]
|
|
38
|
+
* @property {string} [line_1]
|
|
39
|
+
* @property {string} [line_2]
|
|
40
|
+
* @property {string} [line_3]
|
|
41
|
+
* @property {string} [line_4]
|
|
42
|
+
* @property {string} [line_5]
|
|
43
|
+
* @property {string} [line_6]
|
|
44
|
+
* @property {string} [line_7]
|
|
45
|
+
* @property {PostageType} [postage]
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @typedef {Object} TemplateData
|
|
50
|
+
* @property {string} id
|
|
51
|
+
* @property {string} name
|
|
52
|
+
* @property {NotificationType} type
|
|
53
|
+
* @property {string} created_at
|
|
54
|
+
* @property {string | null} updated_at
|
|
55
|
+
* @property {string} created_by
|
|
56
|
+
* @property {number} version
|
|
57
|
+
* @property {string} body
|
|
58
|
+
* @property {string} [subject]
|
|
59
|
+
* @property {string} [letter_contact_block]
|
|
60
|
+
* @property {PostageType} [postage]
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @param {string} apiKeyOrUrl - API key (1 arg), or base URL (2-3 args)
|
|
65
|
+
* @param {string} [serviceIdOrApiKey] - API key (2 args), or service ID (3 args)
|
|
66
|
+
* @param {string} [apiKeyId] - API key (3 args)
|
|
9
67
|
* @constructor
|
|
10
68
|
*/
|
|
11
|
-
function NotifyClient() {
|
|
69
|
+
function NotifyClient(apiKeyOrUrl, serviceIdOrApiKey, apiKeyId) {
|
|
12
70
|
this.apiClient = new (Function.prototype.bind.apply(
|
|
13
71
|
ApiClient,
|
|
14
72
|
[null].concat(Array.prototype.slice.call(arguments))
|
|
@@ -126,265 +184,231 @@ function _check_and_encode_file(file, size_limit) {
|
|
|
126
184
|
return file.toString('base64')
|
|
127
185
|
}
|
|
128
186
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
*
|
|
357
|
-
* @param {object} an axios instance
|
|
358
|
-
*/
|
|
359
|
-
setClient: function(client) {
|
|
360
|
-
this.apiClient.setClient(client);
|
|
361
|
-
},
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
*
|
|
365
|
-
* @param {Buffer} fileData
|
|
366
|
-
* @param {object} options
|
|
367
|
-
*
|
|
368
|
-
* @returns {Dictionary}
|
|
369
|
-
*/
|
|
370
|
-
prepareUpload: function(fileData, options) {
|
|
371
|
-
let data = {
|
|
372
|
-
file: _check_and_encode_file(fileData, 2),
|
|
373
|
-
filename: null,
|
|
374
|
-
confirm_email_before_download: null,
|
|
375
|
-
retention_period: null,
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (options !== undefined) {
|
|
379
|
-
data.filename = options.filename || null;
|
|
380
|
-
data.confirm_email_before_download = options.confirmEmailBeforeDownload !== undefined ? options.confirmEmailBeforeDownload : null;
|
|
381
|
-
data.retention_period = options.retentionPeriod || null;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return data;
|
|
385
|
-
},
|
|
386
|
-
|
|
387
|
-
});
|
|
187
|
+
/**
|
|
188
|
+
* @param {string} templateId
|
|
189
|
+
* @param {string} emailAddress
|
|
190
|
+
* @param {{personalisation?: Object, reference?: string, emailReplyToId?: string, oneClickUnsubscribeURL?: string}} [options]
|
|
191
|
+
* @returns {Promise<import('axios').AxiosResponse<{id: string, reference?: string, content: {body: string, subject: string, from_email: string, one_click_unsubscribe_url?: string}, uri: string, template: TemplateRef}>>}
|
|
192
|
+
*/
|
|
193
|
+
NotifyClient.prototype.sendEmail = function (templateId, emailAddress, options) {
|
|
194
|
+
options = options || {};
|
|
195
|
+
var err = checkOptionsKeys(['personalisation', 'reference', 'emailReplyToId', 'oneClickUnsubscribeURL'], options)
|
|
196
|
+
if (err) {
|
|
197
|
+
return Promise.reject(err);
|
|
198
|
+
}
|
|
199
|
+
var personalisation = options.personalisation || undefined,
|
|
200
|
+
reference = options.reference || undefined,
|
|
201
|
+
emailReplyToId = options.emailReplyToId || undefined,
|
|
202
|
+
oneClickUnsubscribeURL = options.oneClickUnsubscribeURL || undefined;
|
|
203
|
+
|
|
204
|
+
return this.apiClient.post('/v2/notifications/email',
|
|
205
|
+
createNotificationPayload('email', templateId, emailAddress, personalisation, reference, emailReplyToId, oneClickUnsubscribeURL));
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @param {string} templateId
|
|
210
|
+
* @param {string} phoneNumber
|
|
211
|
+
* @param {{personalisation?: Object, reference?: string, smsSenderId?: string}} [options]
|
|
212
|
+
* @returns {Promise<import('axios').AxiosResponse<{id: string, reference?: string, content: {body: string, from_number: string}, uri: string, template: TemplateRef}>>}
|
|
213
|
+
*/
|
|
214
|
+
NotifyClient.prototype.sendSms = function (templateId, phoneNumber, options) {
|
|
215
|
+
options = options || {};
|
|
216
|
+
var err = checkOptionsKeys(['personalisation', 'reference', 'smsSenderId'], options)
|
|
217
|
+
if (err) {
|
|
218
|
+
return Promise.reject(err);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
var personalisation = options.personalisation || undefined;
|
|
222
|
+
var reference = options.reference || undefined;
|
|
223
|
+
var smsSenderId = options.smsSenderId || undefined;
|
|
224
|
+
|
|
225
|
+
return this.apiClient.post('/v2/notifications/sms',
|
|
226
|
+
createNotificationPayload('sms', templateId, phoneNumber, personalisation, reference, smsSenderId));
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @param {string} templateId
|
|
231
|
+
* @param {{personalisation?: Object, reference?: string}} [options]
|
|
232
|
+
* @returns {Promise<import('axios').AxiosResponse<{id: string, reference?: string, content: {body: string, subject: string}, uri: string, template: TemplateRef, scheduled_for: string | null}>>}
|
|
233
|
+
*/
|
|
234
|
+
NotifyClient.prototype.sendLetter = function (templateId, options) {
|
|
235
|
+
options = options || {};
|
|
236
|
+
var err = checkOptionsKeys(['personalisation', 'reference'], options)
|
|
237
|
+
if (err) {
|
|
238
|
+
return Promise.reject(err);
|
|
239
|
+
}
|
|
240
|
+
var personalisation = options.personalisation || undefined;
|
|
241
|
+
var reference = options.reference || undefined;
|
|
242
|
+
|
|
243
|
+
return this.apiClient.post('/v2/notifications/letter',
|
|
244
|
+
createNotificationPayload('letter', templateId, undefined, personalisation, reference));
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @param {string} reference
|
|
249
|
+
* @param {Buffer | string} pdf_file
|
|
250
|
+
* @param {"first" | "second" | "economy" | "europe" | "rest-of-world"} [postage]
|
|
251
|
+
* @returns {Promise<import('axios').AxiosResponse<{id: string, reference: string, postage: PostageType}>>}
|
|
252
|
+
*/
|
|
253
|
+
NotifyClient.prototype.sendPrecompiledLetter = function(reference, pdf_file, postage) {
|
|
254
|
+
var postage = postage || undefined
|
|
255
|
+
var content = _check_and_encode_file(pdf_file, 5)
|
|
256
|
+
var notification = {
|
|
257
|
+
"reference": reference,
|
|
258
|
+
"content": content
|
|
259
|
+
}
|
|
260
|
+
if (postage != undefined) {
|
|
261
|
+
notification["postage"] = postage
|
|
262
|
+
}
|
|
263
|
+
return this.apiClient.post('/v2/notifications/letter', notification);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* @param {string} notificationId
|
|
268
|
+
* @returns {Promise<import('axios').AxiosResponse<NotificationResponse>>}
|
|
269
|
+
*/
|
|
270
|
+
NotifyClient.prototype.getNotificationById = function(notificationId) {
|
|
271
|
+
return this.apiClient.get('/v2/notifications/' + notificationId);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* @param {string} [templateType]
|
|
276
|
+
* @param {string} [status]
|
|
277
|
+
* @param {string} [reference]
|
|
278
|
+
* @param {string} [olderThanId]
|
|
279
|
+
* @returns {Promise<import('axios').AxiosResponse<{notifications: NotificationResponse[], links: {current: string, next: string}}>>}
|
|
280
|
+
*/
|
|
281
|
+
NotifyClient.prototype.getNotifications = function(templateType, status, reference, olderThanId) {
|
|
282
|
+
return this.apiClient.get('/v2/notifications' + buildGetAllNotificationsQuery(templateType, status, reference, olderThanId));
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @param {string} notificationId
|
|
287
|
+
* @returns {Promise<Buffer>}
|
|
288
|
+
*/
|
|
289
|
+
NotifyClient.prototype.getPdfForLetterNotification = function(notificationId) {
|
|
290
|
+
const url = '/v2/notifications/' + notificationId + '/pdf'
|
|
291
|
+
|
|
292
|
+
// Unlike other requests, we expect a successful response as an arraybuffer and an error as JSON
|
|
293
|
+
// Axios does not support flexible response types so we will need to handle the error case ourselves below
|
|
294
|
+
return this.apiClient.get(url, { responseType: 'arraybuffer' })
|
|
295
|
+
.then(function(response) {
|
|
296
|
+
var pdf = Buffer.from(response.data, "base64")
|
|
297
|
+
return pdf
|
|
298
|
+
})
|
|
299
|
+
.catch(function(error) {
|
|
300
|
+
// If we receive an error, as the response is an arraybuffer rather than our usual JSON
|
|
301
|
+
// we need to convert it to JSON to be read by the user
|
|
302
|
+
string_of_error_body = new TextDecoder().decode(error.response.data);
|
|
303
|
+
|
|
304
|
+
// Then we replace the error data with the JSON error rather than the arraybuffer of the error
|
|
305
|
+
error.response.data = JSON.parse(string_of_error_body);
|
|
306
|
+
|
|
307
|
+
// and rethrow to let the user handle the error
|
|
308
|
+
throw error
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* @param {string} templateId
|
|
314
|
+
* @returns {Promise<import('axios').AxiosResponse<TemplateData>>}
|
|
315
|
+
*/
|
|
316
|
+
NotifyClient.prototype.getTemplateById = function(templateId) {
|
|
317
|
+
return this.apiClient.get('/v2/template/' + templateId);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* @param {string} templateId
|
|
322
|
+
* @param {number} version
|
|
323
|
+
* @returns {Promise<import('axios').AxiosResponse<TemplateData>>}
|
|
324
|
+
*/
|
|
325
|
+
NotifyClient.prototype.getTemplateByIdAndVersion = function(templateId, version) {
|
|
326
|
+
return this.apiClient.get('/v2/template/' + templateId + '/version/' + version);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @param {NotificationType} [templateType]
|
|
331
|
+
* @returns {Promise<import('axios').AxiosResponse<{templates: TemplateData[]}>>}
|
|
332
|
+
*/
|
|
333
|
+
NotifyClient.prototype.getAllTemplates = function(templateType) {
|
|
334
|
+
let templateQuery = ''
|
|
335
|
+
|
|
336
|
+
if (templateType) {
|
|
337
|
+
templateQuery = '?type=' + templateType;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return this.apiClient.get('/v2/templates' + templateQuery);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @param {string} templateId
|
|
345
|
+
* @param {Object} [personalisation]
|
|
346
|
+
* @returns {Promise<import('axios').AxiosResponse<{id: string, type: NotificationType, version: number, body: string, html?: string, subject?: string, postage?: PostageType}>>}
|
|
347
|
+
*/
|
|
348
|
+
NotifyClient.prototype.previewTemplateById = function(templateId, personalisation) {
|
|
349
|
+
|
|
350
|
+
let payload = {}
|
|
351
|
+
|
|
352
|
+
if (personalisation) {
|
|
353
|
+
payload.personalisation = personalisation;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return this.apiClient.post('/v2/template/' + templateId + '/preview', payload);
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @param {string} [olderThan]
|
|
361
|
+
* @returns {Promise<import('axios').AxiosResponse<{received_text_messages: Array<{id: string, user_number: string, notify_number: string, created_at: string, service_id: string, content: string}>, links: {current: string, next: string}}>>}
|
|
362
|
+
*/
|
|
363
|
+
NotifyClient.prototype.getReceivedTexts = function(olderThan){
|
|
364
|
+
let queryString;
|
|
365
|
+
|
|
366
|
+
if (olderThan) {
|
|
367
|
+
queryString = '?older_than=' + olderThan;
|
|
368
|
+
} else {
|
|
369
|
+
queryString = '';
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return this.apiClient.get('/v2/received-text-messages' + queryString);
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* @param {import('axios').AxiosProxyConfig} proxyConfig
|
|
377
|
+
* @returns {void}
|
|
378
|
+
*/
|
|
379
|
+
NotifyClient.prototype.setProxy = function(proxyConfig) {
|
|
380
|
+
this.apiClient.setProxy(proxyConfig);
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @param {import('axios').AxiosInstance} client
|
|
385
|
+
* @returns {void}
|
|
386
|
+
*/
|
|
387
|
+
NotifyClient.prototype.setClient = function(client) {
|
|
388
|
+
this.apiClient.setClient(client);
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* @param {Buffer | string} fileData
|
|
393
|
+
* @param {{filename?: string, confirmEmailBeforeDownload?: boolean, retentionPeriod?: string}} [options]
|
|
394
|
+
* @returns {{file: string, filename: string | null, confirm_email_before_download: boolean | null, retention_period: string | null}}
|
|
395
|
+
*/
|
|
396
|
+
NotifyClient.prototype.prepareUpload = function(fileData, options) {
|
|
397
|
+
let data = {
|
|
398
|
+
file: _check_and_encode_file(fileData, 2),
|
|
399
|
+
filename: null,
|
|
400
|
+
confirm_email_before_download: null,
|
|
401
|
+
retention_period: null,
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (options !== undefined) {
|
|
405
|
+
data.filename = options.filename || null;
|
|
406
|
+
data.confirm_email_before_download = options.confirmEmailBeforeDownload !== undefined ? options.confirmEmailBeforeDownload : null;
|
|
407
|
+
data.retention_period = options.retentionPeriod || null;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return data;
|
|
411
|
+
};
|
|
388
412
|
|
|
389
413
|
module.exports = {
|
|
390
414
|
NotifyClient: NotifyClient
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notifications-node-client",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"homepage": "https://docs.notifications.service.gov.uk/node.html",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"description": "GOV.UK Notify Node.js client ",
|
|
10
10
|
"main": "index.js",
|
|
11
|
+
"types": "types/index.d.ts",
|
|
11
12
|
"scripts": {
|
|
12
13
|
"test": "mocha \"spec/**/*.js\" && npm run test:markdown:standard",
|
|
13
14
|
"test:markdown:standard": "standard-markdown DOCUMENTATION.md",
|
|
14
|
-
"integration": "mocha spec/integration/test.js"
|
|
15
|
+
"integration": "mocha spec/integration/test.js",
|
|
16
|
+
"build:types": "tsc",
|
|
17
|
+
"check:types": "tsc --noEmit"
|
|
15
18
|
},
|
|
16
19
|
"engines": {
|
|
17
20
|
"npm": ">=6.14.13",
|
|
@@ -24,6 +27,7 @@
|
|
|
24
27
|
"jsonwebtoken": "^9.0.2"
|
|
25
28
|
},
|
|
26
29
|
"devDependencies": {
|
|
30
|
+
"@types/node": "^25.3.0",
|
|
27
31
|
"chai": "4.3.4",
|
|
28
32
|
"chai-as-promised": "7.1.1",
|
|
29
33
|
"chai-bytes": "0.1.2",
|
|
@@ -34,6 +38,7 @@
|
|
|
34
38
|
"nock": "9.2.6",
|
|
35
39
|
"optimist": "0.6.1",
|
|
36
40
|
"sinon": "^18.0.0",
|
|
37
|
-
"standard-markdown": "7.1.0"
|
|
41
|
+
"standard-markdown": "7.1.0",
|
|
42
|
+
"typescript": "^5.9.0"
|
|
38
43
|
}
|
|
39
44
|
}
|
package/spec/integration/test.js
CHANGED
|
@@ -27,7 +27,7 @@ function make_random_id() {
|
|
|
27
27
|
|
|
28
28
|
describer('notification api with a live service', function () {
|
|
29
29
|
// default is 2000 (ms) - api is sometimes slower than this :(
|
|
30
|
-
this.timeout(
|
|
30
|
+
this.timeout(120000)
|
|
31
31
|
|
|
32
32
|
let notifyClient;
|
|
33
33
|
let teamNotifyClient;
|
|
@@ -247,7 +247,7 @@ describer('notification api with a live service', function () {
|
|
|
247
247
|
}
|
|
248
248
|
if (err.response.data && (err.response.data.errors[0].error === "PDFNotReadyError")) {
|
|
249
249
|
count += 1
|
|
250
|
-
if (count <
|
|
250
|
+
if (count < 24) {
|
|
251
251
|
setTimeout(tryClient, 5000)
|
|
252
252
|
} else {
|
|
253
253
|
done(new Error('Too many PDFNotReadyError errors'));
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// This file is compiled with tsc --noEmit to verify the generated types work correctly.
|
|
2
|
+
// It is NOT run as a test - it only needs to type-check.
|
|
3
|
+
|
|
4
|
+
import { NotifyClient } from '..';
|
|
5
|
+
|
|
6
|
+
// Constructor overloads
|
|
7
|
+
const client1 = new NotifyClient('apiKeyId');
|
|
8
|
+
const client2 = new NotifyClient('https://example.com', 'apiKeyId');
|
|
9
|
+
const client3 = new NotifyClient('https://example.com', 'serviceId', 'apiKeyId');
|
|
10
|
+
|
|
11
|
+
// sendEmail
|
|
12
|
+
async function testSendEmail() {
|
|
13
|
+
const response = await client1.sendEmail('template-id', 'test@example.com', {
|
|
14
|
+
personalisation: { name: 'Test' },
|
|
15
|
+
reference: 'ref-123',
|
|
16
|
+
emailReplyToId: 'reply-to-id',
|
|
17
|
+
oneClickUnsubscribeURL: 'https://example.com/unsub',
|
|
18
|
+
});
|
|
19
|
+
const id: string = response.data.id;
|
|
20
|
+
const subject: string = response.data.content.subject;
|
|
21
|
+
const fromEmail: string = response.data.content.from_email;
|
|
22
|
+
const unsubUrl: string | undefined = response.data.content.one_click_unsubscribe_url;
|
|
23
|
+
const templateId: string = response.data.template.id;
|
|
24
|
+
const templateVersion: number = response.data.template.version;
|
|
25
|
+
const templateUri: string = response.data.template.uri;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// sendSms
|
|
29
|
+
async function testSendSms() {
|
|
30
|
+
const response = await client1.sendSms('template-id', '07123456789', {
|
|
31
|
+
personalisation: { code: '1234' },
|
|
32
|
+
reference: 'ref-123',
|
|
33
|
+
smsSenderId: 'sender-id',
|
|
34
|
+
});
|
|
35
|
+
const id: string = response.data.id;
|
|
36
|
+
const body: string = response.data.content.body;
|
|
37
|
+
const fromNumber: string = response.data.content.from_number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// sendLetter
|
|
41
|
+
async function testSendLetter() {
|
|
42
|
+
const response = await client1.sendLetter('template-id', {
|
|
43
|
+
personalisation: { address_line_1: 'Mr Test', address_line_2: '1 Test St', postcode: 'SW1A 1AA' },
|
|
44
|
+
reference: 'ref-123',
|
|
45
|
+
});
|
|
46
|
+
const id: string = response.data.id;
|
|
47
|
+
const scheduledFor: string | null = response.data.scheduled_for;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// sendPrecompiledLetter
|
|
51
|
+
async function testSendPrecompiledLetter() {
|
|
52
|
+
const response = await client1.sendPrecompiledLetter('ref', Buffer.from('pdf'), 'first');
|
|
53
|
+
const id: string = response.data.id;
|
|
54
|
+
const postage: string = response.data.postage;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// getNotificationById
|
|
58
|
+
async function testGetNotificationById() {
|
|
59
|
+
const response = await client1.getNotificationById('notification-id');
|
|
60
|
+
const id: string = response.data.id;
|
|
61
|
+
const type: "sms" | "letter" | "email" = response.data.type;
|
|
62
|
+
const status: string = response.data.status;
|
|
63
|
+
const body: string = response.data.body;
|
|
64
|
+
const createdAt: string = response.data.created_at;
|
|
65
|
+
const isCostDataReady: boolean = response.data.is_cost_data_ready;
|
|
66
|
+
const emailAddress: string | undefined = response.data.email_address;
|
|
67
|
+
const phoneNumber: string | undefined = response.data.phone_number;
|
|
68
|
+
const subject: string | undefined = response.data.subject;
|
|
69
|
+
const createdByName: string | undefined = response.data.created_by_name;
|
|
70
|
+
const sentAt: string | undefined = response.data.sent_at;
|
|
71
|
+
const completedAt: string | undefined = response.data.completed_at;
|
|
72
|
+
const scheduledFor: string | undefined = response.data.scheduled_for;
|
|
73
|
+
const oneClickUnsubscribe: string | undefined = response.data.one_click_unsubscribe;
|
|
74
|
+
const costInPounds: number | undefined = response.data.cost_in_pounds;
|
|
75
|
+
const line1: string | undefined = response.data.line_1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// getNotifications
|
|
79
|
+
async function testGetNotifications() {
|
|
80
|
+
const response = await client1.getNotifications('sms', 'delivered', 'ref', 'older-than-id');
|
|
81
|
+
const notifications = response.data.notifications;
|
|
82
|
+
const firstNotification = notifications[0];
|
|
83
|
+
const type: "sms" | "letter" | "email" = firstNotification.type;
|
|
84
|
+
const links = response.data.links;
|
|
85
|
+
const current: string = links.current;
|
|
86
|
+
const next: string = links.next;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// getPdfForLetterNotification
|
|
90
|
+
async function testGetPdf() {
|
|
91
|
+
const pdf: Buffer = await client1.getPdfForLetterNotification('notification-id');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// getTemplateById
|
|
95
|
+
async function testGetTemplateById() {
|
|
96
|
+
const response = await client1.getTemplateById('template-id');
|
|
97
|
+
const id: string = response.data.id;
|
|
98
|
+
const name: string = response.data.name;
|
|
99
|
+
const type: "sms" | "letter" | "email" = response.data.type;
|
|
100
|
+
const createdAt: string = response.data.created_at;
|
|
101
|
+
const version: number = response.data.version;
|
|
102
|
+
const body: string = response.data.body;
|
|
103
|
+
const letterContactBlock: string | undefined = response.data.letter_contact_block;
|
|
104
|
+
const postage: string | undefined = response.data.postage;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// getTemplateByIdAndVersion
|
|
108
|
+
async function testGetTemplateByIdAndVersion() {
|
|
109
|
+
const response = await client1.getTemplateByIdAndVersion('template-id', 3);
|
|
110
|
+
const id: string = response.data.id;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// getAllTemplates
|
|
114
|
+
async function testGetAllTemplates() {
|
|
115
|
+
const response = await client1.getAllTemplates('email');
|
|
116
|
+
const templates = response.data.templates;
|
|
117
|
+
const first = templates[0];
|
|
118
|
+
const type: "sms" | "letter" | "email" = first.type;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// previewTemplateById
|
|
122
|
+
async function testPreviewTemplateById() {
|
|
123
|
+
const response = await client1.previewTemplateById('template-id', { name: 'Test' });
|
|
124
|
+
const id: string = response.data.id;
|
|
125
|
+
const type: "sms" | "letter" | "email" = response.data.type;
|
|
126
|
+
const body: string = response.data.body;
|
|
127
|
+
const html: string | undefined = response.data.html;
|
|
128
|
+
const postage: "first" | "second" | "economy" | "europe" | "rest-of-world" | undefined = response.data.postage;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// getReceivedTexts
|
|
132
|
+
async function testGetReceivedTexts() {
|
|
133
|
+
const response = await client1.getReceivedTexts('older-than-id');
|
|
134
|
+
const messages = response.data.received_text_messages;
|
|
135
|
+
const first = messages[0];
|
|
136
|
+
const userNumber: string = first.user_number;
|
|
137
|
+
const serviceId: string = first.service_id;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// prepareUpload
|
|
141
|
+
function testPrepareUpload() {
|
|
142
|
+
const result = client1.prepareUpload(Buffer.from('data'), {
|
|
143
|
+
filename: 'test.csv',
|
|
144
|
+
confirmEmailBeforeDownload: true,
|
|
145
|
+
retentionPeriod: '52 weeks',
|
|
146
|
+
});
|
|
147
|
+
const file: string = result.file;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// setProxy
|
|
151
|
+
client1.setProxy({ host: 'proxy.example.com', port: 8080 });
|
|
152
|
+
|
|
153
|
+
// setClient - accepts axios instance
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"checkJs": false,
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"emitDeclarationOnly": true,
|
|
7
|
+
"declarationDir": "types",
|
|
8
|
+
"strict": false,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"moduleResolution": "node",
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"target": "es2015",
|
|
14
|
+
"module": "commonjs"
|
|
15
|
+
},
|
|
16
|
+
"include": ["client/notification.js", "index.js"],
|
|
17
|
+
"exclude": ["node_modules", "spec"]
|
|
18
|
+
}
|