Skip to content

feat(zendesk-api-service): add function to fetch voice lines #120

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

Merged
merged 10 commits into from
May 14, 2025
Merged
27 changes: 13 additions & 14 deletions __tests__/services/sunshine-conversation-api-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Capabilities,
IAuthor,
IContent,
IIntegrationSuncoTwilio,
IIntegrationWhatsApp,
ISendNotificationPayload,
IServiceConfig,
Expand Down Expand Up @@ -473,21 +474,19 @@ describe("SunshineConversationApiService", () => {
}
};

const notification: IIntegrationSuncoTwilio = {
id: "id",
status: "status",
"type": UserChannelTypes.Twilio,
accountSid: "accountSid",
phoneNumberSid: "phoneNumberSid",
messagingServiceSid: "messagingServiceSid",
displayName: "Twilio",
phoneNumber: "+12345678900"
};

// Sending twilio notification
await sunshineConversationApiService.sendNotification(
{
id: "id",
status: "status",
"type": UserChannelTypes.Twilio,
accountSid: "accountSid",
phoneNumberSid: "phoneNumberSid",
messagingServiceSid: "messagingServiceSid",
displayName: "Twilio",
phoneNumber: "+12345678900"
},
phoneNumberSample,
contentSample
);
await sunshineConversationApiService.sendNotification(notification, phoneNumberSample, contentSample);

expect(client.request).toHaveBeenCalledWith(options);
});
Expand Down
37 changes: 37 additions & 0 deletions __tests__/services/zendesk-api-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,43 @@ describe("ZendeskService", () => {
expect(result).toEqual(locales);
});
});

describe("getVoiceLines", () => {
it("should call the API and return the voice lines", async () => {
const lines = [{ name: "line1" }];
requestMock.mockResolvedValueOnce({ lines });

const result = await service.getVoiceLines();

expect(requestMock).toHaveBeenCalledWith(`/api/v2/channels/voice/lines`);
expect(result).toEqual(lines);
});

it("should continue calling the API until next_page disappears", async () => {
const lines = [{ name: "line1" }];
requestMock
.mockResolvedValueOnce({ lines, next_page: "next_page" })
.mockResolvedValueOnce({ lines: [] });

const result = await service.getVoiceLines();

expect(requestMock).toHaveBeenCalledTimes(2);
expect(requestMock).toHaveBeenNthCalledWith(1, `/api/v2/channels/voice/lines`);
expect(requestMock).toHaveBeenNthCalledWith(2, "next_page");
expect(result).toEqual(lines);
});

it("should only call the API one time with fetchAllLines set to false", async () => {
const lines = [{ name: "line1" }];
requestMock.mockResolvedValueOnce({ lines, next_page: "next_page" });

const result = await service.getVoiceLines(false);

expect(requestMock).toHaveBeenCalledTimes(1);
expect(requestMock).toHaveBeenCalledWith(`/api/v2/channels/voice/lines`);
expect(result).toEqual(lines);
});
});
});
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zendesk/zaf-toolbox",
"version": "0.2.12",
"version": "0.3.0",
"description": "A toolbox for ZAF application built with 🩷 by Zendesk Labs",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
Expand Down
15 changes: 12 additions & 3 deletions src/models/sunshine-conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ export type IIntegration =
| IIntegrationIos
| IIntegrationMessageBirds
| IIntegrationMessenger
| IIntegrationTwillio
| IIntegrationTwilio
| IIntegrationTwitter
| IIntegrationWeb
| IIntegrationWhatsApp
Expand Down Expand Up @@ -548,8 +548,18 @@ export interface IIntegrationMessenger extends IIntegrationBase {
pageName?: string;
}

