Custom message handling

With the Xtremepush SDK you, as a developer, have a unified callback to all the user interactions with messages. You can use it to implement any business logic if having the standard deeplinking mechanism is not enough.

iOS

Objective-C

User interaction is described with the XPMessageResponse model. It contains:

  • XPMessage *message
  • XPAction *action

XPMessage contains:

  • XPMessageType *type - message type, one of:
    • XPMessageType_Push
    • XPMessageType_Inapp
    • XPMessageType_Inbox
  • NSString *identifier - message ID
  • NSString *campaignIdentifier - campaign ID
  • NSString *title - message title
  • NSString *text - message text
  • NSDictionary *data - custom payloads
  • NSDictionary *payload - raw message payload

XPAction contains:

  • XPActionType *type - response type, one of:
    • XPActionType_Click
    • XPActionType_Dismiss
    • XPActionType_Present
  • NSString *identifier - action identifier (like button ID, optional)

Here is how to register the handler:

[XPush registerMessageResponseHandler:^(XPMessageResponse *response) {
    switch (response.action.type) {
        case XPActionType_Click:
            // Logic when message is clicked
            break;
        case XPActionType_Dismiss:
            // Logic when message is dismissed
            break;
        case XPActionType_Present:
            // Logic when message is received in foreground
            break;
    }
}];

📘

If you use interactive notifications and want to handle button clicks in the background you need to make sure to use a method with completion handler instead:

[XPush registerMessageResponseHandlerWithCompletion:^(XPMessageResponse * _Nonnull x, XPMessageCompletionBlock  _Nonnull completionHandler) {
    if (response.action.type == XPActionType_Click) {
            if (response.action.identifier == @"like") {
                   // Like article asynchronously and call completionHandler when finished
                   [self likeArticle: response.message.data[@"articleId"] completionHandler: completionHandler];
                   return;
            }
    }

    // If nothing to be done
    completionHandler();
}];

Below is a complete example of custom notification handling. It does multiple things:

  • Shows a custom dialog when a push message is received in foreground
  • Opens an article page when a message is clicked
  • Saves information when one of the message buttons is clicked
[XPush registerMessageResponseHandlerWithCompletion: ^(XPMessageResponse * _Nonnull response, XPMessageCompletionBlock  _Nonnull completionHandler) {        
        switch (response.action.type) {

            // When message is received in foreground
            case XPActionType_Present:
                // Show an article dialog with "View" button
                [self showArticleDialog: response.message viewButtonCallback: ^{
                    // Report message as clicked
                    [XPush reportMessageClicked:response.message];
                    // Navigate to article page
                    [self openArticle: x.message.data[@"articleId"]];
                }];
                break;
                
            // When message is clicked
            case XPActionType_Click:
                // Default click action
                if (response.action.identifier == nil) {
                    // Navigate to the article page
                    [self openArticle: response.message.data[@"articleId"]];
                } 

                // Action for a certain button click
                else {
                    switch(response.action.identifier) {
                        case "like":
                              // Like article asynchronously and call completionHandler when finished
                              [self likeArticle: response.message.data[@"articleId"] completionHandler: completionHandler];
                              return;
                    }
                }
                break;
        }
    
        completionHandler();
}];

Swift

User interaction is described with the XPMessageResponse model. It contains:

  • message: XPMessage
  • action: XPAction

XPMessage contains:

  • type: XPMessageType- message type, one of:
    • XPMessageType_Push
    • XPMessageType_Inapp
    • XPMessageType_Inbox
  • identifier: String - message ID
  • campaignIdentifier: String - campaign ID
  • title: String - message title
  • text: String - message text
  • data: [AnyHashable : Any]? - custom payloads
  • payload: [AnyHashable : Any] - raw message payload

XPAction contains:

  • type: XPActionType - response type, one of:
    • XPActionType_Click
    • XPActionType_Dismiss
    • XPActionType_Present
  • identifier: String - action identifier (like button ID, optional)

Here is how to register the handler:

XPush.registerMessageResponseHandler({(_ response: XPMessageResponse) -> Void in
    switch response.action.type {
        case XPActionType_Click:
            // Logic when message is clicked

        case XPActionType_Dismiss:
            // Logic when message is dismissed

        case XPActionType_Present:
            // Logic when message is received in foreground

    }
})

