This article provides developers information for setting up custom message handler.
Contents
Introduction
Marketers have the following ways to process links from push message:
Classical Deep links
Deep links can be used exclusively by customers who have installed your application. Otherwise, the link will redirect the user to the AppStore/Google Play Store to download your application.
Deep links have the following structure:
[scheme]://[host]/[path]
Ask your app developer team to provide you the full scheme with explanations on what are the possible scheme variations. The scheme may contain paths and parameters, which will affect the user experience, when the recipient opens the link and sees the message.
You will find detailed information on the Deep links in iOS and Android documentation resources.
Our platform enriches user experience by passing JSON payload with each notification sent. The JSON payload may contain additional data you for the application to process.
To use deep links in their classical form, you need to set the custom field in our platform, that your deep link handler can process and to redirect the user to the desired application screen.
1. The first step is to create a custom field for the Mobile application in the Emarsys platform.
Mobile Engage -> Applications -> Custom Fields -> Create Custom Data field
2. Notify your Mobile application developers about the string id
used to elaborate the link from payload sent in each push message. This parameter is used to fetch the deep link from the data payload.
Handler data examples are provided in the Firebase and Emarsys documentation.
3. Make sure you are using the correct root parameters for the handler during the campaign creation to extract data from payload.
Create Push Message -> Platform Settings -> Root parameters
The iOS root parameters should contain the following:
{"aps":{"content-available":1, "mutable-
content":"1"}…}
Universal links
Universal links are a common way to unite the traffic from the web and the mobile application and to direct it to a desired Mobile application screen. Whenever the application is unavailable, the traffic can be redirected to a webpage. The difference compared to the classic deep links lies in the way the usual website link is processed by your application.
Make sure that your mobile application developers have read the Deep links for Developers documentation to follow the additional steps to set up universal link processing and allowlisting.
One way to process the universal link is to query the link from your application and resolve the URL path redirecting to the desired application screen.
Make sure you have acquired all the paths to the application and the required website pages from your tech team.
Here’s a code example for processing paths and parameters in universal links provided by Apple:
func application(_ application: UIApplication,
continue userActivity: UIUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
// Get URL components from the incoming user activity
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL,
let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true) else {
return false
}
// Check for specific URL components that you need
guard let path = components.path,
let params = components.queryItems else {
return false
}
print("path = \(path)")
if let albumName = params.first(where: { $0.name == "albumname" } )?.value,
let photoIndex = params.first(where: { $0.name == "index" })?.value {
print("album = \(albumName)")
print("photoIndex = \(photoIndex)")
return true
} else {
print("Either album name or photo index missing")
return false
}
}
The example below shows the path /recipe
with the additional parameter recipeId processed by the application code set in Android Developer studio IDE.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent) {
val appLinkAction = intent.action
val appLinkData: Uri? = intent.data
if (Intent.ACTION_VIEW == appLinkAction) {
appLinkData?.lastPathSegment?.also { recipeId ->
Uri.parse("content://com.recipe_app/recipe/")
.buildUpon()
.appendPath(recipeId)
.build().also { appData ->
showRecipe(appData)
}
}
}
}
1. The first step is to create a custom field for your Mobile application in the Emarsys platform.
Mobile Engage -> Applications -> Custom Fields -> Create Custom Data field
Keep in mind, that custom data are sent as an u object
. The data can be fetched and then processed by a handler as described above.
2. The next step is to add a Universal link into the campaign:
Make sure that you are aligned with your Mobile developer team regarding the paths’ naming convention and parameters’ values that you are using in Universal links. The link you are using during the Push message creation in the Emarsys platform has to be also available on your website.
Universal links with buttons
Our new SDK 2.4.1 simplifies the process of adding universal links to your campaign. Go to Tap actions to specify the actions and meta data within.
The code samples below provide an example of handling the JSON payload if the key was set to campaign_id
with the value of summer_sale
.
iOS
Objective-C
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate, EMSEventHandler>
//
@end
AppDelegate.m
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//
[UNUserNotificationCenter.currentNotificationCenter setDelegate: Emarsys.notificationCenterDelegate];
[Emarsys.notificationCenterDelegate setEventHandler: self];
[Emarsys.inApp setEventHandler: self];
//
}
//
- (void)handleEvent:(NSString *)eventName payload:(nullable NSDictionary<NSString *, NSObject *> *)payload {
if ([eventName isEqual: @"OpenSalesCampaign"]) {
NSString *campaignId = (NSString *)payload[@"campaign_id"];
if (campaignId != nil) {
// navigate to the Sales campaign view
}
}
}
Swift
class AppDelegate: UIResponder, UIApplicationDelegate, EMSEventHandler {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//
UNUserNotificationCenter.current().delegate = Emarsys.notificationCenterDelegate
Emarsys.notificationCenterDelegate.eventHandler = self
Emarsys.inApp.eventHandler = self
//
}
//
func handleEvent(_ eventName: String, payload: [String : NSObject]?) {
if eventName == "OpenSalesCampaign", let campaignId = payload?["campaign_id"] as? String {
// navigate to the Sales campaign view
}
}
}
Android
Java
public class ApplicationClass extends Application implements EventHandler {
@Override
public void onCreate() {
super.onCreate();
//
Emarsys.getPush().setNotificationEventHandler(this);
Emarsys.getInApp().setEventHandler(this);
// ...
}
//
@Override
public void handleEvent(@NotNull Context context, @NotNull String eventName, @Nullable JSONObject payload) {
if ("OpenSalesCampaign".equals(eventName)) {
try {
String campaignId = payload.getString("campaign_id");
if (campaignId != null) {
// navigate to the Sales campaign view
}
} catch (ex: Exception) {
// ...
}
}
}
}
Kotlin
class ApplicationClass : Application(), EventHandler {
override fun onCreate() {
super.onCreate()
//
Emarsys.push.setNotificationEventHandler(this)
Emarsys.inApp.setEventHandler(this)
//
}
//
override fun handleEvent(context: Context, eventName: String, payload: JSONObject?) {
if ("OpenSalesCampaign".equals(eventName)) {
try {
payload?.getString("campaign_id").let {
// navigate to the Sales campaign view
}
} catch (ex: Exception) {
// ...
}
}
}
}