diff --git a/packages/javascript-api/src/lib/model/ticket/external-data.ts b/packages/javascript-api/src/lib/model/ticket/external-data.ts new file mode 100644 index 00000000..e5c9977d --- /dev/null +++ b/packages/javascript-api/src/lib/model/ticket/external-data.ts @@ -0,0 +1,34 @@ +export type ExternalData = { + fields?: ExternalDataField[]; +}; + +export type ExternalDataField = + | ExternalMessageField + | ExternalTextualField + | ExternalListField; + +export interface ExternalMessageField { + type: 'message'; + content: string; + importance: 'info' | 'warning' | 'error'; +} + +export interface ExternalTextualField { + type: 'text' | 'email' | 'phoneNumber'; + title: string; + value: string; +} + +export interface ExternalListItem { + title: string; + text?: string; + url?: string; + footer?: string; + timestamp?: string; +} + +export interface ExternalListField { + type: 'list'; + title: string; + items: ExternalListItem[]; +} diff --git a/packages/javascript-api/src/lib/services/ticket/set-external-data.spec.ts b/packages/javascript-api/src/lib/services/ticket/set-external-data.spec.ts new file mode 100644 index 00000000..d5bc3ee1 --- /dev/null +++ b/packages/javascript-api/src/lib/services/ticket/set-external-data.spec.ts @@ -0,0 +1,56 @@ +import * as sinon from 'sinon'; +import { Qminder } from '../../qminder'; +import { TicketService } from './ticket.service'; +import { ExternalData } from '../../model/ticket/external-data.js'; + +describe('Ticket.setExternalData', () => { + let requestStub: sinon.SinonStub; + + beforeEach(() => { + Qminder.setKey('EXAMPLE_API_KEY'); + Qminder.setServer('api.qminder.com'); + requestStub = sinon.stub(Qminder.ApiBase, 'request'); + }); + + afterEach(() => { + sinon.restore(); + }); + + it('sends POST to v1/tickets//external with stringified data and returns success', async () => { + const ticketId = '123'; + const provider = 'crm'; + const title = 'Case #42'; + const data: ExternalData = { + fields: [ + { type: 'message', content: 'Hello', importance: 'info' }, + { type: 'text', title: 'Order', value: '42' }, + { + type: 'list', + title: 'Links', + items: [{ title: 'Home', url: 'https://example.com' }], + }, + ], + }; + + requestStub.resolves({ result: 'success' }); + + const result = await TicketService.setExternalData( + ticketId, + provider, + title, + data, + ); + + expect(result).toBe('success'); + + expect(requestStub.calledOnce).toBeTruthy(); + const [url, options] = requestStub.getCall(0).args as [string, any]; + expect(url).toBe(`v1/tickets/${ticketId}/external`); + expect(options.method).toBe('POST'); + expect(options.body).toEqual({ + provider, + title, + data: JSON.stringify(data), + }); + }); +}); diff --git a/packages/javascript-api/src/lib/services/ticket/ticket.ts b/packages/javascript-api/src/lib/services/ticket/ticket.ts index 0f4ff6a3..ef4dbe75 100644 --- a/packages/javascript-api/src/lib/services/ticket/ticket.ts +++ b/packages/javascript-api/src/lib/services/ticket/ticket.ts @@ -11,6 +11,7 @@ import { } from '../../util/id-or-object.js'; import { ApiBase } from '../api-base/api-base.js'; import { ResponseValidationError } from '../../model/errors/response-validation-error.js'; +import { ExternalData } from '../../model/ticket/external-data.js'; /** * Represents a collection of search criteria for TicketService.count(). @@ -755,7 +756,7 @@ export function setExternalData( ticket: IdOrObject, provider: string, title: string, - data: any, + data: ExternalData, ): Promise<'success'> { const ticketId = extractId(ticket);