diff --git a/api/messages-api.ts b/api/messages-api.ts
index 2b00916..b765f56 100644
--- a/api/messages-api.ts
+++ b/api/messages-api.ts
@@ -93,7 +93,7 @@ export const MessagesApiAxiosParamCreator = function (configuration?: Configurat
};
},
/**
- * Returns a list of messages based on query parameters.
+ * Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
* @summary List Messages
* @param {string} accountId Your Bandwidth Account ID.
* @param {string} [messageId] The ID of the message to search for. Special characters need to be encoded using URL encoding. Message IDs could come in different formats, e.g., 9e0df4ca-b18d-40d7-a59f-82fcdf5ae8e6 and 1589228074636lm4k2je7j7jklbn2 are valid message ID formats. Note that you must include at least one query parameter.
@@ -293,7 +293,7 @@ export const MessagesApiFp = function(configuration?: Configuration) {
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
- * Returns a list of messages based on query parameters.
+ * Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
* @summary List Messages
* @param {string} accountId Your Bandwidth Account ID.
* @param {string} [messageId] The ID of the message to search for. Special characters need to be encoded using URL encoding. Message IDs could come in different formats, e.g., 9e0df4ca-b18d-40d7-a59f-82fcdf5ae8e6 and 1589228074636lm4k2je7j7jklbn2 are valid message ID formats. Note that you must include at least one query parameter.
@@ -353,7 +353,7 @@ export const MessagesApiFactory = function (configuration?: Configuration, baseP
return localVarFp.createMessage(accountId, messageRequest, options).then((request) => request(axios, basePath));
},
/**
- * Returns a list of messages based on query parameters.
+ * Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
* @summary List Messages
* @param {string} accountId Your Bandwidth Account ID.
* @param {string} [messageId] The ID of the message to search for. Special characters need to be encoded using URL encoding. Message IDs could come in different formats, e.g., 9e0df4ca-b18d-40d7-a59f-82fcdf5ae8e6 and 1589228074636lm4k2je7j7jklbn2 are valid message ID formats. Note that you must include at least one query parameter.
@@ -409,7 +409,7 @@ export class MessagesApi extends BaseAPI {
}
/**
- * Returns a list of messages based on query parameters.
+ * Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
* @summary List Messages
* @param {string} accountId Your Bandwidth Account ID.
* @param {string} [messageId] The ID of the message to search for. Special characters need to be encoded using URL encoding. Message IDs could come in different formats, e.g., 9e0df4ca-b18d-40d7-a59f-82fcdf5ae8e6 and 1589228074636lm4k2je7j7jklbn2 are valid message ID formats. Note that you must include at least one query parameter.
diff --git a/bandwidth.yml b/bandwidth.yml
index 22b13ce..7c08f29 100644
--- a/bandwidth.yml
+++ b/bandwidth.yml
@@ -163,7 +163,13 @@ paths:
/users/{accountId}/messages:
get:
summary: List Messages
- description: Returns a list of messages based on query parameters.
+ description: >
+ Returns a list of messages based on query parameters.
+
+
+ **Rate Limit:** This endpoint is rate limited to 3500 requests per 5
+ minutes per Source IP address. Exceeding the limit returns HTTP 429 with
+ a `Retry-After` header.
operationId: listMessages
tags:
- Messages
@@ -207,10 +213,12 @@ paths:
$ref: '#/components/responses/messagingForbiddenError'
'404':
$ref: '#/components/responses/messagingNotFoundError'
+ '405':
+ $ref: '#/components/responses/messagingMethodNotAllowedError'
'415':
$ref: '#/components/responses/messagingInvalidMediaTypeError'
'429':
- $ref: '#/components/responses/messagingTooManyRequestsError'
+ $ref: '#/components/responses/listMessagesTooManyRequestsError'
'500':
$ref: '#/components/responses/messagingInternalServerError'
post:
@@ -2257,7 +2265,9 @@ components:
type: object
properties:
media:
- $ref: '#/components/schemas/rbmMessageContentFile'
+ type: array
+ items:
+ $ref: '#/components/schemas/rbmMessageContentFile'
suggestions:
$ref: '#/components/schemas/multiChannelFullActions'
required:
@@ -5875,7 +5885,6 @@ components:
type: object
internalTicketNumber:
type: string
- format: uuid
description: >-
Unique identifier (UUID) generated by Bandwidth to assist in tracking
the verification status of a toll-free number - included in all webhook
@@ -5883,7 +5892,6 @@ components:
example: acde070d-8c4c-4f0d-9d8a-162843c10333
internalTicketNumberForWebhook:
type: string
- format: uuid
description: >-
Unique identifier (UUID) generated by Bandwidth to assist in tracking
the verification status of a toll-free number.
@@ -6752,6 +6760,21 @@ components:
- type: internal-server-error
description: Internal server error. No further information available
source: {}
+ listMessagesTooManyRequestsError:
+ description: Too Many Requests
+ headers:
+ Retry-After:
+ description: The number of seconds to wait before retrying the request.
+ schema:
+ type: integer
+ example: 300
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/messagingRequestError"
+ example:
+ type: rate_limit_exceeded
+ description: Rate limit exceeded. Wait for Retry-After time before sending another request.
createCallResponse:
description: Created
headers:
diff --git a/docs/MessagesApi.md b/docs/MessagesApi.md
index 0a01251..9202261 100644
--- a/docs/MessagesApi.md
+++ b/docs/MessagesApi.md
@@ -74,7 +74,7 @@ const { status, data } = await apiInstance.createMessage(
# **listMessages**
> MessagesList listMessages()
-Returns a list of messages based on query parameters.
+Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
### Example
@@ -204,8 +204,9 @@ const { status, data } = await apiInstance.listMessages(
|**401** | Unauthorized | - |
|**403** | Forbidden | - |
|**404** | Not Found | - |
+|**405** | Method Not Allowed | - |
|**415** | Unsupported Media Type | - |
-|**429** | Too Many Requests | - |
+|**429** | Too Many Requests | * Retry-After - The number of seconds to wait before retrying the request.
|
|**500** | Internal Server Error | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/docs/MultiChannelChannelListRBMObjectAllOfContent.md b/docs/MultiChannelChannelListRBMObjectAllOfContent.md
index 4d566be..dc887e8 100644
--- a/docs/MultiChannelChannelListRBMObjectAllOfContent.md
+++ b/docs/MultiChannelChannelListRBMObjectAllOfContent.md
@@ -8,7 +8,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**text** | **string** | The text associated with the message. Must be 3270 characters or less | [default to undefined]
**suggestions** | [**Array<MultiChannelAction>**](MultiChannelAction.md) | An array of suggested actions for the recipient. | [optional] [default to undefined]
-**media** | [**RbmMessageContentFile**](RbmMessageContentFile.md) | | [default to undefined]
+**media** | [**Array<RbmMessageContentFile>**](RbmMessageContentFile.md) | | [default to undefined]
**orientation** | [**StandaloneCardOrientationEnum**](StandaloneCardOrientationEnum.md) | | [default to undefined]
**thumbnailImageAlignment** | [**ThumbnailAlignmentEnum**](ThumbnailAlignmentEnum.md) | | [default to undefined]
**cardContent** | [**RbmCardContent**](RbmCardContent.md) | | [default to undefined]
diff --git a/docs/RbmMessageMedia.md b/docs/RbmMessageMedia.md
index a941751..c184653 100644
--- a/docs/RbmMessageMedia.md
+++ b/docs/RbmMessageMedia.md
@@ -5,7 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**media** | [**RbmMessageContentFile**](RbmMessageContentFile.md) | | [default to undefined]
+**media** | [**Array<RbmMessageContentFile>**](RbmMessageContentFile.md) | | [default to undefined]
**suggestions** | [**Array<MultiChannelAction>**](MultiChannelAction.md) | An array of suggested actions for the recipient. | [optional] [default to undefined]
## Example
diff --git a/models/rbm-message-media.ts b/models/rbm-message-media.ts
index c196bef..7a953d3 100644
--- a/models/rbm-message-media.ts
+++ b/models/rbm-message-media.ts
@@ -21,7 +21,7 @@ import type { MultiChannelAction } from './multi-channel-action';
import type { RbmMessageContentFile } from './rbm-message-content-file';
export interface RbmMessageMedia {
- 'media': RbmMessageContentFile;
+ 'media': Array;
/**
* An array of suggested actions for the recipient.
*/
diff --git a/tests/smoke/multi-channel-api.test.ts b/tests/smoke/multi-channel-api.test.ts
index 04a1c44..e4bac30 100644
--- a/tests/smoke/multi-channel-api.test.ts
+++ b/tests/smoke/multi-channel-api.test.ts
@@ -11,7 +11,20 @@ import {
RbmMessageContentText,
MultiChannelMessageRequest,
MessageDirectionEnum,
- RbmActionTypeEnum
+ RbmActionTypeEnum,
+ CardWidthEnum,
+ RbmMediaHeightEnum,
+ RbmCardContent,
+ RbmMessageCarouselCard,
+ RbmMessageMedia,
+ RbmActionDial,
+ MultiChannelChannelListRBMResponseObject,
+ RbmStandaloneCard,
+ StandaloneCardOrientationEnum,
+ ThumbnailAlignmentEnum,
+ MultiChannelChannelListSMSObject,
+ MultiChannelChannelListMMSObject,
+ MultiChannelChannelListRBMObject
} from '../../models';
describe('MultiChannelApi', () => {
@@ -103,8 +116,8 @@ describe('MultiChannelApi', () => {
});
});
- describe('createMultiChannelRBMMessage', () => {
- test('should create a multi-channel RBM message', async () => {
+ describe('createMultiChannelRBMTextMessage', () => {
+ test('should create a multi-channel RBM text message', async () => {
const content: RbmMessageContentText = {
text: "Hello World!",
suggestions: [{
@@ -145,7 +158,230 @@ describe('MultiChannelApi', () => {
expect(data.data?.priority).toBeOneOf(Object.values(PriorityEnum));
expect(data.data?.expiration).toBeDateString();
expect(data.data?.channelList).toBeArray();
- expect(data.data?.channelList![0].channel).toEqual(MultiChannelMessageChannelEnum.Rbm);
+ expect(data.data?.channelList![0]).toBeObject();
+ const channelListObject = data.data?.channelList![0] as MultiChannelChannelListRBMResponseObject;
+ expect(channelListObject.from).toEqual(BW_NUMBER);
+ expect(channelListObject.applicationId).toEqual(BW_MESSAGING_APPLICATION_ID);
+ expect(channelListObject.channel).toEqual(MultiChannelMessageChannelEnum.Rbm);
+ expect(channelListObject.content).toBeObject();
+ expect(channelListObject.owner).toEqual(BW_NUMBER);
+ const rbmContent = channelListObject.content as RbmMessageContentText;
+ expect(rbmContent.text).toBeString();
+ expect(rbmContent.suggestions).toBeArray();
+ expect(rbmContent.suggestions[0]).toBeObject();
+ const rbmActionDial = rbmContent.suggestions[0] as RbmActionDial;
+ expect(rbmActionDial.type).toEqual(RbmActionTypeEnum.DialPhone);
+ expect(rbmActionDial.text).toBeString();
+ expect(rbmActionDial.postbackData).toBeString();
+ expect(rbmActionDial.phoneNumber).toBeString();
+ });
+ });
+
+ describe('createMultiChannelRBMMediaMessage', () => {
+ test('should create a multi-channel RBM media message', async () => {
+ const content: RbmMessageMedia = {
+ media:[{
+ fileUrl: "https://example.com/image.jpg",
+ thumbnailUrl: "https://example.com/thumbnail.jpg",
+ }],
+ suggestions: [{
+ type: RbmActionTypeEnum.DialPhone,
+ text: "Call Us",
+ postbackData: "tel:+1234567890",
+ phoneNumber: BW_NUMBER
+ }]
+ };
+
+ const channelListObject: MultiChannelChannelListRBMObject = {
+ from: BW_NUMBER,
+ applicationId: BW_MESSAGING_APPLICATION_ID,
+ channel: MultiChannelMessageChannelEnum.Rbm,
+ content,
+ };
+
+ const multiChannelMessageRequest: MultiChannelMessageRequest = {
+ to: USER_NUMBER,
+ tag: "tag",
+ priority: PriorityEnum.High,
+ expiration,
+ channelList: [channelListObject],
+ };
+
+ const { status, data } = await multiChannelApi.createMultiChannelMessage(
+ BW_ACCOUNT_ID,
+ multiChannelMessageRequest
+ );
+
+ expect(status).toEqual(202);
+ expect(data.links).toBeArray();
+ expect(data.data?.id).toBeString();
+ expect(data.data?.time).toBeDateString();
+ expect(data.data?.direction).toBeOneOf(Object.values(MessageDirectionEnum));
+ expect(data.data?.to).toBeArray();
+ expect(data.data?.tag).toBeString();
+ expect(data.data?.priority).toBeOneOf(Object.values(PriorityEnum));
+ expect(data.data?.expiration).toBeDateString();
+ expect(data.data?.channelList).toBeArray();
+ expect(data.data?.channelList![0]).toBeObject();
+ const channelListObject = data.data?.channelList![0] as MultiChannelChannelListRBMResponseObject;
+ expect(channelListObject.from).toEqual(BW_NUMBER);
+ expect(channelListObject.applicationId).toEqual(BW_MESSAGING_APPLICATION_ID);
+ expect(channelListObject.channel).toEqual(MultiChannelMessageChannelEnum.Rbm);
+ expect(channelListObject.content).toBeObject();
+ expect(channelListObject.owner).toEqual(BW_NUMBER);
+ const rbmContent = channelListObject.content as RbmMessageMedia;
+ expect(rbmContent.media).toBeArray();
+ expect(rbmContent.media[0].fileUrl).toBeString();
+ expect(rbmContent.media[0].thumbnailUrl).toBeString();
+ expect(rbmContent.suggestions).toBeArray();
+ expect(rbmContent.suggestions[0]).toBeObject();
+ const rbmActionDial = rbmContent.suggestions[0] as RbmActionDial;
+ expect(rbmActionDial.type).toEqual(RbmActionTypeEnum.DialPhone);
+ expect(rbmActionDial.text).toBeString();
+ expect(rbmActionDial.postbackData).toBeString();
+ expect(rbmActionDial.phoneNumber).toBeString();
+ });
+ });
+
+ describe('createMultiChannelRBMRichStandaloneMessage', () => {
+ test('should create a multi-channel RBM standalone rich card message', async () => {
+ const content: RbmStandaloneCard = {
+ orientation: StandaloneCardOrientationEnum.Horizontal,
+ thumbnailImageAlignment: ThumbnailAlignmentEnum.Left,
+ cardContent: {
+ title: "Test Title"
+ }
+ };
+
+ const channelListObject: MultiChannelChannelListRBMObject = {
+ from: BW_NUMBER,
+ applicationId: BW_MESSAGING_APPLICATION_ID,
+ channel: MultiChannelMessageChannelEnum.Rbm,
+ content,
+ };
+
+ const multiChannelMessageRequest: MultiChannelMessageRequest = {
+ to: USER_NUMBER,
+ tag: "tag",
+ priority: PriorityEnum.High,
+ expiration,
+ channelList: [channelListObject],
+ };
+
+ const { status, data } = await multiChannelApi.createMultiChannelMessage(
+ BW_ACCOUNT_ID,
+ multiChannelMessageRequest
+ );
+
+ expect(status).toEqual(202);
+ expect(data.links).toBeArray();
+ expect(data.data?.id).toBeString();
+ expect(data.data?.time).toBeDateString();
+ expect(data.data?.direction).toBeOneOf(Object.values(MessageDirectionEnum));
+ expect(data.data?.to).toBeArray();
+ expect(data.data?.tag).toBeString();
+ expect(data.data?.priority).toBeOneOf(Object.values(PriorityEnum));
+ expect(data.data?.expiration).toBeDateString();
+ expect(data.data?.channelList).toBeArray();
+ expect(data.data?.channelList![0]).toBeObject();
+ const channelListObject = data.data?.channelList![0] as MultiChannelChannelListRBMResponseObject;
+ expect(channelListObject.from).toEqual(BW_NUMBER);
+ expect(channelListObject.applicationId).toEqual(BW_MESSAGING_APPLICATION_ID);
+ expect(channelListObject.channel).toEqual(MultiChannelMessageChannelEnum.Rbm);
+ expect(channelListObject.content).toBeObject();
+ expect(channelListObject.owner).toEqual(BW_NUMBER);
+ const rbmContent = channelListObject.content as RbmStandaloneCard;
+ expect(rbmContent.orientation).toEqual(StandaloneCardOrientationEnum.Horizontal);
+ expect(rbmContent.thumbnailImageAlignment).toEqual(ThumbnailAlignmentEnum.Left);
+ expect(rbmContent.cardContent.title).toBeString();
+ });
+ });
+
+ describe('createMultiChannelRBMRichCarouselMessage', () => {
+ test('should create a multi-channel RBM carousel rich card message', async () => {
+ const carouselCard: RbmCardContent = {
+ title: "Card 1 Title",
+ description: "Card 1 Description",
+ media: {
+ fileUrl: "https://example.com/image.jpg",
+ thumbnailUrl: "https://example.com/thumbnail.jpg",
+ height: RbmMediaHeightEnum.Tall
+ },
+ suggestions: [{
+ type: RbmActionTypeEnum.DialPhone,
+ text: "Call Us",
+ postbackData: "tel:+1234567890",
+ phoneNumber: BW_NUMBER
+ }]
+ };
+
+ const content: RbmMessageCarouselCard = {
+ cardWidth: CardWidthEnum.Medium,
+ cardContents: [
+ carouselCard,
+ { title: "Card 2 Title" }
+ ]
+ };
+
+ const channelListObject: MultiChannelChannelListRBMObject = {
+ from: BW_NUMBER,
+ applicationId: BW_MESSAGING_APPLICATION_ID,
+ channel: MultiChannelMessageChannelEnum.Rbm,
+ content,
+ };
+
+ const multiChannelMessageRequest: MultiChannelMessageRequest = {
+ to: USER_NUMBER,
+ tag: "tag",
+ priority: PriorityEnum.High,
+ expiration,
+ channelList: [channelListObject],
+ };
+
+ const { status, data } = await multiChannelApi.createMultiChannelMessage(
+ BW_ACCOUNT_ID,
+ multiChannelMessageRequest
+ );
+
+ expect(status).toEqual(202);
+ expect(data.links).toBeArray();
+ expect(data.data?.id).toBeString();
+ expect(data.data?.time).toBeDateString();
+ expect(data.data?.direction).toBeOneOf(Object.values(MessageDirectionEnum));
+ expect(data.data?.to).toBeArray();
+ expect(data.data?.tag).toBeString();
+ expect(data.data?.priority).toBeOneOf(Object.values(PriorityEnum));
+ expect(data.data?.expiration).toBeDateString();
+ expect(data.data?.channelList).toBeArray();
+ expect(data.data?.channelList![0]).toBeObject();
+ const channelListObject = data.data?.channelList![0] as MultiChannelChannelListRBMResponseObject;
+ expect(channelListObject.from).toEqual(BW_NUMBER);
+ expect(channelListObject.applicationId).toEqual(BW_MESSAGING_APPLICATION_ID);
+ expect(channelListObject.channel).toEqual(MultiChannelMessageChannelEnum.Rbm);
+ expect(channelListObject.content).toBeObject();
+ expect(channelListObject.owner).toEqual(BW_NUMBER);
+ const rbmContent = channelListObject.content as RbmMessageCarouselCard;
+ expect(rbmContent.cardWidth).toEqual(CardWidthEnum.Medium);
+ expect(rbmContent.cardContents).toBeArray();
+ expect(rbmContent.cardContents).toHaveLength(2);
+ expect(rbmContent.cardContents[0]).toBeObject();
+ const firstCard = rbmContent.cardContents[0] as RbmCardContent;
+ expect(firstCard.title).toBeString();
+ expect(firstCard.description).toBeString();
+ expect(firstCard.media).toBeObject();
+ expect(firstCard.media!.fileUrl).toBeString();
+ expect(firstCard.media!.thumbnailUrl).toBeString();
+ expect(firstCard.media!.height).toEqual(RbmMediaHeightEnum.Tall);
+ expect(firstCard.suggestions).toBeArray();
+ expect(firstCard.suggestions[0]).toBeObject();
+ const rbmActionDial = firstCard.suggestions[0] as RbmActionDial;
+ expect(rbmActionDial.type).toEqual(RbmActionTypeEnum.DialPhone);
+ expect(rbmActionDial.text).toBeString();
+ expect(rbmActionDial.postbackData).toBeString();
+ expect(rbmActionDial.phoneNumber).toBeString();
+ expect(rbmContent.cardContents[1]).toBeObject();
+ const secondCard = rbmContent.cardContents[1] as RbmCardContent;
+ expect(secondCard.title).toBeString();
});
});
});