Advanced integration

When a user taps a URL, phone number, or email address sent to a conversation, the SDK handles the event automatically by launching the default app capable of completing the action:

  • default browser for a URL
  • default phone app for a phone number
  • default email app for an email address

Note: Only URLs such as https://www.zendesk.com/ are made clickable in the UI. Other URIs such as zendesk://myapp will not be clickable.

You can customize the behavior and change what happens when the user clicks a URL by setting a MessagingDelegate. The messaging(:shouldHandleURL:from:) function will be called any time the user clicks a URL.

To prevent the SDK from opening the default browser, you should return false when this happens. In that case, you must handle the completion of the action yourself. The function receives two parameters:

  • url: the URL that was clicked
  • source: an enumeration that describes where in the UI the url was clicked, such as a text message, a carousel item, and so on.

You can find a demo app demonstrating the capability in our Zendesk SDK Demo app github.

The snippets below show how you can set a MessagingDelegate in Swift and Objective-C:

Swift
  1. Set the delegate for Messaging.
Messaging.delegate = self
  1. Handle the URL in the delegate method messaging(_ messaging: Messaging, shouldHandleURL url: URL, from source: URLSource) -> Bool.
func messaging(_ messaging: Messaging, shouldHandleURL url: URL, from source: URLSource) -> Bool {    // Your custom action...
    // Return false to prevent the SDK from handling the URL automatically    // Return true to allow the SDK to handle the URL automatically, even    // if you have done something custom    false}
Objective-C
  1. Set the delegate for ZDKMessaging.
ZDKMessaging.delegate = self
  1. Handle the URL in the delegate method - (BOOL)messaging:(ZDKMessaging * _Nonnull)messaging shouldHandleURL:(NSURL * _Nonnull)URL from:(enum ZDKURLSource)source.
- (BOOL)messaging:(ZDKMessaging * _Nonnull)messaging shouldHandleURL:(NSURL * _Nonnull)URL from:(enum ZDKURLSource)source {    // Your custom action...
    // Return false to prevent the SDK from handling the URL automatically    // Return true to allow the SDK to handle the URL automatically, even    // if you have done something custom    return NO;}

Events

The Zendesk SDK for iOS provides an event observer where you can listen for any ZendeskEvent emitted from the SDK.

You can find a demo app demonstrating the capability in our Zendesk SDK Demo app github.

Available Events

ZendeskEvent is a non-frozen enum with a case for each event that can currently be emitted. It has the following cases:

unreadMessageCountChanged

Invoked when there is a change to the current total number of unread messages.

NameTypeComment
currentUnreadCountIntThe current total number of unread messages.
authenticationFailed

Invoked when an authentication error has occurred on any of the API calls.

NameTypeComment
errorErrorDetails about the error that occurred.
conversationAdded

Invoked when a conversation has been added.

NameTypeComment
conversationIdStringThe id of the conversation that was added.
connectionStatusChanged

The SDK ZendeskConnectionStatus has changed due to an action or another event.

NameTypeComment
connectionStatusEnumThe recently developed ZendeskConnectionStatus.
sendMessageFailed

Invoked when a message fails to be sent.

NameTypeComment
errorErrorDetails about the error that occurred.

EventObserver

Swift

Below is a code sample showing how the event observer can be added and removed. The enum is non-frozen so additional cases may be added in the future.

Include a "catch-all" case @unknown default to match any value and produce a warning if all known enum cases are not matched. If additional cases are added and you do not wish to see a warning here, remove the @unknown attribute. See the snippet below:

// To add an event observer to your Zendesk instance:Zendesk.instance?.addEventObserver(self) { event in    switch event {    case .unreadMessageCountChanged(let unreadCount):        // Your custom action...    case .authenticationFailed(let error as NSError):        print("Authentication error received: \(error)")        print("Domain: \(error.domain)")        print("Error code: \(error.code)")        print("Localized Description: \(error.localizedDescription)")        // ...    case .conversationAdded(conversationId: let conversationId):        print("Conversation with the conversation id \(conversationId) was successfully created")    case .connectionStatusChanged(connectionStatus: let connectionStatus):        print("connectionStatusChanged event emitted: \(connectionStatus.stringValue)")    case .sendMessageFailed(let error as NSError):        print("Authentication error received: \(error)")        print("Domain: \(error.domain)")        print("Error code: \(error.code)")        print("Localized Description: \(error.localizedDescription)")        // ...    @unknown default:        break    }}
// To remove an event observer from your Zendesk instance:Zendesk.instance?.removeEventObserver(self)
Objective-C

Below is a code sample showing how the event observer can be added and removed.

Each case in ZDKZendeskEvent is prefixed with ZDKZendeskEvent in the following format:

ZDKZendeskEvent{EventName}

There is currently only one case to match against, but since the enum is non-frozen, there may be additional cases added in the future. For this reason, add a "catch-all" case default that matches any value.

// Get your Zendesk instance:Zendesk *instance = [Zendesk instance];
// To add an event observer to your Zendesk instance:[instance addEventObserver:self :^(enum ZDKZendeskEvent event, id _Nullable value) {    switch (event) {    case ZDKZendeskEventUnreadMessageCountChanged:        // Your custom action...    case ZDKZendeskEventAuthenticationFailed:         // Your custom action...    default:        break;    }}];
// To remove an event observer from your Zendesk instance:[instance removeEventObserver:self];

Authentication

The Zendesk SDK allows authentication of end users so that their identity can be verified by agents using Zendesk. A detailed article on the steps to set up authentication for your account is here. The steps mentioned in this article should be completed before beginning the steps below.

You can find a demo app demonstrating the capability of user authentication on our Demo app repository.

LoginUser

To authenticate a user call the loginUser API with your own JWT.

The JWT can contain the following fields:

NameTypeComment
external_idStringThe external id of the user. Required. The maximum length is 255 characters.
nameStringThe name of the user. Optional.
emailStringThe email of the user. Optional.
Swift

The result of loginUser can be observed in the optional completionHandler.

Zendesk.instance?.loginUser(with: "your_jwt_here") { result in    switch result {    case .success(let user):        // ...    case .failure(let error):        // ...    }         }
Objective-C
Zendesk *instance = [Zendesk instance];
[instance loginUserWith:@"your_jwt_here" completionHandler:^(ZDKZendeskUser * _Nullable user, NSError * _Nullable error) {    // ...}];

LogoutUser

To unauthenticate a user call the logoutUser API.

This is primarily for authenticated users but calling logoutUser for an unauthenticated user will clear all of their data, including their conversation history. Please note that there is no way for us to recover this data, so only use this for testing purposes. The next time the unauthenticated user enters the conversation screen a new user and conversation will be created for them.

Swift

The result of logoutUser can be observed in the optional completionHandler.

Zendesk.instance?.logoutUser { result in    switch result {    case .success:        // ...    case .failure(let error):        // ...    }}
Objective-C
Zendesk *instance = [Zendesk instance];
[instance logoutUserWithCompletionHandler:^(NSError * _Nullable error) {  // ...}];

Note: This will unsubscribe you from Push notifications. You will no longer receive these notifications for any of your ongoing conversations. If you log back in and get resubscribed, you will received new notifications but not the ones you missed while you were logged out.

Authentication Errors

All authentication errors can be observed through Events.

The most common error that will happen here is a HTTP 401 error. In this case a new JWT should be generated and a call made to loginUser.

Authentication Lifecycle

Once loginUser is successful, the user remains authenticated until the token expires or an error occurs.

On expiry, the server will send back a 401 HTTP error, which can be caught by using the event listener. The user will not be able to interact with Zendesk anymore and will need to be authenticated again using loginUser. If the now unauthenticated user tries to open a conversation, they will be presented with the conversation screen and an error. The conversation itself will not be shown.

As the SDK doesn't renew the token itself, you will have to handle the re-authentication process.

Visitor Path

The Visitor Path lets agents see what screen the end user had landed on, for better conversation context.

You can find a demo app demonstrating the capability in our Zendesk SDK Demo app github.

Page View Event

The PageView object encapsulates information related to a user’s interactions and passes it to the Page View Event API. These session-based page view events can be seen in Agent Workspace by support agents using Zendesk.

Swift

Below is a code sample showing how to send a Page View Event.

The API accepts a PageView object as a parameter. Pass the location of the screen that the end user is on to url and the name of the screen to pageTitle.

// Create a `PageView` objectlet pageView = PageView(pageTitle: pageTitle, url: url)Zendesk.instance?.sendPageViewEvent(pageView) { result in    // Your custom result handling...}
Objective-C

Below is a code sample showing how to send a Page View Event.

The API accepts a PageView object as a parameter. Pass the location of the screen that the end user is on to url and the name of the screen to pageTitle.

// Get your Zendesk instance:Zendesk *instance = [Zendesk instance];// Create a PageViewZDKPageView *pageView = [[ZDKPageView alloc] initWithPageTitle:@"page title" url:@"www.example.com"];[zendesk sendPageViewEvent:pageView completionHandler:^(NSError *error) {    if (error != nil) {        // handle error    }}];

Proactive messaging

Proactive messaging can deliver targeted local push notifications to your users through your mobile SDK channel when triggering pre-defined conditions. See Creating proactive messages for mobile SDK channels for information on creating a proactive messaging campaign for your channel. The steps mentioned in the article should be completed before performing the steps below.

Local push notifications

Proactive messaging uses iOS local notifications to deliver messages to users that meet your pre-defined conditions.

The ZendeskSDK will request notification permission from the user (if they haven't been prompted previously) so a proactive message can be displayed.

Follow the steps in implementing push notifications in your app's codebase to ensure your project can handle the push notifications actions correctly.
You must implement the handleTap function inside userNotificationCenter(didReceive) to display the conversation view after the end user taps on the proactive Message notification.

You can find a demo app demonstrating the capability in our Zendesk SDK Demo app github.

Swift
PushNotifications.handleTap(userInfo) { viewController in    // Handle displaying the returned viewController in here}
Objective-C
[ZDKPushNotifications handleTap:userInfo completion:^(UIViewController * _Nullable viewController) {    // Handle displaying the returned viewController in here}];

Relationship with the Page View event

A proactive messaging campaign is evaluated when triggered by the Page View Event integration. It is essential that for each screen the user visits, the page view event is correctly updated to reflect this.

For example, suppose you have a campaign that triggers when the user is on a particular product screen for 30 seconds. If the user navigates to a different screen after 25 seconds, and there's no subsequent page view event sent, the user will receive a proactive message notification.

Customization

The style of the Zendesk SDK can be set through Admin Center which currently includes the primary color, the message color and the action color.

There is additional customization support available for setting text colors through the SDK using the following API. Please note this is a temporary API which will be available until the same feature is supported in Admin Center. This API will then be deprecated.

When initializing the Zendesk SDK, different text colors can now be passed as parameters to compliment the available style colors, with support for both light and dark mode.

Swift
let colors = UserColors(onPrimary: .black,                         onMessage: .black,                         onAction: .black)let factory = DefaultMessagingFactory(userLightColors: colors,                                       userDarkColors: colors)Zendesk.initialize(withChannelKey: "channel_key",                     messagingFactory: factory) { result in    // ...}
Objective-C
ZDKUserColors *colors = [[ZDKUserColors alloc] initOnPrimary:UIColor.blackColor                                                   onMessage:UIColor.blackColor                                                    onAction:UIColor.blackColor];ZDKDefaultMessagingFactory *factory = [[ZDKDefaultMessagingFactory alloc] initWithUserLightColors:colors                                                                                   userDarkColors:colors];[Zendesk initializeWithChannelKey:@"channel_key"                 messagingFactory:factory                completionHandler:^(Zendesk * _Nullable zendesk, NSError * _Nullable error) {    // ...}];

Messaging Metadata

To learn more about Messaging Metadata, see Introduction to Messaging Metadata.

Note: The SDK must be initialized before using any of these methods. See Initialize the SDK for more details.

You can find a demo app demonstrating the capability in our Zendesk SDK Demo app github.

Conversation Fields

Set Conversation Fields

Allows values for conversation fields to be set in the SDK to add contextual data about the conversation.

Zendesk.instance.messaging.setConversationFields(_ fields: [String : AnyHashable])

Conversation fields must first be created as custom ticket fields and configured to allow their values to be set by end users in Admin Center. To use conversation fields, see Using Messaging Metadata with the Zendesk Web Widgets and SDKs.

The values stored are persisted, and will be applied to all conversations going forward. To remove conversation fields stored in the SDK, use the clearConversationFields API.

Note: Conversation fields are not immediately associated with a conversation when the API is called. Calling the API will store the conversation fields, but those fields will only be applied to a conversation when end users either start a new conversation or send a new message in an existing conversation.

Note: An event for handling failed validation checks on conversation fields set using the setConversationFields API will be added in an upcoming release of the Zendesk SDK.

System ticket fields, such as the Priority field, are not supported.

Parameters

fields: [String : AnyHashable]: Is a dictionary of key-value pairs.

TypeDescription
Stringid of custom ticket field
AnyHashablevalue of the custom ticket field

Note: The supported types for AnyHashable are string, number and boolean.

Example

For example, if the id of your custom text field for a flight number is 4422761977114 and you want to set its value to FA2590, then you would call:

Swift
Zendesk.instance.messaging.setConversationFields(["4422761977114": "FA2590"])
Objective-C
[Zendesk.instance.messaging setConversationFields:@{@"4422761977114": @"FA2590"}];
Clear Conversation Fields

You can clear conversation fields from the SDK storage when the client side context changes. To do this, use the clearConversationFields API. This removes all stored conversation fields from the SDK storage.

Note: This API does not affect conversation fields already applied to the conversation.

Example
Swift
Zendesk.instance.messaging.clearConversationFields()
Objective-C
[Zendesk.instance.messaging clearConversationFields];

Conversation Tags

Set Conversation Tags

Allows custom conversation tags to be set in the SDK to add contextual data about the conversation.

Zendesk.instance.messaging.setConversationTags(_ tags: [String])

To use conversation tags, refer to Using Messaging Metadata with the Zendesk Web Widgets and SDKs.

Note: Conversation tags are not immediately associated with a conversation when the API is called. It will only be applied to a conversation when end users either start a new conversation or send a new message in an existing conversation.

Parameters

[String] An array of strings.

TypeDescription
[String]The array of custom tags to be provided.
Example

For example, to apply promo_code and discount tags to a conversation about an order, then you would call:

Swift
Zendesk.instance.messaging.setConversationTags(["promo_code", "discount"])
Objective-C
[Zendesk.instance.messaging setConversationTags:@[@"promo_code", @"discount"]];
Clear Conversation Tags

Allows you to clear conversation tags from SDK storage when the client side context changes. To do this, use the clearConversationTags API. This removes all stored conversation tags from the SDK storage.

Note: This API does not affect conversation tags already applied to the conversation.

Example
Swift
Zendesk.instance.messaging.clearConversationTags()
Objective-C
[Zendesk.instance.messaging clearConversationTags];

Postback Buttons in Messaging

Introduction

Postback buttons are a great way to enhance your conversations, since they can trigger server-side logic when a user clicks on them. When you send the postback button, you can attach a payload and when the user clicks on it, it will trigger webhooks listening to the postback trigger. The payload associated with the action clicked by the user will be included in the webhook body. This allows you to respond to the press of a button from your backend. The server-side logic can use the payload to run different code based on the context of the conversation. These features are very useful when building a bot. You can also use them to trigger other server-side actions with the click of a button in the conversation, such as an “add-to-cart” action.

Sending postback buttons

Postback buttons will soon be leveraged by the Zendesk FlowBuilder in carousel messages, so you will be able to create carousel buttons for your Zendesk Bot that will save the user's response and proceed the flow accordingly. You can also send postback buttons by using the Sunshine Conversations API. (Note that a Zendesk Suite Professional plan or above is required to send the postback buttons via the Sunshine Conversations API.)

You can use postback buttons together with other button types in the same message, as seen below, with the exception of reply buttons. (Reply buttons can not be used together with postback buttons or any other button type supported in Messaging.)

const apiInstance = new SunshineConversationsApi.MessagesApi();const data = new SunshineConversationsApi.MessagePost();data.author = {    type: 'business'};data.content = {    type: 'text',    text: 'Press one of the buttons below',    actions: [        {            type: 'postback',            text: 'Postback Button Label',            payload: 'PAYLOAD_HERE'        },        {            type: 'link',            text: 'Link Button Label',            uri: 'http://url.button.com'        }    ]};
apiInstance.postMessage(appId, conversationId, data)    .then(response => /* success */)    .catch(error => /* failure */);
Setting up your conversation integrations

When you send postback buttons via the Sunshine Conversations API, in order for the buttons to trigger webhooks, you will need to set up “conversation integrations” and subscribe for postback events. Here is more information on how you can set up conversation integrations.

Echo Postbacks

The ‘echoPostback’ allows you to add a message to the conversation history when a postback button is clicked. The content of the message will match the button label. When ‘echoPostback’ is enabled, the message will be silently added to the conversation as a user message, without a corresponding ‘conversation:message’ webhook being triggered. To enable ‘echoPostback’ a request must be made to update the app via the Sunshine Conversations API.

Swift concurrency: async/await

The public APIs of the Zendesk SDK support async/await operations. This feature is available only on iOS 13.0.0 and above.

Example
  • Initialize the Zendesk SDK and present the messaging view.
Task {    do {        let zendesk = try await Zendesk.initialize(withChannelKey: Const.channelKey, messagingFactory: DefaultMessagingFactory())        if let messagingViewcontroller = zendesk.messaging?.messagingViewController() {            // Present the messaging view controller according to your preference            // for example:            navigationController?.pushViewController(messagingViewcontroller, animated: true)        }    } catch let error {        // Handle any initialization error    }}
  • Authenticate and unauthenticate a user:
func login() {    Task {        do {            let zendeskUser = try await Zendesk.instance?.loginUser(with: "JWT")        } catch let error {            // Handle any authentication error        }    }}
func logout() {    Task {        do {            try await Zendesk.instance?.logoutUser()        } catch let error {            // Handle any authentication error        }    }}
  • Send a page view event that captures a specific user interaction to the PageView endpoint:
// Create a `PageView` objectlet pageView = PageView(pageTitle: pageTitle, url: url)Task {    do {        try await Zendesk.instance?.sendPageViewEvent(pageView)    } catch let error {        // Handle any error    }}

Invalidate the SDK

Invalidating the Zendesk SDK will end its current instance. The invalidate() function now supports clearing the internal storage through a boolean parameter. When the parameter is set to true it will clear all non essential data to ensure this data doesn't accumulate over time. If clearing storage not intended to be performed during invalidation, it will be cleared when the end user logs out. The default value of the parameter is set to false to keep the previous behaviour of the SDK. It is important to remember that once the Zendesk SDK is invalidated no messages nor notifications will be received.

Example
Swift
Zendesk.invalidate(true)
Objective-C
[Zendesk invalidateClearStorage:YES];

Switching between Instances

The Zendesk SDK enables switching between different instances at runtime, which is useful for running multiple instances within a single application. To use this feature, the invalidate function must be set to false.

Example
Swift
Zendesk.invalidate(false)
Objective-C
[Zendesk invalidateClearStorage:NO];