📘

If you use interactive notifications and want to handle button clicks in background you need to make sure to use a method with completion handler instead:

XPush.registerMessageResponseHandler(withCompletion: {(_ x: XPMessageResponse, _ completionHandler: XPMessageCompletionBlock) -> Void in
    if response.action.type == XPActionType_Click {
        if response.action.identifier == "like" {
            // Like article asynchronously and call completionHandler when finished
            self.likeArticle(response.message.data["articleId"], completionHandler: completionHandler)
            return
        }
    }
    // If nothing to be done
    completionHandler()
})

Below is a complete example of custom notification handling. It does multiple things:

  • Shows a custom dialog when a push message is received in foreground
  • Opens an article page when a message is clicked
  • Saves information when one of the message buttons is clicked
XPush.registerMessageResponseHandler(withCompletion: {(_ x: XPMessageResponse, _ completionHandler: XPMessageCompletionBlock) -> Void in
   if response.action.type == XPActionType_Present {
                showArticleDialog(response.message, viewButtonCallback: {() -> Void in
                    // Report message as clicked
                    XPush.reportMessageClicked(response.message)
                    // Navigate to article page
                    self.openArticle(x.message.data["articleId"])
                })
            }
            else if response.action.type == XPActionType_Click {
                // Default click action
                if response.action.identifier == nil {
                    // Navigate to the article page
                    openArticle(response.message.data["articleId"])
                }
                    // Action for a certain button click
                else {
                    if response.action.identifier == "like" {
                        // Like article asynchronously and call completionHandler when finished
                        self.likeArticle(response.message.data["articleId"], completionHandler: completionHandler)
                    }
                }
            }
            
            // If nothing to be done
            completionHandler()
})

Android

User interaction is described with the objects 

  • Message messagePayload
  • HashMap<String, String> responsePayload

Message contains:

  • String type - message type, one of:
    • "push"
    • "inapp"
    • "inbox"
  • String id- message ID
  • String campaignId - campaign ID
  • String title - message title
  • String text- message text
  • HashMap<String, String> data - custom payloads

the responsePayload HashMap contains:

  • String type - response type, one of:
    • "present"
    • "click"
    • "dismiss"
  • String action- action identifier (like button ID, optional)

Implement the MessageResponseListener in your Application.java class

public class YOUR_APPLICATION_CLASS extends Application implements MessageResponseListener {

Then implement the method

@Override
    public void messageResponseReceived(Message messagePayload,
            HashMap<String, String> responsePayload,
            WeakReference uiReference) {
        
    }

Then add the setMessageResponseListener option to your initialisation of the PushConnector:

new PushConnector.Builder(XPUSH_APP_KEY, GOOGLE_PROJECT_NUMBER)
            .setMessageResponseListener(this)
            ...
            .create(this);

Below is a complete example of custom notification handling. It does multiple things:

  • Shows a custom dialog when a push message is received in foreground
  • Opens an article page when a message is clicked
  • Saves information when one of the message buttons is clicked
@Override
    public void messageResponseReceived(final Message messagePayload,
            HashMap<String, String> responsePayload,
            final WeakReference uiReference) {

        switch (responsePayload.get("type")) {

            // When app is received in the foreground show a custom notification
            case "present":
                if (uiReference != null && uiReference.get() != null) {
                    ((Activity) uiReference.get()).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            AlertDialog.Builder builder = new AlertDialog.Builder((Activity) uiReference.get());
                            builder.setPositiveButton("View", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    //go to article id
                                    openArticle(messagePayload.data.get("articleId"));
                                }
                            });
                            builder.setMessage(messagePayload.text);
                            builder.setTitle(messagePayload.title);
                            AlertDialog dialog = builder.create();
                            dialog.show();
                        }
                    });
                }
                break;

            //when message is clicked
            case "click":
                //default click action
                if (!(responsePayload.containsKey("action"))) {
                    //navigate to article
                    openArticle(messagePayload.data.get("articleId"));
                }
                //action for a certain button click
                else {
                    switch (responsePayload.get("action")) {
                        case "like":
                            //like article
                            likeArticle(messagePayload.data.get("articleId"));
                            break;
                    }
                }
                break;
        }
    }