RCS Custom Messages
The custom message type is one of the outbound message types supported by the RCS channel of the Messages API. Whereas the other outbound types defined in the RCS channel (text, image, video, and file) are abstractions of certain types of RCS message supported by the Google RBM (RCS Business Messaging) service, the custom type is essentially a pass-through to Google RBM. This means that the custom type has a lot of flexibility in supporting many different types of RCS message, but this fact also comes with the caveat that there is no validation of the structure of the custom object by the Vonage API.
The JSON structure for the custom message type has the standard required (to, from, channel, message_type) and optional (webhook_url, client_ref, ttl) properties of the other outbound RCS message types, as well as a custom property which is an object. The contents of this custom object define the type of RCS message to be sent.
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"webhook_url":"https//example.com/status", // optional
"client_ref":"abc123", // optional
"ttl": 9000, // optional
"custom": {
// message structure is defined here
}
}
There are many different types of RCS message that can be sent using the custom type, but they fall into two broad sub-types:
Suggestions
Suggestions are essentially prompts for the recipient of the message, and can be either suggested replies or suggested actions. Suggestions appear as chips (buttons) in the messaging app UI which the recipient of the message can tap in order to select that suggestion.
If the message recipient taps on of the suggestions, this will trigger an inbound message to the inbound message webhook that you have set up for your Vonage Application.
- Tapping on a suggested reply will trigger an inbound message of type
reply - Tapping on a suggested action will trigger an inbound message of type
button(in addition to triggering whatever action the suggested action defined)
Note: Suggestion chips will only appear in the UI if the message containing the suggestions is the most recent message in the conversation.
Within the JSON payload for the outbound message request, suggestions are defined as objects within a suggestions array. The array can contain a minimum of one and a maximum of eleven reply or action objects, or a combination of both.
Additionally, a text property is required, the value of which is a String. This text will appear above the list of suggestion chips in the messaging app UI.
Both the text string and the suggestions array are contained within a contentMessage object:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Some text here",
"suggestions": [
// suggestion objects
]
}
}
}
The structure of the suggestion objects depends on the type of suggestion.
Suggested Replies
Suggested replies contain a reply property, the value of which is an object. This object has two properties, both strings:
text(String): defines the text which will be displayed on the suggestion chip in the UI. The value of this property will be set as the value of thetitleproperty of thereplyobject in the inboundreplymessage. This string has a maximum length of 25 characters.postbackData(String): an identifier for the suggestion within your application. The value of this property will be set as the value of theidproperty of thereplyobject in the inboundreplymessage.
Here is an example of a suggestion message with two suggested reply options:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Which ice-cream flavour do you prefer?",
"suggestions": [
{
"reply": {
"text": "Vanilla",
"postbackData": "suggestion_1"
}
},
{
"reply": {
"text": "Chocolate",
"postbackData": "suggestion_2"
}
}
]
}
}
}
If the recipient tapped on the chip labelled 'Chocolate', this would trigger an inbound message of type reply which would look like this:
{
"to": "Vonage",
"from": "447900000000",
"channel": "rcs",
"message_uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
"timestamp": "2024-02-08T10:12:44Z",
"message_type": "reply",
"reply": {
"id": "suggestion_2",
"title": "Chocolate"
}
}
The to, from, channel, message_uuid, timestamp, and message_type properties are standard across all inbound message types, with the reply object and its properties specific to the reply message type.
Suggested Actions
Suggested action objects are similar in structure to suggested reply objects except they contain an action property instead of a reply property. As with reply, the value of the action property is an object, which again has text and postbackData properties. In the case of action objects, however, there are additional properties which define or support the action:
text(String): defines the text which will be displayed on the suggestion chip in the UI. The value of this property will be set as the value of thetextproperty of thebuttonobject in the inboundbuttonmessage. This string has a maximum length of 25 characters.postbackData(String): an identifier for the suggestion within your application. The value of this property will be set as the value of thepayloadproperty of thebuttonobject in the inboundbuttonmessage.- Additional properties to define and support the specific action
Here is a suggestion message with one, partly-defined, action:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "This is a suggested action message",
"suggestions": [
{
"action": {
"text": "Action",
"postbackData": "action_1",
// rest of action properties
}
}
]
}
}
}
If the recipient tapped on the chip labelled 'Action', as well as triggering the defined action this would also trigger an inbound message of type button which would look like this:
{
"to": "Vonage",
"from": "447900000000",
"channel": "rcs",
"message_uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
"timestamp": "2024-02-08T10:12:44Z",
"message_type": "button",
"button": {
"payload": "action_1",
"text": "Action"
}
}
There are many different types of action available:
Open an URL
For this action, the action object contains a openUrlAction property which is an object with one property:
url(String): this is the URL to be opened.
If this action chip is tapped, the recipient's device opens the specified URL either in the device's default browser or in an installed app (if an app is registered as a handler for the URL's domain).
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Want to know more about Vonage APIs? Then visit our developer website!",
"suggestions": [
{
"action": {
"text": "Go to developer website",
"postbackData": "action_1",
"openUrlAction": {
"url": "https://developer.vonage.com"
}
}
}
]
}
}
}
Dial a Number
For this action, the action object contains a dialAction property which is an object with one property:
phoneNumber(String): this is the phone number to be dialled. It must be in E.164 format, include the country code, and be prepended by a+, for example+447900000000
In addition to the dialAction property, the action object can contain an additional optional property:
fallbackUrl(String): this is a URL to be opened if it is not possible for the dial action to be initiated.
If this action chip is tapped, the recipient will be directed to call the phone number specified.
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Get in touch!",
"suggestions": [
{
"action": {
"text": "Call now",
"postbackData": "action_1",
"dialAction": {
"phoneNumber": "+447900000000"
},
"fallbackUrl": "https://example.com/contact"
}
}
]
}
}
}
View a Location
For this action, the action object contains a viewLocationAction property which is an object with two properties:
latLong(Object): defines the latitude and longitude of the location and contains two properties:latitude(Number): The latitude in degrees. It must be in the range [-90.0, +90.0]longitude(Number): The longitude in degrees. It must be in the range [-180.0, +180.0].
label(String): an optional property which adds a label to the pin displayed on the map.
In addition to the viewLocationAction property, the action object can contain an additional optional property:
fallbackUrl(String): this is a URL to be opened if it is not possible for the view location action to be initiated.
If this action chip is tapped, the recipient's device displays the specified location in the device's default map application.
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Drop by our office!",
"suggestions": [
{
"action": {
"text": "See location",
"postbackData": "action_1",
"viewLocationAction": {
"latLong": {
"latitude": 51.5230371,
"longitude": -0.0852492
},
"label": "Vonage London Office"
},
"fallbackUrl": "https://www.google.com/maps/place/Vonage/@51.5230371,-0.0852492,15z"
}
}
]
}
}
}
Share a Location
For this action, the action object contains a shareLocationAction property which is an empty object.
If this action chip is tapped, the recipient's device opens the default location chooser so the recipient can pick a location to send back.
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Where are you?",
"suggestions": [
{
"action": {
"text": "Share location",
"postbackData": "action_1",
"shareLocationAction": {}
}
}
]
}
}
}
Create a Calendar Event
For this action, the action object contains a createCalendarEventAction property which is an object with four properties:
startTime(String in Timestamp format): defines the event start time. A timestamp in RFC3339 UTC "Zulu" format, for example2024-06-28T19:00:00ZendTime(String in Timestamp format): defines the event end time. A timestamp in RFC3339 UTC "Zulu" format, for example2024-06-28T19:00:00Z.title(String): defines the title of the event.description(String): defines the description of the event.
In addition to the createCalendarEventAction property, the action object can contain an additional optional property:
fallbackUrl(String): this is a URL to be opened if it is not possible for the create calendar event action to be initiated.
If this action chip is tapped, the recipient's device opens the default calendar app and starts creating a new calendar event with the data defined in the createCalendarEventAction object.
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"text": "Product Launch: Save the date!",
"suggestions": [
{
"action": {
"text": "Save to calendar",
"postbackData": "postback_data_1234",
"fallbackUrl": "https://www.google.com/calendar",
"createCalendarEventAction": {
"startTime": "2024-06-28T19:00:00Z",
"endTime": "2024-06-28T20:00:00Z",
"title": "Vonage API Product Launch",
"description": "Event to demo Vonage's new and exciting API product"
}
}
}
]
}
}
}
Rich Cards
Rich cards are combinations of multiple different types of message element grouped together in a single message. Rich cards can contain:
- An image or video
- Title text
- Description text
- A list of up to four suggested replies or suggested actions (but not a combination of the two)
The exact combination of elements is fairly flexible, but a card must contain at least an image, video, or title to be valid.
The structure of rich card messages are defined in a richCard object within the contentMessage object property of the custom object:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"richCard": {
// rich card structure defined here
}
}
}
}
There two ways in which rich cards can be sent:
Standalone Rich Card
A standalone rich card is a single card containing a combination of the elements described above. The structure of a standalone card is defined within a standaloneCard object. This object has three top-level properties:
cardOrientation(String): defines the orientation of the card. Must be one ofHORIZONTAL,VERTICAL,CARD_ORIENTATION_UNSPECIFIED. Note: inHORIZONTALlayout, ifcardContentcontains themediafield it must also include at least atitle,description, orsuggestionsfield.thumbnailImageAlignment(String): defines the image preview alignment for cards withcardOrientationofHORIZONTAL. Must be one ofLEFT,RIGHT,THUMBNAIL_IMAGE_ALIGNMENT_UNSPECIFIEDcardContent(Object): contains the properties which define the content of the card
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"richCard": {
"standaloneCard": {
"cardOrientation": "HORIZONTAL",
"thumbnailImageAlignment": "LEFT",
"cardContent": {
// content of the rich card is defined here
}
}
}
}
}
}
The cardContent object can contain four properties, but must contain at least a title or media property:
title(String): The title text displayed on the card. Maximum length 200 characters.description(String): Description text displayed on the card. Maximum length 2000 characters.media(Object): defines the details of the media to include in the card. Themediaobject has two properties:height(String): defines the display height of the media. Must be one ofSHORT(112 DP),MEDIUM(168 DP),TALL(264 DP),HEIGHT_UNSPECIFIEDcontentInfo(Object): specifies the content to be displayed. This object has three properties:fileUrl(String): a publicly reachable URL of the file. Recommended maximum file size of 100 MB.thumbnailUrl(String): an optional url for a thumbnail to display while the media specified infileUrldownloads. Maximum size of 100 kB.forceRefresh(Boolean): if set totrue, the file and thumbnail are fetched from the specified URLs, even if the RBM platform has cached copies of them.
suggestions(Array): a list of suggestions to include in the card. Either suggested replies or suggested actions, but not both together. Maximum of four. See suggestions for details of the different suggestion types.
Below is one example of what the JSON for sending a standalone card might look like:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"richCard": {
"standaloneCard": {
"thumbnailImageAlignment": "RIGHT",
"cardOrientation": "VERTICAL",
"cardContent": {
"title": "Quick question",
"description": "Do you like this picture?",
"media": {
"height": "TALL",
"contentInfo": {
"fileUrl": "https://example.com/funny-cat-photo.jpg",
"forceRefresh": "false"
}
},
"suggestions": [
{
"reply": {
"text": "Yes",
"postbackData": "suggestion_1"
}
},
{
"reply": {
"text": "I love it!",
"postbackData": "suggestion_2"
}
}
]
}
}
}
}
}
}
Rich Card Carousel
Carousels can combine multiple rich cards, allowing recipients to react to each individually.
Note: The maximum size of a rich card carousel payload is 250 KB.
The structure of a rich card carousel is defined within a carouselCard object. This object has two top-level properties:
cardWidth(String): defines the width of the cards in the carousel. Must be one ofSMALL(120 DP),MEDIUM(232 DP),CARD_WIDTH_UNSPECIFIEDcardContents(Array): an array of rich card objects. The structure of these objects is the same as described for the structure of thecardContentobjects for standalone rich cards.
Below is an example of a rich card carousel containing two rich cards:
{
"to": "447900000000",
"from": "Vonage",
"channel": "rcs",
"message_type": "custom",
"custom": {
"contentMessage": {
"richCard": {
"carouselCard": {
"cardWidth": "MEDIUM",
"cardContents": [
{
"title": "Option 1: Photo",
"description": "Do you prefer this photo?",
"suggestions": [
{
"reply": {
"text": "Option 1",
"postbackData":"card_1"
}
}
],
"media": {
"height": "MEDIUM",
"contentInfo": {
"fileUrl": "https://example.com/funny-cat-photo.jpg",
"forceRefresh": "false"
}
}
},
{
"title": "Option 2: Video",
"description": "Or this video?",
"suggestions": [
{
"reply": {
"text": "Option 2",
"postbackData": "card_2"
}
}
],
"media": {
"height": "MEDIUM",
"contentInfo": {
"fileUrl": "https://example.com/cute-cat-video.mp4",
"forceRefresh": "false"
}
}
}
]
}
}
}
}
Code Snippets
Below is a list of code snippets for sending message requests for different types of custom message:
- Suggested Reply
- Suggested Action: Open URL
- Suggested Action: Dial an Number
- Suggested Action: View Location
- Suggested Action: Share Location
- Suggested Action: Create Calendar Event
- Suggested Action: Multiple Actions
- Standalone Rich Card
- Rich Card Carousel
External Documentation
Below are some links to the Google RBM documentation covering different message types sent via the Vonage Messages API RCS channel using the custom message type: