Introduction

Prerequisites


Only for campaigns served by push notifications: Configure push notifications.

Overview


Synerise campaigns are served in two ways:

  • By Push Notifications, which means that the campaigns are delivered as a push notification:

    • Simple push
    • Silent push
    • Banner
    • Mandatory upgrade
    • First run message
  • By Synerise backend, which means that the campaign is retrieved by SDK through API:

    • In-app messages
    • Walkthrough
Note: You can create each campaign type in the Synerise app. Full documentation is available at this link.

Synerise push notification structure


Each notification follows this basic structure corresponding to the operating system:

{
  "data": {
    "issuer": "Synerise",
    "message-type": "static-content",
    "content-type": "simple-push",
    "content": {
      <<campaign content>>
    }
  }
}
  • issuer - in Synerise notifications, the issuer is always Synerise. If you want to handle notifications with your own methods, remember to change the issuer field. If issuer is set to Synerise, the payload is always handled by the Synerise SDK.
  • message-type - specifies if the content is static or dynamic.
  • content-type - specifies the type of content in the payload.
  • content - the content of the message.

You can also react to Synerise push notifications in your own way, using the payloads presented earlier in this article.

Checking push campaign type


You may need to know whether an incoming push notification comes from Synerise.

Method Description
Injector.isSynerisePush Returns ’true’ if the notification comes from Synerise.
It is validated by checking if the issuer of the push is Synerise.
Injector.isSyneriseSimplePush Checks if the notification payload contains a Simple Push campaign.
Injector.isSyneriseBanner Checks if the notification payload contains a Banner campaign.
Injector.isSyneriseSilentCommand Checks if the notification payload contains a Silent Command campaign.
Injector.isSilentSdkCommand Checks if the notification payload contains a Silent SDK Command campaign.

Types of actions in campaigns


Campaigns can have three action types:

  • OPEN_APP - This option opens your app after clicking the notification or does nothing in foreground.
  • OPEN_URL - This option opens an URL. Depending on your implementation, the link is opened in the browser by default or in your custom implementation, such as a webview in your application.
  • DEEP_LINKING - This option lets you transfer users to a specific view in your app by system methods or by your custom implementation.

Handling actions from campaigns


Android

You can handle actions in your own customized way by using:

Configuration

  1. Make your activity available for deep linking by including the following parameters in your AndroidManifest:
       <activity
          android:name=".ui.linking.DeepLinkingActivity">
          <intent-filter>
              <action android:name="syne://test" />
              <category android:name="android.intent.category.DEFAULT" />
               <data 
                  android:scheme="syne"
                  android:host="test" />
          </intent-filter>
       </activity>
       
    Important: Your action name must be the same as your URI scheme and host.
  2. Optional: Specify an activity to call after closing the activity that was called by deep linking. Provide an additional intent category:
       <activity
          android:name=".ui.linking.DeepLinkingActivity"
          android:parentActivityName=".ui.linking.ParentDeepLinkingActivity">
          <intent-filter>
              <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.DEFAULT" />
              <category android:name="android.intent.category.BROWSABLE" />
              <data
                  android:host="test"
                  android:scheme="syne" />
          </intent-filter>
       </activity>
       
  3. Send a deep link from app.synerise.com by defining the Deep link parameter as syne://test?param=value, where:
    • syne and test are the scheme and host provided in the intent filter.
    • parameter is the parameter name.
    • value is the parameter value.
  4. If the link begins with https, set Action type in the content editor (in app.synerise) to Open url when creating the communication in Synerise Application.
Tip: If your deep link doesn’t contain the :// characters after the scheme, it is treated as a regular string key and set to the Intent’s action.
This means that you can set an action name (in your AndroidManifest activity’s intent filter) to any string and then match it with the provided deep link.

Simple Push, Banner and Walkthrough

You can specify your custom action when a customer interacts with your simple push, banner, or walkthrough.

The SDK allows you to handle those actions. By default, an URL opens the browser and deep linking opens an activity.

Important: The callbacks presented below work only with simple push, banner and walkthrough.

Receive data from the deep link by implementing the following code:

String data = intent.getDataString();
if (data != null) {
   Uri uri = Uri.parse(data);
   value = uri.getQueryParameter("param");
}

If you want to implement your own behavior, refer to the following code:

public class App extends Application implements OnInjectorListener {

    @Override
    public void onCreate() {
        super.onCreate();

        Synerise.Builder.with(this, syneriseClientApiKey, appId)
                        .notificationIcon(R.drawable.ic_notification_icon)
                        .build();
    }

    @Override
    public boolean onOpenUrl(InjectorSource source, String url) {

        // your action here

        SystemUtils.openURL(this, url); // default behavior
        return source != InjectorSource.WALKTHROUGH; // default behavior
    }

    @Override
    public boolean onDeepLink(InjectorSource source, String deepLink) {

        // your action here

        SystemUtils.openDeepLink(this, deepLink); // default behavior
        return source != InjectorSource.WALKTHROUGH; // default behavior
    }

  • onOpenUrl(InjectorSource, String) - callback is fired when a customer interacts with the URL action. Returns true if the activity should be closed after the action executes, false otherwise.
  • onDeepLink(InjectorSource, String) - callback is fired when a customer interacts with the DEEP_LINKING action. Returns true if the activity should be closed after the action executes, false otherwise.

In-app messages

You can specify your custom action when customer interacts with your in-app messages.

The SDK allows you to handle those actions. By default, an URL opens the browser and deep linking opens an activity.

Important: The callbacks presented below work only with in-app message.

If you want to implement your own behavior, refer to the following code:

public static OnInAppListener NULL = new OnInAppListener() {
  @Override
  public void onHandledOpenUrl(InAppMessageData inAppMessageData) {
    //...
  }

  @Override
  public void onHandledOpenDeepLink(InAppMessageData inAppMessageData) {

  }
};

iOS

You can handle actions from each type of campaign in your own customized way by using SyneriseDelegate methods.

The InjectorInAppMessageDelegate monitors when a JS method is used in an in-app message.

In extended methods for handling OPEN_URL and DEEP_LINKING, the following parameters are available:

