Skip to content

Personnalisation des messages in-app

Découvrez comment personnaliser les messages in-app pour le SDK de Braze.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Android Braze. You’ll also need to set up in-app messages.

Setting custom manager listeners

While the BrazeInAppMessageManager listener can automatically handle the display and lifecycle of in-app messages, you’ll need to implement a custom manager listener if you’d like to fully customize your messages.

The Braze SDK has a default DefaultHtmlInAppMessageActionListener class that is used if no custom listener is defined and takes appropriate action automatically. If you require more control over how a user interacts with different buttons inside a custom HTML in-app message, implement a custom IHtmlInAppMessageActionListener class.

Step 1: Implement the custom manager listener

Step 1.1: Implement IInAppMessageManagerListener

Create a class that implements IInAppMessageManagerListener.

The callbacks in your IInAppMessageManagerListener will also be called at various points in the in-app message lifecycle. For example, if you set a custom manager listener when an in-app message is received from Braze, the beforeInAppMessageDisplayed() method will be called. If your implementation of this method returns InAppMessageOperation.DISCARD, that signals to Braze that the in-app message will be handled by the host app and should not be displayed by Braze. If InAppMessageOperation.DISPLAY_NOW is returned, Braze will attempt to display the in-app message. This method should be used if you choose to display the in-app message in a customized manner.

IInAppMessageManagerListener also includes delegate methods for message clicks and buttons, which can be used in cases like intercepting a message when a button or message is clicked for further processing.

Step 1.2: Hook into IAM view lifecycle methods (optional)

The IInAppMessageManagerListener interface has in-app message view methods called at distinct points in the in-app message view lifecycle. These methods are called in the following order:

  1. beforeInAppMessageViewOpened: Called just before the in-app message is added to the activity’s view. The in-app message is not yet visible to the user at this time.
  2. afterInAppMessageViewOpened: Called just after the in-app message is added to the activity’s view. The in-app message is now visible to the user at this time.
  3. beforeInAppMessageViewClosed: Called just before the in-app message is removed from the activity’s view. The in-app message is still visible to the user at this time.
  4. afterInAppMessageViewClosed: Called just after the in-app message is removed from the activity’s view. The in-app message is no longer visible to the user at this time.

Note that the time between afterInAppMessageViewOpened and beforeInAppMessageViewClosed is when the in-app message view is on screen, visible to the user.

Create a class that implements IHtmlInAppMessageActionListener.

The callbacks in your IHtmlInAppMessageActionListener will be called whenever the user initiates any of the following actions inside the HTML in-app message:

  • Clicks on the close button
  • Fires a custom event
  • Clicks on a URL inside HTML in-app message
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class CustomHtmlInAppMessageActionListener implements IHtmlInAppMessageActionListener {
  private final Context mContext;

  public CustomHtmlInAppMessageActionListener(Context context) {
    mContext = context;
  }

  @Override
  public void onCloseClicked(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show();
    BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
  }

  @Override
  public boolean onCustomEventFired(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show();
    return true;
  }

  @Override
  public boolean onOtherUrlAction(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom url pressed: " + url + " . Ignoring", Toast.LENGTH_LONG).show();
    BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
    return true;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CustomHtmlInAppMessageActionListener(private val mContext: Context) : IHtmlInAppMessageActionListener {

    override fun onCloseClicked(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle) {
        Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show()
        BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
    }

    override fun onCustomEventFired(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show()
        return true
    }

    override fun onOtherUrlAction(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom url pressed: $url . Ignoring", Toast.LENGTH_LONG).show()
        BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
        return true
    }
}

Step 2: Instruct Braze to use the custom manager listener

After you create IInAppMessageManagerListener, call BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener() to instruct BrazeInAppMessageManager to use your custom IInAppMessageManagerListener instead of the default listener. Do this in your Application.onCreate() before any other calls to Braze, so the custom listener is set before any in-app messages are displayed.

Altering in-app messages before display

When a new in-app message is received, and there is already an in-app message being displayed, the new message will be put onto the top of the stack and can be displayed at a later time.

However, if there is no in-app message being displayed, the following delegate method in IInAppMessageManagerListener will be called:

1
2
3
4
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  return InAppMessageOperation.DISPLAY_NOW
}

The InAppMessageOperation() return value can control when the message should be displayed. The suggested usage of this method would be to delay messages in certain parts of the app by returning DISPLAY_LATER when in-app messages would be distracting to the user’s app experience.

See InAppMessageOperation for more details.

On Android, this is done by calling logClick and logImpression on in-app messages and logButtonClick on immersive in-app messages.

After your IHtmlInAppMessageActionListener is created, call BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener() to instruct BrazeInAppMessageManager to use your custom IHtmlInAppMessageActionListener instead of the default action listener.

We recommend setting your IHtmlInAppMessageActionListener in your Application.onCreate() before any other calls to Braze. This will set the custom action listener before any in-app message is displayed:

1
BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(new CustomHtmlInAppMessageActionListener(context));
1
BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(CustomHtmlInAppMessageActionListener(context))

Setting custom factories

You can override a number of defaults through custom factory objects. These can be registered with the Braze SDK as needed to achieve the desired results. However, if you decide to override a factory, you’ll likely need to explicitly defer to the default or reimplement the functionality provided by the Braze default. The following code snippet illustrates how to supply custom implementations of the IInAppMessageViewFactory and the IInAppMessageViewWrapperFactory interfaces.

In-app message types

1
2
3
4
5
6
7
8
class BrazeDemoApplication : Application(){
 override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(BrazeActivityLifecycleCallbackListener(true, true))
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapperFactory())
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(CustomInAppMessageViewFactory())
  }
}

In-app message types

1
2
3
4
5
6
7
8
9
public class BrazeDemoApplication extends Application {
  @Override
  public void onCreate{
    super.onCreate();
    registerActivityLifecycleCallbacks(new BrazeActivityLifecycleCallbackListener(true, true));
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapperFactory());
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(new CustomInAppMessageViewFactory());
  }
}

Braze in-app message types are versatile enough to cover most custom use cases. However, if you want to fully define the visual appearance of your in-app messages instead of using a default type, Braze makes this possible by setting a custom view factory.

The BrazeInAppMessageManager automatically handles placing the in-app message model into the existing activity view hierarchy by default using DefaultInAppMessageViewWrapper. If you need to customize how in-app messages are placed into the view hierarchy, you should use a custom IInAppMessageViewWrapperFactory.

In-app messages have preset animation behavior. Slideup messages slide into the screen; full and modal messages fade in and out. If you want to define custom animation behaviors for your in-app messages, Braze makes this possible by setting up a custom animation factory.

Step 1: Implement the factory

Create a class that implements IInAppMessageViewFactory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CustomInAppMessageViewFactory implements IInAppMessageViewFactory {
  @Override
  public View createInAppMessageView(Activity activity, IInAppMessage inAppMessage) {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    switch (inAppMessage.getMessageType()) {
      case SLIDEUP:
      case MODAL:
      case FULL:
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView();
      default:
        // Use the default in-app message factories
        final IInAppMessageViewFactory defaultInAppMessageViewFactory = BrazeInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage);
        return defaultInAppMessageViewFactory.createInAppMessageView(activity, inAppMessage);
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CustomInAppMessageViewFactory : IInAppMessageViewFactory {
  override fun createInAppMessageView(activity: Activity, inAppMessage: IInAppMessage): View {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    when (inAppMessage.messageType) {
      MessageType.SLIDEUP, MessageType.MODAL, MessageType.FULL ->
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView()
      else -> {
        // Use the default in-app message factories
        val defaultInAppMessageViewFactory = BrazeInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage)
        return defaultInAppMessageViewFactory!!.createInAppMessageView(activity, inAppMessage)
      }
    }
  }
}

Create a class that implements IInAppMessageViewWrapperFactory and returns an IInAppMessageViewWrapper.

This factory is called immediately after the in-app message view is created. The easiest way to implement a custom IInAppMessageViewWrapper is just to extend the default DefaultInAppMessageViewWrapper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class CustomInAppMessageViewWrapper extends DefaultInAppMessageViewWrapper {
  public CustomInAppMessageViewWrapper(View inAppMessageView,
                                       IInAppMessage inAppMessage,
                                       IInAppMessageViewLifecycleListener inAppMessageViewLifecycleListener,
                                       BrazeConfigurationProvider brazeConfigurationProvider,
                                       Animation openingAnimation,
                                       Animation closingAnimation, View clickableInAppMessageView) {
    super(inAppMessageView,
        inAppMessage,
        inAppMessageViewLifecycleListener,
        brazeConfigurationProvider,
        openingAnimation,
        closingAnimation,
        clickableInAppMessageView);
  }

  @Override
  public void open(@NonNull Activity activity) {
    super.open(activity);
    Toast.makeText(activity.getApplicationContext(), "Opened in-app message", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void close() {
    super.close();
    Toast.makeText(mInAppMessageView.getContext().getApplicationContext(), "Closed in-app message", Toast.LENGTH_SHORT).show();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CustomInAppMessageViewWrapper(inAppMessageView: View,
                                    inAppMessage: IInAppMessage,
                                    inAppMessageViewLifecycleListener: IInAppMessageViewLifecycleListener,
                                    brazeConfigurationProvider: BrazeConfigurationProvider,
                                    openingAnimation: Animation,
                                    closingAnimation: Animation, clickableInAppMessageView: View) : 
    DefaultInAppMessageViewWrapper(inAppMessageView, 
        inAppMessage, 
        inAppMessageViewLifecycleListener, 
        brazeConfigurationProvider, 
        openingAnimation, 
        closingAnimation, 
        clickableInAppMessageView) {

  override fun open(activity: Activity) {
    super.open(activity)
    Toast.makeText(activity.applicationContext, "Opened in-app message", Toast.LENGTH_SHORT).show()
  }

  override fun close() {
    super.close()
    Toast.makeText(mInAppMessageView.context.applicationContext, "Closed in-app message", Toast.LENGTH_SHORT).show()
  }
}

Create a class that implements IInAppMessageAnimationFactory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CustomInAppMessageAnimationFactory implements IInAppMessageAnimationFactory {

  @Override
  public Animation getOpeningAnimation(IInAppMessage inAppMessage) {
    Animation animation = new AlphaAnimation(0, 1);
    animation.setInterpolator(new AccelerateInterpolator());
    animation.setDuration(2000L);
    return animation;
  }

  @Override
  public Animation getClosingAnimation(IInAppMessage inAppMessage) {
    Animation animation = new AlphaAnimation(1, 0);
    animation.setInterpolator(new DecelerateInterpolator());
    animation.setDuration(2000L);
    return animation;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CustomInAppMessageAnimationFactory : IInAppMessageAnimationFactory {
  override fun getOpeningAnimation(inAppMessage: IInAppMessage): Animation {
    val animation: Animation = AlphaAnimation(0, 1)
    animation.interpolator = AccelerateInterpolator()
    animation.duration = 2000L
    return animation
  }

  override fun getClosingAnimation(inAppMessage: IInAppMessage): Animation {
    val animation: Animation = AlphaAnimation(1, 0)
    animation.interpolator = DecelerateInterpolator()
    animation.duration = 2000L
    return animation
  }
}

Step 2: Instruct Braze to use the factory

After your IInAppMessageViewFactory is created, call BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory() to instruct BrazeInAppMessageManager to use your custom IInAppMessageViewFactory instead of the default view factory.

How it works

The slideup in-app message view implements IInAppMessageView. The full and modal type message views implement IInAppMessageImmersiveView. Implementing one of these classes allows Braze to add click listeners to your custom view where appropriate. All Braze view classes extend Android’s View class.

Implementing IInAppMessageView allows you to define a certain portion of your custom view as clickable. Implementing IInAppMessageImmersiveView allows you to define message button views and a close button view.

After your IInAppMessageViewWrapper is created, call BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory() to instruct BrazeInAppMessageManager to use your custom IInAppMessageViewWrapperFactory instead of the default view wrapper factory.

We recommend setting your IInAppMessageViewWrapperFactory in your Application.onCreate() before any other calls to Braze. This will set the custom view wrapper factory before any in-app message is displayed:

1
BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapper());
1
BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapper())

Once your IInAppMessageAnimationFactory is created, call BrazeInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory() to instruct BrazeInAppMessageManager to use your custom IInAppMessageAnimationFactory instead of the default animation factory.

We recommend setting your IInAppMessageAnimationFactory in your Application.onCreate() before any other calls to Braze. This will set the custom animation factory before any in-app message is displayed.

Custom styles

Braze UI elements come with a default look and feel that matches the Android standard UI guidelines and provides a seamless experience. This reference article covers custom in-app messaging styling for your Android or FireOS application.

Setting a default style

You can see default styles in the Braze SDK’s styles.xml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <style name="Braze"/>
  <style name="Braze.InAppMessage"/>
  <style name="Braze.InAppMessage.Header">
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:padding">0.0dp</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:textColor">@color/com_braze_inappmessage_header_text</item>
    <item name="android:textSize">20.0sp</item>
    <item name="android:lineSpacingMultiplier">1.3</item>
    <item name="android:gravity">center</item>
    <item name="android:textStyle">bold</item>
    <item name="android:layout_centerHorizontal">true</item>
  </style>

If you would prefer, you can override these styles to create a look and feel that better suits your app.

To override a style, copy it in its entirety to the styles.xml file in your project and make modifications. The whole style must be copied over to your local styles.xml file for all attributes to be correctly set. Note that these custom styles are for changes to individual UI elements, not wholesale changes to layouts. Layout-level changes need to be handled with custom views.

Customizing the font

You can set a custom font by locating the typeface in the res/font directory. To use it, override the style for message text, headers, and button text and use the fontFamily attribute to instruct Braze to use your custom font family.

For example, to update the font on your in-app message button text, override the Braze.InAppMessage.Button style and reference your custom font family. The attribute value should point to a font family in your res/font directory.

Here is a truncated example with a custom font family, my_custom_font_family, referenced on the last line:

1
2
3
4
5
6
7
  <style name="Braze.InAppMessage.Button">
    <item name="android:layout_height">wrap_content</item>
    ...
    <item name="android:paddingBottom">15.0dp</item>
    <item name="android:fontFamily">@font/my_custom_font_family</item>
    <item name="fontFamily">@font/my_custom_font_family</item>
  </style>

Aside from the Braze.InAppMessage.Button style for button text, the style for message text is Braze.InAppMessage.Message and the style for message headers is Braze.InAppMessage.Header. If you want to use your custom font family across all possible in-app message text, you can set your font family on the Braze.InAppMessage style, which is the parent style for all in-app messages.

Message dismissals

Disabling back button dismissals

By default, the hardware back button dismisses Braze in-app messages. This behavior can be disabled on a per-message basis via BrazeInAppMessageManager.setBackButtonDismissesInAppMessageView().

In the following example, disable_back_button is a custom key-value pair set on the in-app message that signifies whether the message should allow for the back button to dismiss the message:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener(new DefaultInAppMessageManagerListener() {
  @Override
  public void beforeInAppMessageViewOpened(View inAppMessageView, IInAppMessage inAppMessage) {
    super.beforeInAppMessageViewOpened(inAppMessageView, inAppMessage);
    final Map<String, String> extras = inAppMessage.getExtras();
    if (extras != null && extras.containsKey("disable_back_button")) {
      BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(false);
    }
  }

  @Override
  public void afterInAppMessageViewClosed(IInAppMessage inAppMessage) {
    super.afterInAppMessageViewClosed(inAppMessage);
    BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(true);
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener(object : DefaultInAppMessageManagerListener() {
  override fun beforeInAppMessageViewOpened(inAppMessageView: View, inAppMessage: IInAppMessage) {
    super.beforeInAppMessageViewOpened(inAppMessageView, inAppMessage)
    val extras = inAppMessage.extras
    if (extras != null && extras.containsKey("disable_back_button")) {
      BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(false)
    }
  }

  override fun afterInAppMessageViewClosed(inAppMessage: IInAppMessage) {
    super.afterInAppMessageViewClosed(inAppMessage)
    BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(true)
  }
})

Enabling outside tap dismissals

By default, dismissing the modal using an outside tap is set to false. Setting this value to true will result in the modal in-app message being dismissed when the user taps outside of the in-app message. This behavior can be toggled on by calling:

1
BrazeInAppMessageManager.getInstance().setClickOutsideModalViewDismissInAppMessageView(true)

Customizing the orientation

To set a fixed orientation for an in-app message, first set a custom in-app message manager listener. Then, update the orientation on the IInAppMessage object in the beforeInAppMessageDisplayed() delegate method:

1
2
3
4
5
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Set the orientation to portrait
  inAppMessage.setOrientation(Orientation.PORTRAIT);
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
4
5
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  // Set the orientation to portrait
  inAppMessage.orientation = Orientation.PORTRAIT
  return InAppMessageOperation.DISPLAY_NOW
}

For tablet devices, in-app messages will appear in the user’s preferred orientation style regardless of actual screen orientation.

Disabling dark theme

By default, IInAppMessageManagerListener’s beforeInAppMessageDisplayed() checks the system settings and conditionally enables dark theme styling on the message with the following code:

1
2
3
4
5
6
7
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  if (inAppMessage instanceof IInAppMessageThemeable && ViewUtils.isDeviceInNightMode(BrazeInAppMessageManager.getInstance().getApplicationContext())) {
    ((IInAppMessageThemeable) inAppMessage).enableDarkTheme();
  }
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
4
5
6
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  if (inAppMessage is IInAppMessageThemeable && ViewUtils.isDeviceInNightMode(BrazeInAppMessageManager.getInstance().applicationContext!!)) {
    (inAppMessage as IInAppMessageThemeable).enableDarkTheme()
  }
  return InAppMessageOperation.DISPLAY_NOW
}

To change this, you can call enableDarkTheme at any step in the pre-display process to implement your own conditional logic.

Customizing the Google Play review prompt

Due to the limitations and restrictions set by Google, custom Google Play review prompts are not currently supported by Braze. While some users have been able to integrate these prompts successfully, others have shown low success rates due to Google Play quotas. Integrate at your own risk. Refer to documentation on Google Play in-app review prompts.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Swift Braze.

Mise en place du délégué à l’interface utilisateur (obligatoire)

Pour personnaliser la présentation des messages in-app et réagir à divers événements du cycle de vie, vous devrez configurer des . BrazeInAppMessageUIDelegate. Il s’agit d’un protocole délégué utilisé pour la réception et le traitement des messages in-app déclenchés, la réception des événements du cycle de vie de l’affichage et le contrôle de la synchronisation de l’affichage. Pour utiliser BrazeInAppMessageUIDelegate, vous devez

  • Utilisez l’implémentation par défaut BrazeInAppMessageUI comme inAppMessagePresenter.
  • Incluez la bibliothèque BrazeUI dans votre projet.

Étape 1 : Mettre en œuvre le protocole BrazeInAppMessageUIDelegate

Tout d’abord, implémentez le protocole BrazeInAppMessageUIDelegate et toutes les méthodes correspondantes que vous souhaitez. Dans l’exemple ci-dessous, nous implémentons ce protocole dans la classe AppDelegate de notre application.

1
2
3
extension AppDelegate: BrazeInAppMessageUIDelegate {
  // Implement your protocol methods here.
}
1
2
3
4
5
6
7
@interface AppDelegate () <BrazeInAppMessageUIDelegate>

@end

@implementation AppDelegate
  // Implement your protocol methods here.
@end

Étape 2 : Attribuer l’objet delegate

Attribuez l’objet delegate à l’instance BrazeInAppMessageUI avant d’attribuer ce message in-app à l’interface utilisateur inAppMessagePresenter.

1
2
3
let inAppMessageUI = BrazeInAppMessageUI()
inAppMessageUI.delegate = self
AppDelegate.braze?.inAppMessagePresenter = inAppMessageUI
1
2
3
BrazeInAppMessageUI *inAppMessageUI = [[BrazeInAppMessageUI alloc] init];
inAppMessageUI.delegate = self;
AppDelegate.braze.inAppMessagePresenter = inAppMessageUI;

Comportement lors du clic

Chaque objet Braze.InAppMessage contient une ClickAction correspondante qui définit le comportement en cas de clic.

Cliquez sur les types d’action

La propriété clickAction de votre Braze.InAppMessage est par défaut .none mais peut être définie sur l’une des valeurs suivantes :

Personnaliser le comportement du clic

Pour personnaliser ce comportement, vous pouvez modifier la propriété clickAction en vous référant à l’exemple suivant :

1
2
3
4
5
6
7
8
func inAppMessage(
  _ ui: BrazeInAppMessageUI, 
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  if let newUrl = URL(string: "{your-url}") {
    context.message.clickAction = .url(newUrl, useWebView: true)
  }
}

La méthode inAppMessage(_:prepareWith:) n’est pas disponible en Objective-C.

Gestion du comportement personnalisé

La méthode de délégation BrazeInAppMessageUIDelegate suivante est appelée en cas de clic sur un message in-app. Pour les clics sur les boutons de messages in-app et les boutons de messages in-app HTML (liens), un ID de bouton est fourni en tant que paramètre facultatif.

1
2
3
4
5
6
7
func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  shouldProcess clickAction: Braze.InAppMessage.ClickAction,
  buttonId: String?,
  message: Braze.InAppMessage,
  view: InAppMessageView
) -> Bool
1
2
3
4
5
6
- (BOOL)inAppMessage:(BrazeInAppMessageUI *)ui
       shouldProcess:(enum BRZInAppMessageRawClickAction)clickAction
                 url:(NSURL *)uri
            buttonId:(NSString *)buttonId
             message:(BRZInAppMessageRaw *)message
                view:(UIView *)view;

Cette méthode renvoie une valeur booléenne indiquant si Braze doit continuer à exécuter l’action de clic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func inAppMessage(
  _ ui: BrazeInAppMessageUI, shouldProcess clickAction: Braze.InAppMessage.ClickAction,
  buttonId: String?, message: Braze.InAppMessage, view: InAppMessageView
) -> Bool {
    guard let buttonId,
      let idInt = Int(buttonId)
    else { return true }
    var button: BrazeKit.Braze.InAppMessage.Button? = nil

    switch message {
    case .modal(let modal):
      button = modal.buttons[idInt]

    case .modalImage(let modalImage):
      button = modalImage.buttons[idInt]

    case .full(let full):
      button = full.buttons[idInt]

    case .fullImage(let fullImage):
      button = fullImage.buttons[idInt]

    default:
      break
    }
    
    print(button?.id)
    print(button?.text)
    print(button?.clickAction)

    return true
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (BOOL)inAppMessage:(BrazeInAppMessageUI *)ui
       shouldProcess:(enum BRZInAppMessageRawClickAction)clickAction
                 url:(NSURL *)uri
            buttonId:(NSString *)buttonId
             message:(BRZInAppMessageRaw *)message
                view:(UIView *)view {
  NSInteger buttonInt = [buttonId integerValue];

  if (message.type == BRZInAppMessageRawTypeFull || message.type == BRZInAppMessageRawTypeModal) {
    BRZInAppMessageRawButton *button = message.buttons[buttonInt];
    NSLog(@"%ld", (long)button.identifier);
    NSLog(@"%@", button.text);
    NSLog(@"%ld", (long)button.clickAction);
  }
  return YES;
}

Personnalisation des fenêtres modales/boîtes de dialogue, etc.

Pour activer les rejets par touché extérieur, vous pouvez modifier la propriété dismissOnBackgroundTap de la structure Attributes du type de message in-app que vous souhaitez personnaliser.

Par exemple, si vous souhaitez activer cette fonctionnalité pour les messages in-app de type fenêtre modale, vous pouvez configurer ce qui suit :

1
BrazeInAppMessageUI.ModalImageView.Attributes.defaults.dismissOnBackgroundTap = true

La personnalisation via Attributes n’est pas disponible en Objective-C.

La valeur par défaut est false. Cela détermine si le message in-app modal sera rejeté lorsque l’utilisateur touche à l’extérieur du message in-app.

Pour plus de détails sur la personnalisation des messages in-app, consultez cet article.

Personnalisation de l’orientation des messages

Vous pouvez personnaliser l’orientation de vos messages in-app. Vous pouvez définir une nouvelle orientation par défaut pour tous les messages ou définir une orientation personnalisée pour un seul message.

Pour choisir une orientation par défaut pour tous les messages in-app, utilisez la méthode inAppMessage(_:prepareWith:) pour définir la propriété preferredOrientation sur le site PresentationContext.

Par exemple, pour définir le portrait comme orientation par défaut :

1
2
3
4
5
6
func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  context.preferredOrientation = .portrait
}
1
2
3
4
- (void)inAppMessage:(BrazeInAppMessageUI *)ui
         prepareWith:(BrazeInAppMessageUIPresentationContextRaw *)context {
  context.preferredOrientation = BRZInAppMessageRawOrientationPortrait;
}

Pour définir l’orientation d’un seul message, modifiez la propriété orientation de Braze.InAppMessage:

1
2
3
4
5
6
7
8
// Set inAppMessage orientation to support any configuration
inAppMessage.orientation = .any

// Set inAppMessage orientation to only display in portrait
inAppMessage.orientation = .portrait

// Set inAppMessage orientation to only display in landscape
inAppMessage.orientation = .landscape
1
2
3
4
5
6
7
8
// Set inAppMessage orientation to support any configuration
inAppMessage.orientation = BRZInAppMessageRawOrientationAny;

// Set inAppMessage orientation to only display in portrait
inAppMessage.orientation = BRZInAppMessageRawOrientationPortrait;

// Set inAppMessage orientation to only display in landscape
inAppMessage.orientation = BRZInAppMessageRawOrientationLandscape;

Une fois le message in-app affiché, tout changement d’orientation de l’appareil pendant que le message est encore affiché entraînera la rotation du message avec l’appareil (à condition que la configuration du message orientation le permette).

L’orientation de l’appareil doit également être prise en charge par la propriété orientation du message in-app pour que le message s’affiche. En outre, le paramètre preferredOrientation ne sera respecté que s’il est inclus dans les orientations d’interface prises en charge par votre application, dans la section Informations sur le déploiement des paramètres de votre cible dans Xcode.

Orientations prises en charge dans Xcode.

Personnalisation de la durée d’affichage

Vous pouvez contrôler si un message in-app disponible s’affichera à certains moments de votre expérience sur communication. Si, dans certaines situations, vous ne souhaitez pas que le message in-app apparaisse, par exemple pendant un jeu en plein écran ou sur un écran de chargement, vous pouvez retarder ou supprimer les messages in-app en attente. Pour contrôler le moment de l’envoi du message in-app, utilisez la méthode de délégué inAppMessage(_:displayChoiceForMessage:) pour définir la propriété BrazeInAppMessageUI.DisplayChoice.

1
2
3
4
func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  displayChoiceForMessage message: Braze.InAppMessage
) -> BrazeInAppMessageUI.DisplayChoice
1
- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui displayChoiceForMessage:(BRZInAppMessageRaw *)message

Configurez BrazeInAppMessageUI.DisplayChoice pour qu’il renvoie l’une des valeurs suivantes :

Masquer la barre d’état

Pour les messages in-app Full, FullImage et HTML, le SDK masque la barre d’état par défaut. Pour les autres types de messages in-app, la barre d’état reste intacte. Pour configurer ce comportement, utilisez la méthode de délégué inAppMessage(_:prepareWith:) pour définir la propriété statusBarHideBehavior sur le PresentationContext. Ce champ prend l’une des valeurs suivantes :

Désactivation du mode sombre

Pour empêcher les messages in-app d’adopter le style du mode sombre lorsque l’appareil de l’utilisateur a activé le mode sombre, implémentez la méthode de délégué inAppMessage(_:prepareWith:). Le PresentationContext transmis à la méthode contient une référence à l’objet InAppMessage à présenter. Chaque InAppMessage possède une propriété themes contenant un thème de mode dark et light. Si vous définissez la propriété themes.dark sur la valeur nil, Braze présentera automatiquement le message in-app à l’aide de son thème lumineux.

Les types de messages in-app avec boutons ont un objet themes supplémentaire sur leur propriété buttons. Pour empêcher les boutons d’adopter le style du mode sombre, vous pouvez utiliser l’option map(_:) pour créer un nouveau tableau de boutons avec un thème light et sans thème dark.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  switch context.message {
    case .slideup:
      guard var slideup = context.message.slideup else { return }
      slideup.themes.dark = nil
      context.message.slideup = slideup
    
    case .modal:
      guard var modal = context.message.modal else { return }
      modal.themes.dark = nil
      modal.buttons = modal.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.modal = modal
    
    case .modalImage:
      guard var modalImage = context.message.modalImage else { return }
      modalImage.themes.dark = nil
      modalImage.buttons = modalImage.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.modalImage = modalImage
    
    case .full:
      guard var full = context.message.full else { return }
      full.themes.dark = nil
      full.buttons = full.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.full = full
    
    case .fullImage:
      guard var fullImage = context.message.fullImage else { return }
      fullImage.themes.dark = nil
      fullImage.buttons = fullImage.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.fullImage = fullImage
    
    default:
      break
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (void)inAppMessage:(BrazeInAppMessageUI *)ui
         prepareWith:(BrazeInAppMessageUIPresentationContextRaw *)context {
  switch (context.message.type) {
    case BRZInAppMessageRawTypeSlideup: {
      NSMutableDictionary *updatedThemes = [context.message.themes mutableCopy];
      [updatedThemes removeObjectForKey:@"dark"];
      context.message.themes = updatedThemes;
      break;
    }
    case BRZInAppMessageRawTypeModal:
    case BRZInAppMessageRawTypeFull:
    {
      NSMutableDictionary *updatedThemes = [context.message.themes mutableCopy];
      [updatedThemes removeObjectForKey:@"dark"];
      context.message.themes = updatedThemes;

      NSMutableArray *updatedButtons = [NSMutableArray arrayWithCapacity:context.message.buttons.count];
      for (BRZInAppMessageRawButton *button in context.message.buttons) {
        BRZInAppMessageRawButtonTheme *lightTheme = BRZInAppMessageRawButtonTheme.defaultLight;
        BRZInAppMessageRawButton *newButton = [button mutableCopy];
        newButton.textColor = lightTheme.textColor;
        newButton.backgroundColor = lightTheme.backgroundColor;
        newButton.borderColor = lightTheme.borderColor;
        [updatedButtons addObject:newButton];
      }
      context.message.buttons = updatedButtons;
      break;
    }
    default:
      break;
  }
}

Personnalisation de l’invite d’évaluation de la boutique d’applications

Vous pouvez utiliser des messages in-app dans le cadre d’une campagne pour demander aux utilisateurs de rédiger un avis sur l’App Store.

Étape 1 : Définir le délégué du message in-app

Tout d’abord, définissez l’élément BrazeInAppMessageUIDelegate dans votre application.

Étape 2 : Désactiver le message par défaut d’évaluation de l’App Store

Ensuite, implémentez la inAppMessage(_:displayChoiceForMessage:) méthode de délégation pour désactiver le message par défaut d’évaluation de l’App Store.

1
2
3
4
5
6
7
8
9
func inAppMessage(_ ui: BrazeInAppMessageUI, displayChoiceForMessage message: Braze.InAppMessage) -> BrazeInAppMessageUI.DisplayChoice {
  if message.extras["AppStore Review"] != nil,
    let messageUrl = message.clickAction.url {
      UIApplication.shared.open(messageUrl, options: [:], completionHandler: nil)
      return .discard
  } else {
    return .now
  }
}
1
2
3
4
5
6
7
8
9
- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui
                            displayChoiceForMessage:(BRZInAppMessageRaw *)message {
  if (message.extras != nil && message.extras[@"AppStore Review"] != nil) {
    [[UIApplication sharedApplication] openURL:message.url options:@{} completionHandler:nil];
    return BRZInAppMessageUIDisplayChoiceDiscard;
  } else {
    return BRZInAppMessageUIDisplayChoiceNow;
  }
}

Étape 3 : Créer un lien profond

Dans votre code de traitement de liaison profonde, ajoutez le code suivant pour traiter le lien profond {YOUR-APP-SCHEME}:app-store-review. Notez que vous devrez importer StoreKit pour utiliser SKStoreReviewController :

1
2
3
4
5
6
7
8
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  let urlString = url.absoluteString.removingPercentEncoding
  if (urlString == "{YOUR-APP-SCHEME}:app-store-review") {
    SKStoreReviewController.requestReview()
    return true;
  }
  // Other deep link handling code…
}
1
2
3
4
5
6
7
8
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  NSString *urlString = url.absoluteString.stringByRemovingPercentEncoding;
  if ([urlString isEqualToString:@"{YOUR-APP-SCHEME}:app-store-review"]) {
    [SKStoreReviewController requestReview];
    return YES;
  }
  // Other deep link handling code…
}

Étape 4 : Définir un comportement personnalisé au clic

Créez ensuite une campagne de communication in-app avec les éléments suivants :

  • La paire clé-valeur "AppStore Review" : "true"
  • Le comportement en cours défini sur « Deep Link Into App », en utilisant le lien profond {YOUR-APP-SCHEME}:app-store-review.

Prerequisites

Before you can use this feature, you’ll need to integrate the Web Braze SDK.

Custom styles

Braze UI elements come with a default look and feel that create a neutral in-app message experience and aim for consistency with other Braze mobile platforms. The default Braze styles are defined in CSS within the Braze SDK.

Setting a default style

By overriding selected styles in your application, you can customize our standard in-app message types with your own background images, font families, styles, sizes, animations, and more.

For instance, the following is an example override that will cause an in-app message’s headers to appear italicized:

1
2
3
  body .ab-in-app-message .ab-message-header {
    font-style: italic;
  }

See the JSDocs for more information.

Customizing the z-index

By default, in-app messages are displayed using z-index: 9001. This is configurable using the inAppMessageZIndex initialization option in the scenario that your website styles elements with higher values than that.

1
2
3
4
braze.initialize("YOUR-API-KEY", {
    baseUrl: "YOUR-API-ENDPOINT",
    inAppMessageZIndex: 12000
});

Customizing message dismissals

By default, when an in-app message is showing, pressing the escape button or a click on the grayed-out background of the page will dismiss the message. Configure the requireExplicitInAppMessageDismissal initialization option to true to prevent this behavior and require an explicit button click to dismiss messages.

1
2
3
4
5
import * as braze from "@braze/web-sdk";
braze.initialize("YOUR-API-KEY", {
    baseUrl: "YOUR-API-ENDPOINT",
    requireExplicitInAppMessageDismissal: true
});

To set your in-app message links to open in a new tab, set the openInAppMessagesInNewTab option to true to force all links from in-app message clicks open in a new tab or window.

1
braze.initialize('api-key', { openInAppMessagesInNewTab: true} );

Prerequisites

Before you can use this feature, you’ll need to integrate the React Native Braze SDK.

Methods for logging

You can use these methods by passing your BrazeInAppMessage instance to log analytics and perform actions:

Handling message data

In most cases, you can use the Braze.addListener method to register event listeners to handle data coming from in-app messages.

Additionally, you can access the in-app message data in the JavaScript layer by calling the Braze.subscribeToInAppMessage method to have the SDKs publish an inAppMessageReceived event when an in-app message is triggered. Pass a callback to this method to execute your own code when the in-app message is triggered and received by the listener.

To customize how message data is handled, refer to the following implementation examples:

To enhance the default behavior, or if you don’t have access to customize the native iOS or Android code, we recommend that you disable the default UI while still receiving in-app message events from Braze. To disable the default UI, pass false to the Braze.subscribeToInAppMessage method and use the in-app message data to construct your own message in JavaScript. Note that you will need to manually log analytics on your messages if you choose to disable the default UI.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Braze from "@braze/react-native-sdk";

// Option 1: Listen for the event directly via `Braze.addListener`.
//
// You may use this method to accomplish the same thing if you don't
// wish to make any changes to the default Braze UI.
Braze.addListener(Braze.Events.IN_APP_MESSAGE_RECEIVED, (event) => {
  console.log(event.inAppMessage);
});

// Option 2: Call `subscribeToInAppMessage`.
//
// Pass in `false` to disable the automatic display of in-app messages.
Braze.subscribeToInAppMessage(false, (event) => {
  console.log(event.inAppMessage);
  // Use `event.inAppMessage` to construct your own custom message UI.
});

To include more advanced logic to determine whether or not to show an in-app message using the built-in UI, implement in-app messages through the native layer.

Implement the IInAppMessageManagerListener as described in our Android article on Custom Manager Listener. In your beforeInAppMessageDisplayed implementation, you can access the inAppMessage data, send it to the JavaScript layer, and decide to show or not show the native message based on the return value.

For more on these values, see our Android documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// In-app messaging
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
    WritableMap parameters = new WritableNativeMap();
    parameters.putString("inAppMessage", inAppMessage.forJsonPut().toString());
    getReactNativeHost()
        .getReactInstanceManager()
        .getCurrentReactContext()
        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit("inAppMessageReceived", parameters);
    // Note: return InAppMessageOperation.DISCARD if you would like
    // to prevent the Braze SDK from displaying the message natively.
    return InAppMessageOperation.DISPLAY_NOW;
}

Overriding the default UI delegate

By default, BrazeInAppMessageUI is created and assigned when you initialize the braze instance. BrazeInAppMessageUI is an implementation of the BrazeInAppMessagePresenter protocol and comes with a delegate property that can be used to customize the handling of in-app messages that have been received.

  1. Implement the BrazeInAppMessageUIDelegate delegate as described in our iOS article here.

  2. In the inAppMessage(_:displayChoiceForMessage:) delegate method, you can access the inAppMessage data, send it to the JavaScript layer, and decide to show or not show the native message based on the return value.

For more details on these values, see our iOS documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui
                            displayChoiceForMessage:(BRZInAppMessageRaw *)message {
  // Convert the message to a JavaScript representation.
  NSData *inAppMessageData = [message json];
  NSString *inAppMessageString = [[NSString alloc] initWithData:inAppMessageData encoding:NSUTF8StringEncoding];
  NSDictionary *arguments = @{
    @"inAppMessage" : inAppMessageString
  };

  // Send to JavaScript.
  [self sendEventWithName:@"inAppMessageReceived" body:arguments];

  // Note: Return `BRZInAppMessageUIDisplayChoiceDiscard` if you would like
  // to prevent the Braze SDK from displaying the message natively.
  return BRZInAppMessageUIDisplayChoiceNow;
}

To use this delegate, assign it to brazeInAppMessagePresenter.delegate after initializing the braze instance.

1
2
3
4
5
6
7
8
@import BrazeUI;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:apiKey endpoint:endpoint];
  Braze *braze = [BrazeReactBridge initBraze:configuration];
  ((BrazeInAppMessageUI *)braze.inAppMessagePresenter).delegate = [[CustomDelegate alloc] init];
  AppDelegate.braze = braze;
}

