diff --git a/examples/simple-examples/src/conversation/messages/send.ts b/examples/simple-examples/src/conversation/messages/send.ts index 31bc6461..fa148f09 100644 --- a/examples/simple-examples/src/conversation/messages/send.ts +++ b/examples/simple-examples/src/conversation/messages/send.ts @@ -24,6 +24,7 @@ import { getAppIdFromConfig, getContactIdFromConfig, initConversationService, pr queue: 'HIGH_PRIORITY', processing_strategy: 'DEFAULT', channel_priority_order: ['MESSENGER'], + ttl: 60, }, }; diff --git a/examples/webhooks/src/services/conversation-event.service.ts b/examples/webhooks/src/services/conversation-event.service.ts index f60fff03..c88bb5cd 100644 --- a/examples/webhooks/src/services/conversation-event.service.ts +++ b/examples/webhooks/src/services/conversation-event.service.ts @@ -61,7 +61,7 @@ export class ConversationEventService { contact_id: message.contact_id!, }, message: this.buildContactMessage(contactMessage), - ttl: '5s', + ttl: 5, channel_properties: { MESSENGER_NOTIFICATION_TYPE: 'NO_PUSH', } diff --git a/packages/conversation/src/models/v1/send-message-request/send-message-request.ts b/packages/conversation/src/models/v1/send-message-request/send-message-request.ts index 948adbd9..6b8015b6 100644 --- a/packages/conversation/src/models/v1/send-message-request/send-message-request.ts +++ b/packages/conversation/src/models/v1/send-message-request/send-message-request.ts @@ -35,9 +35,13 @@ export interface SendMessageRequestBase { queue?: MessageQueue; /** @see Recipient */ recipient: T; - /** The timeout allotted for sending the message, expressed in seconds. Passed to channels which support it and emulated by the Conversation API for channels without ttl support but with message retract/unsend functionality. Channel failover will not be performed for messages with an expired TTL. The format is an integer with the suffix `s` (for seconds). Valid integer range is 3 to 315,576,000,000 (inclusive). Example values include `10s` (10 seconds) and `86400s` (24 hours). */ - ttl?: string; - /** Overrides the app\'s [Processing Mode](../../../../../conversation/processing-modes/). Default value is `DEFAULT`. */ + /** The timeout allotted for sending the message, expressed in seconds. Passed to channels which support it and emulated by the Conversation API for channels without ttl support but with message retract/unsend functionality. Channel failover will not be performed for messages with an expired TTL. + * + * The format is an integer with the suffix `s` (for seconds). Valid integer range is 3 to 315,576,000,000 (inclusive). Example values include `10s` (10 seconds) and `86400s` (24 hours). + * The SDK will take care of the formatting: example of valid input for 10 seconds: 10 (number), "10" (string), "10s" (string) + */ + ttl?: string | number; + /** Overrides the app's [Processing Mode](../../../../../conversation/processing-modes/). Default value is `DEFAULT`. */ processing_strategy?: ProcessingStrategy; /** An arbitrary identifier that will be propagated to callbacks related to this message, including MO replies. Only applicable to messages sent with the `CONVERSATION` processing mode. Up to 128 characters long. */ correlation_id?: string; diff --git a/packages/conversation/src/rest/v1/messages/messages-api.ts b/packages/conversation/src/rest/v1/messages/messages-api.ts index 9f13262b..0c21b40d 100644 --- a/packages/conversation/src/rest/v1/messages/messages-api.ts +++ b/packages/conversation/src/rest/v1/messages/messages-api.ts @@ -361,8 +361,11 @@ export class MessagesApi extends ConversationDomainApi { 'Accept': 'application/json', }; - const body: RequestBody = data['sendMessageRequestBody'] - ? JSON.stringify(data['sendMessageRequestBody']) + // Special fields handling: see method for details + const requestDataBody = this.performSendMessageRequestBodyTransformation(data.sendMessageRequestBody); + + const body: RequestBody = requestDataBody + ? JSON.stringify(requestDataBody) : '{}'; const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/messages:send`; @@ -377,6 +380,20 @@ export class MessagesApi extends ConversationDomainApi { }); } + performSendMessageRequestBodyTransformation( + body: SendMessageRequest + ): SendMessageRequest { + const requestDataBody = { ...body }; + // 'ttl' field can be a number or a string and needs to be formatted as for instance "10s" to be accepted by the server + if (typeof requestDataBody.ttl === 'number') { + requestDataBody.ttl = requestDataBody.ttl.toString(); + } + if (typeof requestDataBody.ttl === 'string' && !requestDataBody.ttl.endsWith('s')) { + requestDataBody.ttl = requestDataBody.ttl + 's'; + } + return requestDataBody; + } + /** * Update message metadata * Update a specific message metadata by its ID. diff --git a/packages/conversation/tests/rest/v1/messages/messages-api.test.ts b/packages/conversation/tests/rest/v1/messages/messages-api.test.ts index a22d0151..14d558b0 100644 --- a/packages/conversation/tests/rest/v1/messages/messages-api.test.ts +++ b/packages/conversation/tests/rest/v1/messages/messages-api.test.ts @@ -225,6 +225,22 @@ describe('MessagesApi', () => { expect(response).toEqual(expectedResponse); expect(fixture.send).toHaveBeenCalledWith(requestData); }); + + it('should format the ttl field', () => { + const requestBody: SendMessageRequest = { + ...sendMessageRequest, + ...recipientContactId, + }; + requestBody.ttl = 20; + let formattedBody = messagesApi.performSendMessageRequestBodyTransformation(requestBody); + expect(formattedBody.ttl).toBe('20s'); + requestBody.ttl = '20'; + formattedBody = messagesApi.performSendMessageRequestBodyTransformation(requestBody); + expect(formattedBody.ttl).toBe('20s'); + requestBody.ttl = '20s'; + formattedBody = messagesApi.performSendMessageRequestBodyTransformation(requestBody); + expect(formattedBody.ttl).toBe('20s'); + }); }); describe ('sendCardMessage', () => {