Handling push notifications (Webhook API)
Handling push notifications (Webhook API)
You can use push notifications with the Support SDK using the Webhook API.
The Zendesk Support SDK can be set up to notify the end user when an agent posts a public comment on their request.
Before you start
Before you start, the following information is useful to know:
- You can use either the Webhook API or Urban Airship to send push notifications.
- If you already have a push notifications service we recommend you use the Webhook API option. On the other side, if you don't have your own push notifications service or you are not willing to develop one, you should use the Urban Airship alternative.
- You will only receive notifications on requests that were created through the Support SDK.
- The configuration of your app in Zendesk Support must include the push notification details for your chosen option.
- If you register multiple devices with the same JWT identity, these are all added to the list of active devices for this identity so that you can send push notifications to multiple devices.
- If you switch from one integration to another, or change identities, register the devices again. Otherwise the push notifications will not be delivered properly.
Use the Webhook API for push notifications
Zendesk Support notifies an endpoint that you set up when a notification needs to be sent. After that, your service must handle sending the push notification for the end user's device.
You must set up a push notification service and then register an end user's interest in receiving push notifications on the app side.
When Zendesk Support sends a notification to the end user, it sends a POST
request to the URI set in the app configuration.
For a full webhook integration, you need to do three things:
- Configure your Support SDK App in your account
- Set up your backend to handle our callback API
- Set up your app to handle the push notification and ticket deep-linking
Account Configuration
In the Zendesk Support admin interface, select the "Webhook" option in the push notifications combo box in the Customization tab on the Mobile SDK page.
You'll be prompted to provide the Webhook URI.
Server Integration
Webhook API
As explained above, Zendesk Support sends an HTTP POST request to the URI of your service. The payload looks like this:
POST <your_push_notification_callback_uri>
Content-Type: application/json
Accept: application/json
{
"devices": [
{
"identifier": "oiuytrdsdfghjk",
"type": "ios"
},
{
"identifier": "iuytfrdcvbnmkl",
"type": "android"
}
],
"notification": {
"body": "Agent replied something something",
"title": "Agent replied",
"ticket_id": "5"
}
}
The request body is a JSON object containing the following parameters:
Name | Type | Comment |
---|---|---|
devices | array | List of devices |
notification | object | The details for the notification |
devices
Parse the devices
array to get the devices that need to receive a push notification.
Name | Type | Comment |
---|---|---|
identifier | string | The device identifier/token that was registered through the Support SDK |
type | string | The device type. Possible values: "ios" or "android" |
notification
Use the notification
object to pass along the title or body of the message, or you can customize it yourself. If you want the client app to handle deep-linking, pass the ticket_id
value in the push payload.
Name | Type | Comment |
---|---|---|
title | string | The short message of the notification |
body | string | The long message of the notification |
ticket_id | string | The identifier of the ticket that was updated. Pass this along as zendesk_sdk_request_id if you want ticket deep-linking in the app |
Note: As a best practice, provide a callback URL that's not guessable and make sure you can easily change it.
Device Delete
Apple Push Notification Service (APNS) will let you know if a user unregistered from push notifications. You need to let us know.
You can use the Push Notification Devices Bulk Unregister API to delete the devices of customers who deleted the app or are no longer registered.
Application Integration
You need to handle the following four scenarios in the app code:
You must also enable Background fetch and Remote notifications in the Background Modes section of your apps Capabilities in your project configuration.
Device registration
First, you need to ask the user for permission, as per the iOS docs.
Swift
if #available (iOS 8.0, *) {
let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound],
categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
application.registerForRemoteNotifications(matching:[.alert, .badge, .sound])
}
Objective-C
// Register the app for remote notifications in application:didFinishLaunchingWithOptions:
if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) {
UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotificationTypes:)]) {
UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:types];
}
This should result in a call to the app delegates didRegisterForRemoteNotificationsWithDeviceToken
method. The device token returned by this method is what you'll pass as the identifier parameter to the following Support SDK method:
Swift
NSLocale.preferredLanguages.first ?? "en"
ZDKPushProvider(zendesk: Zendesk.instance).register(deviceIdentifier: identifier, locale: locale) { (pushResponse, error) in
print("Couldn't register device: \(identifier). Error: \(error)")
} else {
print("Successfully registered device: \(identifier)")
}
}
Objective-C
...
NSString * locale = [[NSLocale preferredLanguages] firstObject];
[[[ZDKClassicPushProvider alloc] initWithZendesk:[ZDKClassicZendesk instance]] registerWithDeviceIdentifier:identifier locale:locale completion:^(NSString * _Nullable registrationResponse, NSError * _Nullable error) {
if (error) {
NSLog(@"Couldn't register device: %@. Error: %@ in %@", identifier, error, self.class);
} else if (registrationResponse) {
NSLog(@"Successfully registered device: %@ in %@", identifier, self.class);
}
}];
...
Note: Certain characters should be stripped from the deviceIdentifier
before registering for push notifications with Zendesk. Spaces and occurances of <
and >
should be removed.
To register for push notifications with Zendesk Support, a valid identity must be set in the Support SDK. Depending on how your app is configured, you probably won't have an identity ready in the AppDelegate
. We suggest you store the device identifier returned by Apple and register for push notifications with Zendesk Support once an identity becomes available, such as when the user signs into your app.
Device unregistration
When the user signs out or doesn't want push notifications anymore, call the following API to remove the device identifier from Zendesk Support:
Swift
ZDKPushProvider(zendesk: Zendesk.instance!).unregisterForPush()
Objective-C
[[[ZDKClassicPushProvider alloc] initWithZendesk:[ZDKClassicZendesk instance]] unregisterForPush];
Notification payload handling
Set up the delegate methods to handle the payload received as described in the iOS Notification Programming Guide on the Apple site.
When a notification is received you can handle it using the Support-SDK's deep-linking feature or handle it yourself. If you choose to handle it yourself you can retrieve the ticket and fetch its comments using an API provider.
Ticket deep-linking
You can use the Support SDK's deep linking functionality to show the ticket directly in response to a notification tap.
Presenting the Request UI
Swift
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler:
@escaping () -> Void) {
let requestID = response.notification.request.content.userInfo["tid"]
}
//Inside a UIViewController
func presentRequest(with requestID: String) {
let viewController = RequestUi.buildRequestUi(requestId: requestID)
self.navigationController?.pushViewController(viewController, animated: true)
}
Objective-C
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSString * requestID = [[[[response notification] request] content] userInfo[@"tid"]];
}
//Inside a UIViewController
-(void) presentRequest:(NSString *)requestID {
UIViewController * requestController = [ZDKRequestUi buildRequestUiWithRequestId:requestID];
[self.navigationController pushViewController:requestController animated:YES];
}
Refresh comment stream
You can refresh the comment stream if it is visible. refreshRequest
returns a boolean that indicates if the refresh was successful, e.g. the user had the ticket open at the time. If it returns false you will need to handle the notification yourself.
Swift
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler:
@escaping () -> Void) {
let requestID = response.notification.request.content.userInfo["tid"]
if Support.instance?.refreshRequest(requestId: requestID) {
return
} else {
//Handle the notification
}
}
Objective-C
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSString * requestID = [[[[response notification] request] content] userInfo[@"tid"]];
if ([[ZDKSupport instance] refreshRequestWithRequestId:requestID]) {
return;
} else {
// Handle push
}
}
If you're only using the API providers and building the UI yourself:
Swift
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler:
@escaping () -> Void) {
let requestID = response.notification.request.content.userInfo["tid"]
if Support.instance?.refreshRequest(requestId: requestID) {
return
} else {
//Handle the notification
}
}
Objective-C
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
NSString * requestID = [[[[response notification] request] content] userInfo[@"tid"]];
if ([[ZDKSupport instance] refreshRequestWithRequestId:requestID]) {
return;
} else {
// Handle push
}
}
Make sure your service is sending the zendesk_sdk_request_id
parameter to the application in the extra
section of the message you send to APNS. It should look something like this:
{
aps = {
...
alert = "There has been a reply to your message.";
...
};
...
"zendesk_sdk_request_id" = <the-request-id>;
...
}