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 the 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();
}];
Mark a message as opened
ThereportMessageOpened
and reportMessageClickedfunction
are additions to the SDK that enable developers to implement the feature of marking a message as opened or clicked when a user opens or clicks on it within their application. This function is particularly useful for enhancing user engagement and providing real-time feedback on message interactions. When called, it triggers an event within the SDK that records the message as opened or clicked, depending on the function used, for tracking and analytics purposes. Developers can easily integrate this function into their application's message-handling workflow to improve user experience and gain insights into user engagement patterns.
+ (void)reportMessageOpened:(XPMessage *)message context:(NSDictionary *)context
+ (void)reportMessageOpened:(XPMessage *)message actionIdentifier:(NSString*)actionIdentifier
reportMessageOpened(_ message: XPMessage!, actionIdentifier: String!)
reportMessageOpened(_ message: XPMessage!, context: [AnyHashable : Any]!)
+ (void)reportMessageClicked:(XPMessage *)message context:(NSDictionary*)context;
+ (void)reportMessageClicked:(XPMessage *)message actionIdentifier:(NSString*)actionIdentifier;
reportMessageClicked(_ message: XPMessage!, actionIdentifier: String!)
reportMessageClicked(_ message: XPMessage!, context: [AnyHashable : Any]!)
Messages clicked will be considered opened
Marking a message as clicked using the described method automatically marks it as open, as a user cannot click on the message without first opening it. However, marking a message as opened will not automatically update the click value, as a user may open a message and then not engage with any of the CTAs within it.
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 the 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 the 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;
}
}
Mark a message as opened
As with iOS, thereportMessageOpened
and reportMessageClickedfunction
are additions to the SDK that enable developers to implement the feature of marking a message as opened or clicked when a user opens or clicks on it within their application. This function is particularly useful for enhancing user engagement and providing real-time feedback on message interactions. When called, it triggers an event within the SDK that records the message as opened or clicked, depending on the function used, for tracking and analytics purposes. Developers can easily integrate this function into their application's message-handling workflow to improve user experience and gain insights into user engagement patterns.
reportMessageOpened(message, action, null);
reportMessageOpened(Message message, String action, JSONObject message_context)
reportMessageClicked(message, action, null);
reportMessageClicked(Message message, String action, JSONObject message_context)
Messages clicked will be considered opened
Marking a message as clicked using the described method automatically marks it as open, as a user cannot click on the message without first opening it. However, marking a message as opened will not automatically update the click value, as a user may open a message and then not engage with any of the CTAs within it.
Updated 11 months ago