diff --git a/CHANGELOG.md b/CHANGELOG.md index efb4ea4..41022e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [5.1.0] - 2020-04-07 + +### Changed + +- Added delivery status callback options to sendEmail and sendSms calls + ## [5.0.3] - 2019-12-19 ### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c8f1ab..78831c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,6 @@ export API_SENDING_KEY="API_whitelist_key for sending a SMS to a receiving numbe export INBOUND_SMS_QUERY_KEY="API_test_key to get received text messages - leave blank for local development as cannot test locally" ``` - To run the integration tests: `make integration-test` diff --git a/README.md b/README.md index 774580f..f7c70ec 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,14 @@ If you omit this argument your default sms sender will be set for the notificati Example usage with optional reference - +##### `statusCallbackUrl` + +Optional. Specifies the identifier of the HTTPS URL for delivery status updates to be sent to. + +##### `statusCallbackBearerToken` + +Optional. Specifies the identifier of the Bearer token that will be used for authentication to the delivery status callback URL. This must be provided if the status callback URL is provided. + ### Email @@ -257,6 +265,14 @@ personalisation = { Optional. Specifies the identifier of the email reply-to address to set for the notification. The identifiers are found in your service Settings, when you 'Manage' your 'Email reply to addresses'. If you omit this argument your default email reply-to address will be set for the notification. +##### `statusCallbackUrl` + +Optional. Specifies the identifier of the HTTPS URL for delivery status updates to be sent to. + +##### `statusCallbackBearerToken` + +Optional. Specifies the identifier of the Bearer token that will be used for authentication to the delivery status callback URL. This must be provided if the status callback URL is provided. + ### Send a document by email diff --git a/package.json b/package.json index 1f816cc..61c20ac 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@govau-platforms/notify-client", "author": "Digital Transformation Agency", - "version": "5.0.3", + "version": "5.1.0", "homepage": "https://github.com/govau/notify-client-node", "description": "Notify.gov.au Node.js client ", "license": "MIT", diff --git a/spec/client.ts b/spec/client.ts index 35f5245..9d7b9e5 100644 --- a/spec/client.ts +++ b/spec/client.ts @@ -88,6 +88,33 @@ describe("notification api", () => { }); }); + it("should send an email with status callback url and bearer token", () => { + let email = "dom@example.com", + templateId = "123", + options = { + personalisation: { foo: "bar" }, + statusCallbackUrl: "https://localhost/callback", + statusCallbackBearerToken: "1234567890" + }, + data = { + template_id: templateId, + email_address: email, + personalisation: options.personalisation, + status_callback_url: options.statusCallbackUrl, + status_callback_bearer_token: options.statusCallbackBearerToken + }; + + notifyAuthNock + .post("/v2/notifications/email", data) + .reply(200, { hooray: "bkbbk" }); + + return notifyClient + .sendEmail(templateId, email, options) + .then(response => { + expect(response.statusCode).to.equal(200); + }); + }); + it("should reject options dicts with unknown options", () => { let email = "foo@bar.com", templateId = "123", @@ -154,6 +181,33 @@ describe("notification api", () => { }); }); + it("should send an sms with status callback url and bearer token", () => { + let phoneNo = "07525755555", + templateId = "123", + options = { + personalisation: { foo: "bar" }, + statusCallbackUrl: "https://localhost/callback", + statusCallbackBearerToken: "1234567890" + }, + data = { + template_id: templateId, + phone_number: phoneNo, + personalisation: options.personalisation, + status_callback_url: options.statusCallbackUrl, + status_callback_bearer_token: options.statusCallbackBearerToken + }; + + notifyAuthNock + .post("/v2/notifications/sms", data) + .reply(200, { hooray: "bkbbk" }); + + return notifyClient + .sendSms(templateId, phoneNo, options) + .then(function(response) { + expect(response.statusCode).to.equal(200); + }); + }); + it("should reject options dicts with unknown options", () => { let phoneNumber = "07123456789", templateId = "123", diff --git a/spec/integration/test.ts b/spec/integration/test.ts index 48bbe7c..1b8495b 100644 --- a/spec/integration/test.ts +++ b/spec/integration/test.ts @@ -24,6 +24,8 @@ describer("notification api with a live service", function() { let smsNotificationId; const personalisation = { name: "Foo" }; const clientRef = "client-ref"; + const statusCallbackUrl = "https://localhost/callback"; + const statusCallbackBearerToken = "1234567890"; const email = process.env.FUNCTIONAL_TEST_EMAIL; const phoneNumber = process.env.FUNCTIONAL_TEST_NUMBER; const smsTemplateId = process.env.SMS_TEMPLATE_ID; @@ -98,9 +100,38 @@ describer("notification api with a live service", function() { }); }); + it("send email notification with status callback URL and bearer token", () => { + const postEmailNotificationResponseJson = require("./schemas/v2/POST_notification_email_response.json"); + const options = { + personalisation: personalisation, + reference: clientRef, + statusCallbackUrl: statusCallbackUrl, + statusCallbackBearerToken: statusCallbackBearerToken + }; + + return notifyClient + .sendEmail(emailTemplateId, email, options) + .then(response => { + response.statusCode.should.equal(201); + expect(response.body).to.be.jsonSchema( + postEmailNotificationResponseJson + ); + response.body.content.body.should.equal( + "Hello Foo\n\nFunctional test help make our world a better place\n" + ); + response.body.content.subject.should.equal("NodeJS integration test"); + response.body.reference.should.equal(clientRef); + emailNotificationId = response.body.id; + }); + }); + it("send sms notification", () => { var postSmsNotificationResponseJson = require("./schemas/v2/POST_notification_sms_response.json"), - options = { personalisation: personalisation }; + options = { + personalisation: personalisation, + statusCallbackUrl: statusCallbackUrl, + statusCallbackBearerToken: statusCallbackBearerToken + }; return notifyClient .sendSms(smsTemplateId, phoneNumber, options) @@ -139,6 +170,24 @@ describer("notification api with a live service", function() { }); }); + it("send sms notification with status callback URL and bearer token", () => { + var postSmsNotificationResponseJson = require("./schemas/v2/POST_notification_sms_response.json"), + options = { personalisation: personalisation }; + + return notifyClient + .sendSms(smsTemplateId, phoneNumber, options) + .then(response => { + response.statusCode.should.equal(201); + expect(response.body).to.be.jsonSchema( + postSmsNotificationResponseJson + ); + response.body.content.body.should.equal( + "Hello Foo\n\nFunctional Tests make our world a better place" + ); + smsNotificationId = response.body.id; + }); + }); + const getNotificationJson = require("./schemas/v2/GET_notification_response.json"); const getNotificationsJson = require("./schemas/v2/GET_notifications_response.json"); diff --git a/src/client.ts b/src/client.ts index 692701b..bd455b4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -15,15 +15,25 @@ export default class Client { ): any { options = options || {}; const err = checkOptionsKeys( - ["personalisation", "reference", "emailReplyToId"], + [ + "personalisation", + "reference", + "emailReplyToId", + "statusCallbackUrl", + "statusCallbackBearerToken" + ], options ); if (err) { return Promise.reject(err); } + const personalisation = options.personalisation || undefined; const reference = options.reference || undefined; const emailReplyToId = options.emailReplyToId || undefined; + const statusCallbackUrl = options.statusCallbackUrl || undefined; + const statusCallbackBearerToken = + options.statusCallbackBearerToken || undefined; return this.httpClient.post( "/v2/notifications/email", @@ -33,7 +43,9 @@ export default class Client { emailAddress, personalisation, reference, - emailReplyToId + emailReplyToId, + statusCallbackUrl, + statusCallbackBearerToken ) ); } @@ -41,7 +53,13 @@ export default class Client { public sendSms(templateId: string, phoneNumber: string, options?: any): any { options = options || {}; const err = checkOptionsKeys( - ["personalisation", "reference", "smsSenderId"], + [ + "personalisation", + "reference", + "smsSenderId", + "statusCallbackUrl", + "statusCallbackBearerToken" + ], options ); if (err) { @@ -51,6 +69,9 @@ export default class Client { const personalisation = options.personalisation || undefined; const reference = options.reference || undefined; const smsSenderId = options.smsSenderId || undefined; + const statusCallbackUrl = options.statusCallbackUrl || undefined; + const statusCallbackBearerToken = + options.statusCallbackBearerToken || undefined; return this.httpClient.post( "/v2/notifications/sms", @@ -60,7 +81,9 @@ export default class Client { phoneNumber, personalisation, reference, - smsSenderId + smsSenderId, + statusCallbackUrl, + statusCallbackBearerToken ) ); } @@ -142,7 +165,9 @@ const createPayload = ( to: string, personalisation?: object, reference?: string, - replyToId?: string + replyToId?: string, + statusCallbackUrl?: string, + statusCallbackBearerToken?: string ) => { const payload: { template_id: string; @@ -152,6 +177,8 @@ const createPayload = ( reference?: string; email_reply_to_id?: string; sms_sender_id?: string; + status_callback_url?: string; + status_callback_bearer_token?: string; } = { template_id: templateId }; if (type == "email") { @@ -174,6 +201,14 @@ const createPayload = ( payload.sms_sender_id = replyToId; } + if (statusCallbackUrl) { + payload.status_callback_url = statusCallbackUrl; + } + + if (statusCallbackBearerToken) { + payload.status_callback_bearer_token = statusCallbackBearerToken; + } + return payload; };