export interface IIntegrationTwillio extends IIntegrationBase {
export interface IIntegrationTwilio extends IIntegrationBase {
type: UserChannelTypes.Twilio;
phoneNumber: string;
isTalk?: boolean;
}

export interface IIntegrationTwilioTalk extends IIntegrationTwilio {
sms: boolean;
mms: boolean;
}

export interface IIntegrationSuncoTwilio extends IIntegrationTwilio {
/**
* Twilio Account SID.
*/
Expand All @@ -558,7 +568,6 @@ export interface IIntegrationTwillio extends IIntegrationBase {
* SID for specific phone number. One of messagingServiceSid or phoneNumberSid must be provided when creating a Twilio integration
*/
phoneNumberSid: string;
phoneNumber: string;
/**
* SID for specific messaging service. One of messagingServiceSid or phoneNumberSid must be provided when creating a Twilio integration.
*/
Expand Down
67 changes: 67 additions & 0 deletions src/models/zendesk-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,73 @@
organizations: IZendeskOrganizations[];
}

export interface ILinesResults extends IZendeskResponse {
lines: Line[];
next_page: string | null;
previous_page: string | null;
count: number;
}

interface LineBase {
id: number;

Check failure on line 65 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
nickname: string;

Check failure on line 66 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
priority: number;

Check failure on line 67 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Replace `··` with `····`
default_group_id: number | null;

Check failure on line 68 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
line_type: string;

Check failure on line 69 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
transcription: boolean;

Check failure on line 70 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
recorded: boolean;

Check failure on line 71 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
call_recording_consent: string;

Check failure on line 72 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Replace `··` with `····`
group_ids: number[];

Check failure on line 73 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
greeting_ids: string[];

Check failure on line 74 in src/models/zendesk-api.ts

View workflow job for this annotation

GitHub Actions / Lint the API

Insert `··`
default_greeting_ids: string[];
categorised_greetings_with_sub_settings: CategorisedGreetingsWithSubSettings;
schedule_id: number | null;
created_at: string;
}

export interface DigitalLine extends LineBase {
line_type: "digital";
brand_id: number;
line_id: string;
outbound_number: string | null;
}

export interface PhoneLine extends LineBase {
line_type: "phone";
country_code: string;
external: boolean;
number: string;
name: string;
display_number: string;
location: string;
toll_free: boolean;
categorised_greetings: CategorisedGreetings;
sms_group_id: number | null;
capabilities: Capabilities;
sms_enabled: boolean;
voice_enabled: boolean;
outbound_enabled: boolean;
ivr_id: number | null;
failover_number: string | null;
}

interface Capabilities {
sms: boolean;
mms: boolean;
voice: boolean;
emergency_address: boolean;
}

interface CategorisedGreetings {
[key: string]: string;
}

interface CategorisedGreetingsWithSubSettings {
[key: string]: string | { [subKey: string]: string };
}

export type Line = DigitalLine | PhoneLine;

export interface ILocalesResults {
locales: IZendeskLocale[];
}
21 changes: 17 additions & 4 deletions src/services/zendesk-api-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
IZendeskTag,
IZendeskLocale,
IZendeskGroup,
IZendeskOrganizations
IZendeskOrganizations,
ILinesResults,
IZendeskLines,

Check failure on line 23 in src/services/zendesk-api-service.ts

View workflow job for this annotation

GitHub Actions / Build package

Module '"@models/index"' has no exported member 'IZendeskLines'.
IZendeskResponse
} from "@models/index";
import { convertContentMessageToHtml } from "@utils/convert-content-message-to-html";
import { getFromClient } from "@utils/get-from-client";
Expand All @@ -40,16 +43,15 @@
* @param extractArrayFn Function to extract the array of items from the response.
* @returns A promise resolving to a flattened array of all items.
*/
private async fetchAllPaginatedResults<TResponse, TItem>(
private async fetchAllPaginatedResults<TResponse extends IZendeskResponse, TItem>(
url: string,
fetchAll: boolean,
extractArrayFn: (response: TResponse) => TItem[]
): Promise<TItem[]> {
const results: TResponse[] = [await this.client.request<string, TResponse>(url)];

if (fetchAll) {
while (true) {
const nextPage = (results[results.length - 1] as TResponse & { next_page?: string }).next_page;
const nextPage = results[results.length - 1].next_page;
if (!nextPage) break;
results.push(await this.client.request<string, TResponse>(nextPage));
}
Expand Down Expand Up @@ -253,4 +255,15 @@

return results.locales;
}

/**
* Fetch all voice lines
*/
public async getVoiceLines(fetchAllLines = true): Promise<IZendeskLines[]> {
return this.fetchAllPaginatedResults<ILinesResults, IZendeskLines>(
`/api/v2/channels/voice/lines`,
fetchAllLines,
(response) => response.lines
);
}
}
Loading