Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEVEXP-516: E2E SMS/Delivery Reports #124

Merged
merged 5 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import { Sms } from '@sinch/sdk-core';

const requestData: Sms.GetDeliveryReportByPhoneNumberRequestData = {
batch_id: batchId,
recipient_msisdn: recipientPhoneNumber,
phone_number: recipientPhoneNumber,
};

const smsService = initSmsServiceWithServicePlanId();
let response;
try {
response = await smsService.deliveryReports.getForNumber(requestData);
} catch (error) {
console.error(`ERROR: Impossible to retrieve the delivery report by batch ID ${requestData.batch_id} for the recipient ${requestData.recipient_msisdn}`);
console.error(`ERROR: Impossible to retrieve the delivery report by batch ID ${requestData.batch_id} for the recipient ${requestData.phone_number}`);
throw error;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/webhooks/src/services/sms-event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class SmsEventService {
}

private handleDeliveryReportEvent(event: Sms.DeliveryReport): void {
console.log(`The batch ${event.batch_id} has the following statuses:\n${event.statuses.map((status) => ' - \'' + status.status + '\' for the recipients: ' + status.recipients.join(', ')).join('\n')} `);
console.log(`The batch ${event.batch_id} has the following statuses:\n${event.statuses.map((status) => ' - \'' + status.status + '\' for the recipients: ' + status.recipients?.join(', ')).join('\n')} `);
}

private handleSmsEvent(event: Sms.MOText): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface MessageDeliveryStatus {
/** The number of messages that currently has this code. */
count: number;
/** Only for `full` report. A list of the phone number recipients which messages has this status code. */
recipients: string[];
recipients?: string[];
/** The simplified status as described in _Delivery Report Statuses_. */
status: DeliveryReportStatusEnum;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface GetDeliveryReportByPhoneNumberRequestData {
/** The batch ID you received from sending a message. */
'batch_id': string;
/** Phone number for which you to want to search. */
'recipient_msisdn': string;
'phone_number': string;
}
export interface ListDeliveryReportsRequestData {
/** The page number starting from 0. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export class DeliveryReportsApi extends SmsDomainApi {
*/
public async get(data: GetDeliveryReportByBatchIdRequestData): Promise<DeliveryReport> {
this.client = this.getSinchClient();
data['type'] = data['type'] !== undefined ? data['type'] : 'summary';
const getParams = this.client.extractQueryParams<GetDeliveryReportByBatchIdRequestData>(
data,
['type', 'status', 'code'],
Expand Down Expand Up @@ -73,7 +72,7 @@ export class DeliveryReportsApi extends SmsDomainApi {
};

const body: RequestBody = '';
const basePathUrl = `${this.client.apiClientOptions.hostname}/xms/v1/${this.client.apiClientOptions.projectId}/batches/${data['batch_id']}/delivery_report/${data['recipient_msisdn']}`;
const basePathUrl = `${this.client.apiClientOptions.hostname}/xms/v1/${this.client.apiClientOptions.projectId}/batches/${data['batch_id']}/delivery_report/${data['phone_number']}`;

const requestOptions
= await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined);
Expand All @@ -95,8 +94,6 @@ export class DeliveryReportsApi extends SmsDomainApi {
*/
public list(data: ListDeliveryReportsRequestData): ApiListPromise<RecipientDeliveryReport> {
this.client = this.getSinchClient();
data['page'] = data['page'] !== undefined ? data['page'] : 0;
data['page_size'] = data['page_size'] !== undefined ? data['page_size'] : 30;
const getParams = this.client.extractQueryParams<ListDeliveryReportsRequestData>(
data,
['page', 'page_size', 'start_date', 'end_date', 'status', 'code', 'client_reference'],
Expand Down
JPPortier marked this conversation as resolved.
Show resolved Hide resolved
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('DeliveryReportsApi', () => {
// Given
const requestData: Sms.GetDeliveryReportByPhoneNumberRequestData = {
batch_id: '01HF28S9AAGRKWP2CY92BJB569',
recipient_msisdn: '+33444555666',
phone_number: '+33444555666',
};
const expectedResponse: Sms.RecipientDeliveryReport = {
batch_id: '01HF28S9AAGRKWP2CY92BJB569',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { DeliveryReportsApi, SmsService, Sms } from '../../../../src';
import { Given, When, Then } from '@cucumber/cucumber';
import * as assert from 'assert';
import { PageResult } from '@sinch/sdk-client';

let deliveryReportsApi: DeliveryReportsApi;
let deliveryReport: Sms.DeliveryReport;
let recipientDeliveryReport: Sms.RecipientDeliveryReport;
let listResponse: PageResult<Sms.RecipientDeliveryReport>;
let recipientDeliveryReportList: Sms.RecipientDeliveryReport[];
let pagesIteration: number;

Given('the SMS service "Delivery Reports" is available', () => {
const smsService = new SmsService({
projectId: 'tinyfrog-jump-high-over-lilypadbasin',
keyId: 'keyId',
keySecret: 'keySecret',
authHostname: 'http://localhost:3011',
smsHostname: 'http://localhost:3017',
});
deliveryReportsApi = smsService.deliveryReports;
});

When('I send a request to retrieve a summary SMS delivery report', async () => {
const requestData: Sms.GetDeliveryReportByBatchIdRequestData = {
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
};
deliveryReport = await deliveryReportsApi.get(requestData);
});

Then('the response contains a summary SMS delivery report', () => {
assert.equal(deliveryReport.batch_id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.equal(deliveryReport.client_reference, 'reference_e2e');
assert.ok(deliveryReport.statuses);
let status = deliveryReport.statuses[0];
assert.equal(status.code, 15);
assert.equal(status.count, 1);
assert.equal(status.recipients, undefined);
const failedStatus: Sms.DeliveryReportStatusEnum = 'Failed';
assert.equal(status.status, failedStatus);
status = deliveryReport.statuses[1];
assert.equal(status.code, 0);
assert.equal(status.count, 1);
assert.equal(status.recipients, undefined);
const deliveredStatus: Sms.DeliveryReportStatusEnum = 'Delivered';
assert.equal(status.status, deliveredStatus);
assert.equal(deliveryReport.total_message_count, 2);
assert.equal(deliveryReport.type, 'delivery_report_sms');
});

When('I send a request to retrieve a full SMS delivery report', async () => {
const requestData: Sms.GetDeliveryReportByBatchIdRequestData = {
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
type: 'full',
};
deliveryReport = await deliveryReportsApi.get(requestData);
});

Then('the response contains a full SMS delivery report', () => {
assert.equal(deliveryReport.batch_id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.ok(deliveryReport.statuses);
const status = deliveryReport.statuses[0];
assert.ok(status.recipients);
assert.equal(status.code, 0);
assert.equal(status.count, 1);
assert.equal(status.recipients[0], '12017777777');
const deliveredStatus: Sms.DeliveryReportStatusEnum = 'Delivered';
assert.equal(status.status, deliveredStatus);
});

When('I send a request to retrieve a recipient\'s delivery report', async () => {
const requestData: Sms.GetDeliveryReportByPhoneNumberRequestData = {
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
phone_number: '12017777777',
};
recipientDeliveryReport = await deliveryReportsApi.getForNumber(requestData);
});

Then('the response contains the recipient\'s delivery report details', () => {
assert.equal(recipientDeliveryReport.batch_id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.equal(recipientDeliveryReport.recipient, '12017777777');
assert.equal(recipientDeliveryReport.client_reference, 'reference_e2e');
const deliveredStatus: Sms.DeliveryReportStatusEnum = 'Delivered';
assert.equal(recipientDeliveryReport.status, deliveredStatus);
assert.equal(recipientDeliveryReport.type, 'recipient_delivery_report_sms');
assert.equal(recipientDeliveryReport.code, 0);
assert.deepEqual(recipientDeliveryReport.at, new Date('2024-06-06T13:06:27.833Z'));
assert.deepEqual(recipientDeliveryReport.operator_status_at, new Date('2024-06-06T13:06:00Z'));
});

When('I send a request to list the SMS delivery reports', async () => {
const requestData: Sms.ListDeliveryReportsRequestData = {};
listResponse = await deliveryReportsApi.list(requestData);
});

Then('the response contains {string} SMS delivery reports', (expectedAnswer: string) => {
const expectedDeliveryReportsCount = parseInt(expectedAnswer, 10);
assert.equal(listResponse.data.length, expectedDeliveryReportsCount);
});

When('I send a request to list all the SMS delivery reports', async () => {
recipientDeliveryReportList = [];
for await (const deliveryReport of deliveryReportsApi.list({ page_size: 2 })) {
recipientDeliveryReportList.push(deliveryReport);
}
});

When('I iterate manually over the SMS delivery reports pages', async () => {
recipientDeliveryReportList = [];
listResponse = await deliveryReportsApi.list({
page_size: 2,
});
recipientDeliveryReportList.push(...listResponse.data);
pagesIteration = 1;
let reachedEndOfPages = false;
while (!reachedEndOfPages) {
if (listResponse.hasNextPage) {
listResponse = await listResponse.nextPage();
recipientDeliveryReportList.push(...listResponse.data);
pagesIteration++;
} else {
reachedEndOfPages = true;
}
}
});

Then('the SMS delivery reports list contains {string} SMS delivery reports', (expectedAnswer: string) => {
const expectedDeliveryReportsCount = parseInt(expectedAnswer, 10);
assert.equal(recipientDeliveryReportList.length, expectedDeliveryReportsCount);
});

Then('the SMS delivery reports iteration result contains the data from {string} pages', (expectedAnswer: string) => {
const expectedPagesCount = parseInt(expectedAnswer, 10);
assert.equal(pagesIteration, expectedPagesCount);
});
Loading