Apple Business Chat is a channel built to reach customers through Messages on any Apple device. The channel prides itself on its rich set of messaging features including bot and AI capabilities, security, and ability to connect to the wide world of iOS apps and add-ons.
Apple Business Chat is used for customer service interactions, scheduling tasks, and even payments. This means that customers interact with brands as easily as they message their friends and family. It’s discoverable from Apple Maps, Safari, and Search— or directly embedded into a brand’s website.
Apple Business Chat requires all businesses to register with Apple before rolling out Business Chat. A business will need to submit brand information, including addresses and logos, for Apple’s approval. As part of this process, you’ll be prompted to select a Messaging Service Provider. Here is where Zendesk’s Sunshine Conversations comes into play— as a Messaging Service Provider, we are certified by Apple to provide services and solutions for your Business Chat needs. At the end of the registration process, you’ll receive a unique Business Chat ID that will be used to connect to Sunshine Conversations
There are 4 steps to complete your Business Chat Account in the Apple Business Register:
Sign into the Business Register and add a Business Chat Account
Go to register.apple.com
You’ll be directed to a Manage Services page
Click on Business Chat Accounts
You’ll need to provide
Fill in your Brand Identity details
Complete your Brand Information Card
Select Zendesk- Sunshine Conversations as your Messaging Service Provider
Finally, click Send for review to submit your application to Apple. You’ll be able to see the status of your application at the top of your Business Chat Account page.
After you’ve been approved by Apple for Business Chat, you’ll be issued a Business Chat ID.
You can find the Business Chat ID by going to your Business Chat Account page and scrolling down to the Messaging Service Provider section.
From there, click on Test your Messaging Service Provider connection.
After that, you’ll be directed to a page where you can copy your Business Chat ID.
Apple supports a wide variety of capabilities as seen in the channel capabilities grid. Below is a detailed view of each capability.
Delivery events allow you to track deliveries of Sunshine Conversations messages to Apple Business Chat by subscribing to the conversation:message:delivery:channel
webhook. Failures to deliver a message to Apple Business Chat can be detected by subscribing to the conversation:message:delivery:failure
webhook.
Apple’s documentation can be found here.
You will need to do the following:
<div>
container to house the buttonThe Business Chat button must contain the following, at minimum:
data-apple-business-id
attribute with the business ID you received when you registered your company with Business Chat.If you don’t have a Sunshine Conversations account yet, contact us from the Test your Messaging Service Provider connection in the Business Register to continue the integration process. From that page, you can click on the Connect button to send you to the Sunshine Conversations site.
Log into the Apple Business Register
In a separate tab, log into your Sunshine Conversations Dashboard
Copy your Business Chat ID from the Test your Messaging Service Provider connection page in Apple Business Register
In the Sunshine Conversations Dashboard, select ABC from the list of channel integrations
Next, complete the following steps to connect your ABC integration
Since Business Chat IDs are public, Sunshine Conversations has implemented a security measure to ensure your brand’s Business Chat ID stays linked to your Sunshine Conversations app. This means that a Business Chat ID cannot be migrated from one app to another through the dashboard or API. If you need to remove your Apple Business Chat integration and migrate it to another app, please contact our team for assistance using the help widget in your dashboard. Our team will release the Business Chat ID on your behalf.
There are 3 different IDs required in the payload:
Apple makes it possible to publish a URL for users to tap that will bring them into iMessage to chat with the business.
In order to provide some context to the business about which link was clicked by the user, the biz-intent-id
and biz-group-id
parameters can be included as querystring parameters on the URL:
https://bcrw.apple.com/urn:biz:{businessId}?biz-intent-id=TestingBizIntent&biz-group-id=TestingBizGroup
Group and intent are both optional. If both are left unspecified, the client.raw
object will be absent and the message.source.group
and message.source.intent
fields will be absent.
Whenever Sunshine Conversations receives a group or intent attached to an Apple Business Chat message, these values will be exposed in both the Sunshine Conversations message and client objects. For example, after a user clicks on such a link, the first message received by that user will trigger a message:appUser
webhook like this:
{
"trigger": "message:appUser",
"app": { "_id": "599349ff5f753aecf2e151c9" },
"messages": [
{
"authorId": "caf1dbe12cee751407bd53a6",
"received": 1512587862.523,
"type": "text",
"text": "Hi",
"name": "Glass Chameleon",
"role": "appUser",
"_id": "5a284256fbbc83ffb792e31c",
"source": {
"type": "apple",
"group": "TestingBizGroup",
"intent": "TestingBizIntent"
}
}
],
"appUser": {
"_id": "caf1dbe12cee751407bd53a6",
"signedUpAt": "2017-12-06T16:59:11.355Z",
"conversationStarted": true,
"credentialRequired": true,
"clients": [
{
"raw": {
"group": "TestingBizGroup",
"intent": "TestingBizIntent"
},
"id": "1da8d244-a389-4240-ae6e-4b6975c88236",
"platform": "apple",
"linkedAt": "2017-12-06T16:59:11.357Z",
"lastSeen": "2017-12-06T19:17:42.476Z",
"active": true,
"primary": true
}
]
}
}
Any group or intent received from Apple will be persisted in the client object. Each subsequent message:appUser
webhook payload will include those fields.
The last known group or intent will also be included under the message.source
, and will be replayed in future messages coming from that user so long as neither changes.
Clients and messages can also be retrieved at a later date via the user API and messages API respectively.
A user can click a different business chat link with different biz-*
query parameters, thus changing the conversation’s group and intent. In this case, client.raw.group
and client.raw.intent
will be individually updated with any new values. Group and intent values that were received with previous messages will still be preserved in the message history under that message’s source.group
and source.intent
parameters.
If a user unsubscribes, the group and intent stored on the client will be cleared. If they later change their mind and send a new message to the business (without having clicked a business chat link with query parameters) these parameters will be absent from the smooch client.
The passthrough API is a way to send message types for which there is no corresponding Sunshine Conversations type or to leverage channel-specific features not folded into the Sunshine Conversations API (e.g. Apple list or time pickers.) To accomplish this, the developer provides Sunshine Conversations with the raw payload to send to the messaging provider’s API, and the Sunshine Conversations platform will “pass it through”.
To use the passthrough API, you first craft a valid Sunshine Conversations message of any type, then you specify an additional override parameter for the channels you would like to use passthrough. Under the channel name (in this case abc), the payload field contains the exact structure of a valid Apple Business Chat Service API call to the Message endpoint.
The passthrough API described below has been introduced so that it’s possible to send any message type to Apple Business Chat.
While the passthrough API accepts payloads up to 100kb, building Business Chat messages often result in payloads larger than 100kb. For instance, when sending a list picker with an image associated with each item, those images must be directly included inside the payload (using base64 encoding). To get past this limitation, Sunshine Conversations exposes new large message and large template APIs that handle payloads up to 10mb.
We recommend using templates where possible, to avoid crafting complex messages each time they’re sent and also to avoid network delays when sending large messages.
To use the passthrough API, you first craft a valid message of any type, then you specify an additional override
parameter for the channels you would like to use passthrough.
Example:
{
"role": "appMaker",
"text": "Hello there",
"type": "text",
"override": {
"apple": {
"payload": {
"body": "goodbye",
"type": "text"
}
}
}
}
The above example depicts a simple override example, where the text message will render as “Hello there” on every channel except Apple, where it would render as “goodbye”. Note that type and body are Apple-specific fields, exactly as the Apple API would accept them.
Business Chat requires images (aka large interactive data) to be embedded as base64 strings inside message JSON payloads. This tends to make JSON payloads large. However, our standard /messages API only supports payloads up to 100kb. We provide a large message and large template API to support payloads up to 10mb.
In order to ensure the message is correctly delivered, Sunshine Conversations will automatically set some fields in the payload for you. If you supply these fields, they will be ignored and replaced:
Reserved Key | Reserved Behaviour |
---|---|
v | Specifies the version of the message schema to use. Sunshine Conversations will automatically set this to 1 |
id | A unique identifier (in UUID format) for the message. Sunshine Conversations will automatically generate and populate this value |
sourceId | The unique identifier of the calling business. Sunshine Conversations will populate this value based on the configured integration |
destinationId | The unique identifier of the user. Sunshine Conversations will populate this value based on the target user |
Rich links can contain an image or video preview. For the image, you must provide the image in Base64 encoding. You can obtain this through a library or 3rd party website.
Example of a rich link with an image preview:
{
"role": "appMaker",
"type": "text",
"text": "Hello there!",
"override": {
"apple": {
"payload": {
"body": "https://smooch.io/",
"type": "richLink",
"richLinkData": {
"url": "https://smooch.io/",
"title": "Title",
"assets": {
"image": {
"data": "put base64 encoded image here",
"mimeType": "image/jpg"
}
}
}
}
}
}
}
Example of a Rich link with a video preview:
{
"role": "appMaker",
"type": "text",
"text": "Hello there",
"override": {
"apple": {
"payload": {
"body": "https://smooch.io/",
"type": "richLink",
"richLinkData": {
"url": "https://smooch.io/",
"title": "Title",
"assets": {
"video": {
"url": "https://images.apple.com/media/us/homepod/2018/98e6cc1a_37ec_4e69_b717_9e58c71e1937/films/expand/homepod-expand-tpl-cc-us-20180306_1280x720h.mp4",
"mimeType": "video/mp4"
}
}
}
}
}
}
}
For some message types, it might be necessary to send attachments. In such cases, you should refer to the Apple documentation for instructions on how to upload those resources to Apple, and pass the object reference to Sunshine Conversations using the passthrough API.
Example:
{
"role": "appMaker",
"text": "Hello there",
"type": "image",
"mediaType": "image/png",
"mediaUrl": "https://marketplace-cdn.smooch.io/apple/icon.png",
"override": {
"apple": {
"payload": {
"attachments": [
{
"decryption-key": "00260450bb05cd4597a8ae706199f685c0f6fafee4b6c3e1375771c472f4149e29",
"file-size": "10159",
"mime-type": "image/png",
"mmcs-owner": "M39303332653438322d396338342d313165372d613330332d633735336231626666366661.C01USN00",
"mmcs-signature-base64": "AXG58GIo7xWZz7gRXZH2liWuzVah",
"mmcs-url": "https://p97-content.icloud.com",
"name": "icon.png"
}
],
"body": "goodbye \ufffc",
"type": "text"
}
}
}
}
A sample list picker payload sent through the passthrough API:
{
"role": "appMaker",
"text": "Hello there",
"override": {
"apple": {
"payload": {
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"images": [],
"listPicker": {
"multipleSelection": true,
"sections": [
{
"items": [
{
"identifier": "taco-appetizer",
"order": 0,
"style": "default",
"subtitle": "Great tacos",
"title": "Tacos"
},
{
"identifier": "burrito-appetizer",
"order": 1,
"style": "default",
"subtitle": "Good burritos",
"title": "Burritos"
}
],
"order": 0,
"title": "Appetizers"
},
{
"items": [
{
"identifier": "taco-meal",
"order": 0,
"style": "default",
"subtitle": "Great tacos",
"title": "Tacos"
},
{
"identifier": "burrito-meal",
"order": 1,
"style": "default",
"subtitle": "Good burritos",
"title": "Burritos"
}
],
"order": 1,
"title": "Meals"
}
]
},
"mspVersion": "1.0",
"requestIdentifier": "food-picker-1"
},
"receivedMessage": {
"style": "small",
"subtitle": "Let's eat!",
"title": "FoodPicker"
},
"replyMessage": {
"style": "large",
"subtitle": "Nutrition",
"title": "Selected food"
}
},
"type": "interactive"
}
}
}
}
A sample time picker payload sent through the passthrough API:
{
"role": "appMaker",
"text": "Hello there",
"override": {
"apple": {
"payload": {
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"event": {
"identifier": "reservation-id",
"timeslots": [
{x
"duration": 3600,
"identifier": "7-am",
"startTime": "2018-10-24T07:00+0000"
},
{
"duration": 3600,
"identifier": "8-am",
"startTime": "2018-10-24T08:00+0000"
}
],
"timezoneOffset": 400,
"title": "Available Reservations"
},
"mspVersion": "1.0",
"requestIdentifier": "appointment-selector-1"
},
"receivedMessage": {
"style": "icon",
"title": "Make a reservation"
},
"replyMessage": {
"style": "icon",
"title": "Your reservation"
}
},
"type": "interactive"
}
}
}
}
A sample custom extension (e.g. iMessage App) payload sent through the passthrough API:
{
"role": "appMaker",
"type": "text",
"text": "Hello there",
"override": {
"apple": {
"payload": {
"attachments": [
{
"decryption-key": "00260450bb05cd4597a8ae706199f685c0f6fafee4b6c3e1375771c472f4149e29",
"file-size": "10159",
"mime-type": "image/png",
"mmcs-owner": "M39303332653438322d396338342d313165372d613330332d633735336231626666366661.C01USN00",
"mmcs-signature-base64": "AXG58GIo7xWZz7gRXZH2liWuzVah",
"mmcs-url": "https://p97-content.icloud.com",
"name": "icon.png"
}
],
"interactiveData": {
"URL": "?options=tacos,burritos",
"appId": 34554,
"appName": "Your App Name",
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:ABCD5678:com.yourDomain.MessagesExtension",
"receivedMessage": {
"imageSubtitle": "Image Subtitle",
"imageTitle": "Image Title",
"secondarySubtitle": "Trailing Caption",
"subtitle": "Subcaption",
"tertiarySubtitle": "Trailing Subcaption",
"title": "Caption"
},
"useLiveLayout": false
},
"type": "interactive"
}
}
}
}
Prerequisites for sending ApplePay payment requests include:
Apple Pay Merchant ID including:
developer.apple.com
)register.apple.com
)Valid MerchantSession
object, obtained from Apple’s API
Sent using passthrough API, according to the Apple specification here
Responses are sent to the function-specific URL(s) specified in the request (in the interactiveData.data.payment.endpoints
object)
To receive passthrough messages, subscribe to one of the passthrough webhook triggers through the Sunshine Conversations API. Note that these triggers must be explicitly subscribed for via the Sunshine Conversations API; they are not included in the *
trigger.
Trigger | Usage |
---|---|
passthrough:apple:extension | Triggered when a custom extension message is received |
passthrough:apple:interactive | Triggered when a list picker, time picker, or other
interactiveDataRef
is received |
The passthrough webhook payload includes the associated app
, appUser
, source
, and raw payload received from Apple.
Here is an example passthrough payload for a list picker selection:
{
"app": { "_id": "59a8866f19ac1e893d8f39fe" },
"appUser": { "_id": "12130c355cf163c2dca397a9" },
"payload": {
"apple": {
"destinationId": "9032e482-9c84-11e7-a303-c753b1bff6fa",
"id": "45e36836-fa85-41a1-8c25-359e6c941d40",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"listPicker": {
"multipleSelection": true,
"sections": [
{
"items": [
{
"identifier": "taco-appetizer",
"order": 0,
"style": "default",
"subtitle": "Great tacos",
"title": "Tacos"
},
{
"identifier": "taco-meal",
"order": 0,
"style": "default",
"subtitle": "Great tacos",
"title": "Tacos"
}
],
"order": 0,
"title": "You Selected"
},
{
"items": [
{
"identifier": "burrito-appetizer",
"order": 1,
"style": "default",
"subtitle": "Good burritos",
"title": "Burritos"
},
{
"identifier": "burrito-meal",
"order": 3,
"style": "default",
"subtitle": "Good burritos",
"title": "Burritos"
}
],
"order": 1,
"title": "Others"
}
]
},
"mspVersion": "1.0",
"requestIdentifier": "food-picker-1"
}
},
"sourceId": "urn:mbid:AQAAY5fm8C1h9GM7PJdHm1px6YYbfTH7R5Psfj0Lhh9dYbswZ+zfZekvmh6j1zuXMs7bovQJZ4d1Mw3TssgRy7mu1dXyTAY2uFrMhLt2HQILH5E6Jyq7VhpncbbIm58Ow4J6PbwgyaShPuccYT67n2TzF98KNOs=",
"type": "interactive",
"v": 1
}
},
"source": { "type": "apple" },
"trigger": "passthrough"
}
Users can opt out from receiving further messages. When a customer deletes a conversation in Messages, a dialog appears that asks if they want to stop receiving messages from the business. If the customer chooses to stop receiving messages, Business Chat considers the conversation closed and sends a message of type close
to the Sunshine Conversations. You can read more about this in Apple’s Developer Docs.
Upon receiving a close
message, Sunshine Conversations will set client.status: blocked
on the client with platform: "apple"
of the corresponding appUser
.
A client:block
event will also be POSTed to subscribed webhooks.
The existing Sunshine Conversations /messages
and /templates
APIs will not accept payloads larger than 100kb.
In order to remain compatible with Apple’s large payloads, Sunshine Conversations offers separate APIs designed specifically for handling large Apple Business Chat override payloads. The existing Sunshine Conversations /messages
and /templates
API accept the override parameter inside JSON payloads smaller than 100kb while a separate set of APIs will be offered that are designed to accept much larger payloads, up to 10mb.
Standard Sunshine Conversations API (v1) | Large Apple paylaods equivalent |
---|---|
POST
/v1/apps/:appId/appusers/:userId/messages | POST
/v1/apps/:appId/appusers/:userId/messages/large |
POST
/v1/apps/:appId/templates | POST
/v1/apps/:appId/templates/large |
PUT
/v1/apps/:appId/templates/:templateId | PUT
/v1/apps/:appId/templates/:templateId/large |
The large payload APIs may only be used for apps that have a valid ABC integration configured.
We strongly recommend using templates for sending large Business Chat messages whenever possible as constantly transferring the same large payload when sending the same content to multiple users generates unnecessary network traffic, which may cause message delivery latency.
The large payload APIs behave the same as their conventional equivalents, except for two key differences:
override.apple.payload
(or message.override.apple.override
for templates) is required in the request bodyLarge message and template processing is deferred to a processing queue and therefore large payload APIs return 202 Accepted along with a requestId. For example:
{"requestId":"dkgSujU2R62HF3W9PnRIGy8K"}
This requestId
can be used to track the success or failure of the request (message delivery or template creation/update) via two new webhook triggers: request:success
and request:failure
. The request body of request:success
webhooks have a response key, whose value matches the structure returned from the associated standard API. request:failure
webhooks have an “error” key mapping to an object containing error details. Possible error codes can be found here.
Example for POST /v1/apps/:appId/appusers/:userId/messages/large
:
request:success
example:
{
"trigger": "request:success",
"app": { "_id": "564f56151d195e2100c49f13" },
"appUser": { "_id": "4f75e8d7c26953e0df65bb40" },
"requestId": "dkgSujU2R62HF3W9PnRIGy8K",
"timestamp": 1534173863.84,
"response": {
"message": {
"_id": "5b71beb728ef8677a427c769",
...
},
"conversation": {
"_id": "1f706345a613e803962dfe54",
...
}
}
}
request:failure
example:
{
"trigger": "request:failure",
"app": { "_id": "564f56151d195e2100c49f13" },
"appUser": { "_id": "4f75e8d7c26953e0df65bb40" },
"requestId": "dkgSujU2R62HF3W9PnRIGy8K",
"error": {
"code": "bad_request",
"message": "Invalid JSON"
},
"timestamp": 1534173863.84
}
SUNSHINE_CONV_ROOT='https://api.smooch.io'
APP_ID='your_app_id'
APP_USER_ID='app_user_id'
MESSAGE=$(cat <<-END
{
"type": "text",
"text": "Hello non-apple channel",
"role": "appMaker",
"override": {
"apple": {
"payload": {
"type": "interactive",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"version": "1.0",
"requestIdentifier": "",
"images": [
{
"data": "base64encoded-image-file",
"identifier": "1"
},
{
"data": "base64encoded-image-file",
"identifier": "2"
},
{
"data": "base64encoded-image-file",
"identifier": "3"
}
],
"listPicker": {
"sections": [
{
"title": "Appetizers",
"order": 0,
"items": [
{
"title": "Tacos",
"order": 0,
"identifier": "taco-appetizer",
"imageIdentifier": "2"
},
{
"title": "Burritos",
"order": 1,
"identifier": "burrito-appetizer",
"imageIdentifier": "3"
}
]
},
{
"title": "Meals",
"order": 1,
"items": [
{
"title": "Tacos",
"order": 0,
"identifier": "taco-meal",
"imageIdentifier": "2"
},
{
"title": "Burritos",
"order": 1,
"identifier": "burrito-meal",
"imageIdentifier": "3"
}
]
}
]
}
},
"receivedMessage": {
"style": "small",
"title": "Food Picker",
"subtitle": "Let\"s eat!",
"imageIdentifier": "1"
},
"replyMessage": {
"style": "small",
"title": "Selected food",
"subtitle": "Nutrition"
}
}
}
}
}
}
END
)
curl $SUNSHINE_CONV_ROOT/v1/apps/$APP_ID/appusers/$APP_USER_ID/messages/large \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: Bearer your-account-jwt' \
-d "$MESSAGE"
curl $SUNSHINE_CONV_ROOT/v1/apps/$APP_ID/templates/large \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: Bearer your-account-jwt' \
-d '{
"name": "test-template-1234",
"message":'"$MESSAGE"'
}'
TEMPLATE_ID='your_template_id'
curl $SUNSHINE_CONV_ROOT/v1/apps/$APP_ID/templates/$TEMPLATE_ID/large \
-X PUT \
-H 'content-type: application/json' \
-H 'authorization: Bearer your-account-jwt' \
-d '{
"name": "new-template-name",
"message":'"$MESSAGE"'
}'
Just like the traditional /messages
API, /messages/large
can be used to send messages to users on channels other than Apple Business Chat. If you wish to target a user’s Apple client specifically you can do so via channel targeting.
Sending a large template is done using the standard /messages
API, as described here.
It’s possible to convert a standard template to a large one by calling the PUT /templates/:templateId/large
endpoint. Converting a large template to a standard one is also possible by calling the PUT /templates/:templateId
endpoint and providing the message in the request body.
Large templates are deleted the same way as standard templates, by calling the DELETE /templates/:templateId
endpoint.
Fetching large templates can be achieved by using the same APIs as for standard templates (GET /templates
and GET /templates/:templateId
). An isLarge
property set to true
will be included only for large templates (it won’t be present for standard templates.) Note that when retrieving a large template, the response will not include the Apple override section.