Overriding the default native UI

If you wish to fully customize the presentation of your in-app messages at the native iOS layer, conform to the BrazeInAppMessagePresenter protocol and assign your custom presenter following the sample below:

1
2
3
4
BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:apiKey endpoint:endpoint];
Braze *braze = [BrazeReactBridge initBraze:configuration];
braze.inAppMessagePresenter = [[MyCustomPresenter alloc] init];
AppDelegate.braze = braze;

Personnaliser le comportement des clients

Vous pouvez modifier le comportement d’affichage des messages in-app au moment de l’exécution en procédant comme suit :

1
2
3
4
5
6
7
8
// Sets in-app messages to display immediately when triggered.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISPLAY_NOW);

// Sets in-app messages to display at a later time and be saved in a stack.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISPLAY_LATER);

// Sets in-app messages to be discarded after being triggered.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISCARD);

Mise en place d’un écouteur personnalisé

Si vous avez besoin de plus de contrôle sur la façon dont un utilisateur interagit avec les messages in-app, utilisez un BrazeInAppMessageListener et attribuez-le à Appboy.AppboyBinding.inAppMessageListener. Concernant les délégués que vous ne souhaitez pas utiliser, vous pouvez simplement les laisser définis comme null.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
BrazeInAppMessageListener listener = new BrazeInAppMessageListener() {
  BeforeInAppMessageDisplayed = BeforeInAppMessageDisplayed,
  OnInAppMessageButtonClicked = OnInAppMessageButtonClicked,
  OnInAppMessageClicked       = OnInAppMessageClicked,
  OnInAppMessageHTMLClicked   = OnInAppMessageHTMLClicked,
  OnInAppMessageDismissed     = OnInAppMessageDismissed,
};
Appboy.AppboyBinding.inAppMessageListener = listener;

public void BeforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Executed before an in-app message is displayed.
}

public void OnInAppMessageButtonClicked(IInAppMessage inAppMessage, InAppMessageButton inAppMessageButton) {
  // Executed whenever an in-app message button is clicked.
}

public void OnInAppMessageClicked(IInAppMessage inAppMessage) {
  // Executed whenever an in-app message is clicked.
}

public void OnInAppMessageHTMLClicked(IInAppMessage inAppMessage, Uri uri) {
  // Executed whenever an HTML in-app message is clicked.
}

public void OnInAppMessageDismissed(IInAppMessage inAppMessage) {
  // Executed whenever an in-app message is dismissed without a click.
}
CETTE PAGE A-T-ELLE ÉTÉ UTILE?
New Stuff!