Handle push notifications (Webhook API)

This is the developer guide for the Support SDK v1 for Android. For Support SDK v2, see Support SDK v2 Android.

This feature is only available on the Team, Professional, and Enterprise plans.

This page shows you how to 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 to 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 switch from one integration to another, 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:

  1. Configure your Support SDK App in your account
  2. Set up your backend to handle our callback API
  3. 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.

Push Notifications Webhook Configuration

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

Google Cloud Messaging (GCM) will let you know if a user unregistered from push notififcations. You need to let us know too.

You can use the Push Notification Devices Bulk Unregister API to delete the devices of customers that deleted the app or are no longer registered.

Application Integration

You need to handle the following four scenarios in the app code:

Device registration

You need to register devices interested in receive push notifications with Zendesk Support.

First, go through the following guide from Google on implementing a GCM Client on Android: Implementing GCM Client on Android. The GCM API will issue an id after registration.

Second, send the id to your Zendesk Support instance through the Support SDK API to register the device:

ZendeskConfig.INSTANCE.enablePushWithIdentifier("<registration id>", new ZendeskCallback<PushRegistrationResponse>() {
    @Override
    public void onSuccess(PushRegistrationResponse pushRegistrationResponse) {

    }

    @Override
    public void onError(ErrorResponse errorResponse) {

    }
});
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:

ZendeskConfig.INSTANCE.disablePush("<registration id>", new ZendeskCallback<Response>() {
    @Override
    public void onSuccess(Response response) {

    }

    @Override
    public void onError(ErrorResponse errorResponse) {

    }
});
Notification payload handling

Set up your BroadcastReceiver or IntentService to receive and handle push notifications. Extract the payload from the given intent and show a notification.

When a notification is received you have the option of using the Support SDK's deep-linking feature to handle the notification or handling 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.

Acquire an Intent

Use one of the methods provided by ZendeskDeepLinking.INSTANCE to get an Intent.

/**
 * Get an pre-configured {@linkplain android.content.Intent} to open a request.
 *
 * @param context               An application context
 * @param requestId             A valid requestId
 * @param subject               A subject
 * @param backStackActivities   A list of back stack activities
 * @param fallbackActivity      An activity that will be shown, if something fails (e.g. user configuration changed)
 * @return                      An intent
 */
@Nullable
public Intent getRequestIntent(
    Context context,
    String requestId,
    @Nullable String subject,
    @Nullable ArrayList<Intent> backStackActivites,
    @Nullable Intent fallbackActivity
);

/**
 * Get an pre-configured {@link Intent} to open a request.
 *
 * @param context               An application context
 * @param requestId             A valid requestId
 * @param subject               A subject
 * @param backStackActivities   A list of back stack activities
 * @param fallbackActivity      An activity that will be shown, if something fails (e.g. user configuration changed)
 * @param zendeskUrl            The full URL of your Zendesk Support instance, https://{subdomain}.zendesk.com
 * @param applicationId         The application id of your SDK app, as found in the web interface
 * @param oauthClientId         The oauth client id that was supplied when you set up oauth in the
 *                              web interface
 * @return                      An intent
 */
public Intent getRequestIntent(
    Context context,
    String requestId,
    @Nullable String subject,
    @Nullable ArrayList<Intent> backStackActivities,
    @Nullable Intent fallbackActivity,
    String zendeskUrl,
    String applicationId,
    String oauthClientId
);

It's important to make sure that ZendeskConfig is initialized. If it isn't, getRequestIntent() will return null. If you want to use deep linking in an IntentReceiver or BroadcastReceiver, keep in mind that your ZendeskConfig could be uninitialized even if you've initialized it in an Activity or Fragment.

Do the following to prevent the Intent from being null:

  1. Initialize ZendeskConfig before acquiring an Intent.
  2. Use the overloaded method getRequestIntent(), which accepts a Zendesk Support URL, application ID, and oAuth client ID.

To preserve the navigation flow, you can specify a list of back stack intents. These activities will be shown if the user presses back. Also, you can add a fallback Activity that will be shown if an error occurs. Ensure that provided Intents are explicit Intents.

Important: Due to limitations of TaskStackBuilder, the provided list of back stack activities won’t be shown on devices running Android 2.3 and below.

final Intent mainActivity = new Intent(getApplicationContext(), MainActivity.class);
mainActivity.putExtra(MainActivity.EXTRA_VIEWPAGER_POSITION, MainActivity.VIEWPAGER_POS_HELP);

final ArrayList<Intent> backStackItems = new ArrayList<>();
backStackItems.add(mainActivity);

final Intent deepLinkIntent = ZendeskDeepLinking.INSTANCE.getRequestIntent(
    context, "{requestId}", "{subject}", backStackItems, mainActivity
);
Using the Intent

The returned Intent invokes an BroadcastReceiver that handles the further deep linking process.

1. Notifications

final Intent deepLinkIntent = ZendeskDeepLinking.INSTANCE.getRequestIntent(
    context, "{requestId}", "{subject}", backStackItems, mainActivity
);

final PendingIntent contentIntent = PendingIntent.getBroadcast(
    context, {requestCode}, deepLinkIntent, {flags}
);

final Notification notification = new NotificationCompat.Builder(context)
    ...
    .setContentIntent(contentIntent)
    ...
    .build();

2. In an Activity/Fragment

final Intent deepLinkIntent = ZendeskDeepLinking.INSTANCE.getRequestIntent(
    context, "{requestId}", "{subject}", backStackItems, mainActivity
);
context.sendBroadcast(deepLinkIntent);
Refresh comment stream

Another feature provided by ZendeskDeepLinking.INSTANCE is the possibility of refreshing the comment stream if it's visible.

/**
 * Will reload comments in a {@linkplain com.zendesk.sdk.requests.ViewRequestFragment}
 * if it's visible to the user and displaying the given requestId.
 *
 * @param requestId         A request id
 * @return                  True if a reload was triggered, false if not.
 */
public boolean refreshComments(String requestId);

Example:

final boolean commentsRefreshed = ZendeskDeepLinking.INSTANCE.refreshComments(requestId);
if(!commentsRefreshed){
    //e.g. show a notification
}