  • SyneriseActivity: Enum that defines the kind of activity from the action that was sent.
  • SyneriseActivityCompletionHandler: Block/closure that defines whether an activity should be hidden or not and what code should be invoked after.

Sample implementation of OPEN_URL action

This way you can, for example, check the type of activity or use your own webview to show the web page.

Important: If you don’t configure a custom action for OPEN_URL, the SDK runs the default browser with the requested URL address.
// MARK: - SyneriseDelegate

func snr_handledAction(url: URL, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) {
  if activity == .walkthrough {
    completionHandler(.none, {
      if UIApplication.shared.canOpenURL(url) {
        if #available(iOS 10, *) {
            UIApplication.shared.open(url, options:[:], completionHandler:nil)
        } else {
            UIApplication.shared.openURL(url)
        }
      }
    })

    return
  }

  if activity == .banner || activity == .simplePush {
    completionHandler(.hide, {
      //...
    })

    return
  }
}

This way you can, for example, check the type of activity and handle your deeplink in a custom way.

Important: If you don’t configure a custom action for DEEP_LINKING, the SDK tries to handle the deeplink in the host app by a system method.
// MARK: - SyneriseDelegate

func snr_handledAction(deepLink: String, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) {
  if activity == .walkthrough {
    completionHandler(.none, {
      goToHelpWithId(deepLink)
    })

    return
  }

  if activity == .banner {
    completionHandler(.hide, {
      goToPromotionFromDeepLink(deepLink)
    })

    return
  }

  if activity == .simplePush {
    completionHandler(.hide, {
      goToMessageWithId(deepLink)
    })

    return
  }
}

The code below presents a system method sample implementation to handle deeplinks. See Apple Developer - UIApplication.open(_:options:completionHandler:) method for more details.

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  //...
  //other methods
  func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    let sourceApplication: String? = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
    let annotation: Any? = options[UIApplication.OpenURLOptionsKey.annotation]
        
    let handled: Bool = ApplicationDelegate.shared.application(app, open: url, sourceApplication: sourceApplication, annotation: annotation)
      if handled == true {
        return true
      }
        
      if url.scheme == "sample-swift" {
        applicationController.getMainCoordinator()?.didReceiveDeeplink(host: url.host!, pathComponents: url.pathComponents)
        return true
      }
        
    return false
  }
}

React Native and Flutter

Important: React Native SDK and Flutter SDK cannot handle actions by default, you must implement it.

You have to handle actions in your own way by implementing suitable methods in listeners:

Simple Push, Banner and Walkthrough

You can specify your custom action when a customer interacts with your simple push, banner, or walkthrough.

Synerise.Injector.setListener({
  onOpenUrl: function(url) {
    //url implementation
    Linking.openURL(url);
  },
  onDeepLink: function(deepLink) {
    //your custom deeplinking implementation
  }
  //...
  //other listener's methods
});

In-app messages

You can specify your custom action when a customer interacts with your in-app messages.

Synerise.Injector.setInAppMessageListener({
  onOpenUrl: function(data, url) {
    //url implementation
  },
  onDeepLink: function(data, deepLink) {
    //your custom deeplinking implementation
  },
  //...
  //other listener's methods
});

Universal links help your users follow links to content in your app or to your website. When they open a universal link, their mobile OS checks whether any installed app is registered for that domain. If there is no configured application URL for a given path, the user stays on the website.

Important: In order to send universal links from Synerise, you must use the OPEN_URL action in your campaign configuration on Synerise UI.

Android

In order to implement universal links, you need to configure them in the AndroidManifest.xml file in your application.

Add data to your activity in order to connect a URL with a screen.

<activity
  android:name=".ui.dev.tracker.TrackerViewActivity"
  android:screenOrientation="portrait">
  <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data
          android:host="synerise.com"
          android:pathPrefix="/tracker"
          android:scheme="https" />
      <!-- note that the leading "/" is required for pathPrefix-->
  </intent-filter>
</activity>

iOS

To implement universal links:

  1. On your app identifier, enable Associated Domains

  2. In your Xcode project, enable Associated Domain (in capabilities).

  3. Configure your website to host the apple-app-site-association file.

        {
          "applinks": {
            "apps": [],
            "details": [
              {
                "appID": “<<TEAM_ID>>.com.synerise.sdk.sample",
                "paths": [
                  "*"
                ]
              }
            ]
          }
        }
        

  4. Configure your app to handle universal links.

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
      if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        let url = userActivity.webpageURL!
        print(url.absoluteString)
        // handle url and run app action that you want
      }
      
      return true
    }
        

See Apple Developer - Universal Links for Developers for more details.

Blocking campaigns


Note: This feature is available only for iOS SDK.

If you don’t want to show any of the Synerise campaigns somewhere in your application or if there are View Controllers that should never be covered by Synerise activity (for example, banners), you can block the Synerise elements.

To do this, add the SyneriseActivityNotAllowed protocol in your View Controller declaration.

For example:

class SampleViewController: UIViewController, SyneriseActivityNotAllowed {

}

When View Controller implements that protocol and Synerise tries to run an activity, the activity is skipped.

😕

We are sorry to hear that

Thank you for helping improve out documentation. If you need help or have any questions, please consider contacting support.

😉

Awesome!

Thank you for helping improve out documentation. If you need help or have any questions, please consider contacting support.

Close modal icon Placeholder alt for modal to satisfy link checker