Skip to content

Création de liens profonds dans les messages in-app

Découvrez comment créer des liens profonds dans un message in-app à l’aide du SDK de Braze.

Conditions préalables

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

Création d’un délégué universel

Le SDK Android permet de définir un objet délégué unique pour gérer de manière personnalisée tous les liens profonds ouverts par Braze via les Content Cards, les messages in-app et les notifications push.

Votre objet délégué doit implémenter l’interface IBrazeDeeplinkHandler et être défini à l’aide de BrazeDeeplinkHandler.setBrazeDeeplinkHandler(). Dans la plupart des cas, le délégué doit être défini dans le Application.onCreate() de votre application.

Voici un exemple de remplacement du comportement par défaut de UriAction avec des indicateurs d’intention personnalisés et un comportement personnalisé pour les URL YouTube :

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
public class CustomDeeplinkHandler implements IBrazeDeeplinkHandler {
  private static final String TAG = BrazeLogger.getBrazeLogTag(CustomDeeplinkHandler.class);

  @Override
  public void gotoUri(Context context, UriAction uriAction) {
    String uri = uriAction.getUri().toString();
    // Open YouTube URLs in the YouTube app and not our app
    if (!StringUtils.isNullOrBlank(uri) && uri.contains("youtube.com")) {
      uriAction.setUseWebView(false);
    }

    CustomUriAction customUriAction = new CustomUriAction(uriAction);
    customUriAction.execute(context);
  }

  public static class CustomUriAction extends UriAction {

    public CustomUriAction(@NonNull UriAction uriAction) {
      super(uriAction);
    }

    @Override
    protected void openUriWithActionView(Context context, Uri uri, Bundle extras) {
      Intent intent = getActionViewIntent(context, uri, extras);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
      if (intent.resolveActivity(context.getPackageManager()) != null) {
        context.startActivity(intent);
      } else {
        BrazeLogger.w(TAG, "Could not find appropriate activity to open for deep link " + uri + ".");
      }
    }
  }
}
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
class CustomDeeplinkHandler : IBrazeDeeplinkHandler {

  override fun gotoUri(context: Context, uriAction: UriAction) {
    val uri = uriAction.uri.toString()
    // Open YouTube URLs in the YouTube app and not our app
    if (!StringUtils.isNullOrBlank(uri) && uri.contains("youtube.com")) {
      uriAction.useWebView = false
    }

    val customUriAction = CustomUriAction(uriAction)
    customUriAction.execute(context)
  }

  class CustomUriAction(uriAction: UriAction) : UriAction(uriAction) {

    override fun openUriWithActionView(context: Context, uri: Uri, extras: Bundle) {
      val intent = getActionViewIntent(context, uri, extras)
      intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
      if (intent.resolveActivity(context.packageManager) != null) {
        context.startActivity(intent)
      } else {
        BrazeLogger.w(TAG, "Could not find appropriate activity to open for deep link $uri.")
      }
    }
  }

  companion object {
    private val TAG = BrazeLogger.getBrazeLogTag(CustomDeeplinkHandler::class.java)
  }
}

Création de liens profonds vers les paramètres de l’application

Pour permettre aux liens profonds d’ouvrir directement les paramètres de votre application, vous aurez besoin d’un BrazeDeeplinkHandler personnalisé. Dans l’exemple suivant, la présence d’une paire clé-valeur personnalisée appelée open_notification_page fait en sorte que le lien profond ouvre la page des paramètres de l’application :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BrazeDeeplinkHandler.setBrazeDeeplinkHandler(new IBrazeDeeplinkHandler() {
  @Override
  public void gotoUri(Context context, UriAction uriAction) {
    final Bundle extras = uriAction.getExtras();
    if (extras.containsKey("open_notification_page")) {
      Intent intent = new Intent();
      intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

      //for Android 5-7
      intent.putExtra("app_package", context.getPackageName());
      intent.putExtra("app_uid", context.getApplicationInfo().uid);

      // for Android 8 and later
      intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
      context.startActivity(intent);
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BrazeDeeplinkHandler.setBrazeDeeplinkHandler(object : IBrazeDeeplinkHandler {
  override fun gotoUri(context: Context, uriAction: UriAction) {
    val extras = uriAction.extras
    if (extras.containsKey("open_notification_page")) {
      val intent = Intent()
      intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
      intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK

      //for Android 5-7
      intent.putExtra("app_package", context.packageName)
      intent.putExtra("app_uid", context.applicationInfo.uid)

      // for Android 8 and later
      intent.putExtra("android.provider.extra.APP_PACKAGE", context.packageName)
      context.startActivity(intent)
    }
  }
})

Personnalisation de l’activité WebView

Lorsque Braze ouvre des liens profonds vers des sites web à l’intérieur de l’application, ces liens sont gérés par BrazeWebViewActivity.

Pour modifier ce comportement :

  1. Créez une nouvelle activité qui gère l’URL cible depuis Intent.getExtras() avec la clé com.braze.Constants.BRAZE_WEBVIEW_URL_EXTRA. Pour un exemple, consultez BrazeWebViewActivity.kt.
  2. Ajoutez cette activité à AndroidManifest.xml et définissez exported sur false.
    1
    2
    3
    
     <activity
         android:name=".MyCustomWebViewActivity"
         android:exported="false" />
    
  3. Définissez votre activité personnalisée dans un objet générateur BrazeConfig. Construisez le générateur et transmettez-le à Braze.configure() dans votre Application.onCreate().
1
2
3
4
5
BrazeConfig brazeConfig = new BrazeConfig.Builder()
    .setCustomWebViewActivityClass(MyCustomWebViewActivity::class)
    ...
    .build();
Braze.configure(this, brazeConfig);
1
2
3
4
5
val brazeConfig = BrazeConfig.Builder()
    .setCustomWebViewActivityClass(MyCustomWebViewActivity::class.java)
    ...
    .build()
Braze.configure(this, brazeConfig)

Résolution des problèmes

Si les liens profonds provenant des notifications push ne fonctionnent pas sur Android, essayez les étapes suivantes :

  1. Testez le lien profond en dehors de Braze. Ouvrez l’URL du lien profond depuis une autre application, comme un e-mail ou un navigateur. Si votre application ne s’ouvre pas, le lien profond n’est peut-être pas correctement configuré dans votre AndroidManifest.xml. Pour plus d’informations, consultez la documentation Android Créer des liens profonds.
  2. Vérifiez que la gestion automatique des liens profonds est activée. Assurez-vous que com_braze_handle_push_deep_links_automatically est défini sur true dans braze.xml, ou configurez cette option via la configuration au moment de l’exécution. Sans ce paramètre, Braze n’ouvre pas automatiquement votre application ni la destination du lien profond lorsqu’un utilisateur appuie sur une notification push.
  3. Vérifiez votre délégué de gestion des liens profonds. Si vous avez défini un IBrazeDeeplinkHandler personnalisé, confirmez que votre implémentation de gotoUri gère bien l’URI et ne l’ignore pas.
  4. Testez sur différents canaux. Si le même lien profond fonctionne dans un message in-app mais pas depuis une notification push, le problème se situe probablement dans la gestion des liens profonds push, et non dans le lien profond lui-même.

Utilisation de Jetpack Compose

Pour gérer les liens profonds avec Jetpack Compose et NavHost :

  1. Assurez-vous que l’activité gérant votre lien profond est enregistrée dans le manifeste Android.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     <activity
       ...
       <intent-filter>
         <action android:name="android.intent.action.VIEW" />
         <category android:name="android.intent.category.BROWSABLE" />
         <category android:name="android.intent.category.DEFAULT" />
         <data
             android:host="articles"
             android:scheme="myapp" />
       </intent-filter>
     </activity>
    
  2. Dans NavHost, spécifiez les liens profonds que vous souhaitez gérer.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
     composableWithCompositionLocal(
         route = "YOUR_ROUTE_HERE",
         deepLinks = listOf(navDeepLink {
             uriPattern = "myapp://articles/{${MainDestinations.ARTICLE_ID_KEY}}"
         }),
         arguments = listOf(
             navArgument(MainDestinations.ARTICLE_ID_KEY) {
                 type = NavType.LongType
             }
         ),
     ) { backStackEntry ->
         val arguments = requireNotNull(backStackEntry.arguments)
         val articleId = arguments.getLong(MainDestinations.ARTICLE_ID_KEY)
         ArticleDetail(
             articleId
         )
     }
    
  3. Selon l’architecture de votre application, vous devrez peut-être également gérer la nouvelle intention envoyée à votre activité actuelle.
    1
    2
    3
    4
    5
    6
    7
    
     DisposableEffect(Unit) {
         val listener = Consumer<Intent> {
             navHostController.handleDeepLink(it)
         }
         addOnNewIntentListener(listener)
         onDispose { removeOnNewIntentListener(listener) }
     }
    

Conditions préalables

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

Étape 1 : Enregistrer un schéma

Pour gérer les liens profonds, un schéma personnalisé doit être déclaré dans votre fichier Info.plist. La structure de navigation est définie par un tableau de dictionnaires. Chacun de ces dictionnaires contient un tableau de chaînes de caractères.

Utilisez Xcode pour modifier votre fichier Info.plist :

  1. Ajoutez une nouvelle clé, URL types. Xcode en fera automatiquement un tableau contenant un dictionnaire appelé Item 0.
  2. Dans Item 0, ajoutez une clé URL identifier. Définissez la valeur sur votre schéma personnalisé.
  3. Dans Item 0, ajoutez une clé URL Schemes. Ce sera automatiquement un tableau contenant une chaîne Item 0.
  4. Définissez URL Schemes » Item 0 sur votre schéma personnalisé.

Sinon, si vous souhaitez modifier votre fichier Info.plist directement, vous pouvez suivre cette spécification :

1
2
3
4
5
6
7
8
9
10
11
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>YOUR.SCHEME</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>YOUR.SCHEME</string>
        </array>
    </dict>
</array>

Étape 2 : Ajouter une liste d’autorisations de schémas

Vous devez déclarer les schémas d’URL que vous souhaitez transmettre à canOpenURL(_:) en ajoutant la clé LSApplicationQueriesSchemes au fichier Info.plist de votre application. Toute tentative d’appel de schémas en dehors de cette liste d’autorisations entraînera l’enregistrement d’une erreur dans les journaux de l’appareil, et le lien profond ne s’ouvrira pas. Un exemple de cette erreur ressemblera à ceci :

1
<Warning>: -canOpenURL: failed for URL: "yourapp://deeplink" – error: "This app is not allowed to query for scheme yourapp"

Par exemple, si un message in-app doit ouvrir l’application Facebook lorsqu’on appuie dessus, l’application doit avoir le schéma personnalisé de Facebook (fb) dans votre liste d’autorisations. Sinon, le système rejettera le lien profond. Les liens profonds qui dirigent vers une page ou une vue au sein de votre propre application nécessitent toujours que le schéma personnalisé de votre application soit répertorié dans le fichier Info.plist de votre application.

Votre liste d’autorisations pourrait ressembler à ceci :

1
2
3
4
5
6
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>myapp</string>
    <string>fb</string>
    <string>twitter</string>
</array>

Pour plus d’informations, reportez-vous à la documentation d’Apple sur la clé LSApplicationQueriesSchemes.

Étape 3 : Implémenter un gestionnaire

Après l’activation de votre application, iOS appellera la méthode application:openURL:options:. L’argument important est l’objet NSURL.

1
2
3
4
5
6
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
  let path = url.path
  let query = url.query
  // Insert your code here to take some action based upon the path and query.
  return true
}
1
2
3
4
5
6
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  NSString *path  = [url path];
  NSString *query = [url query];
  // Insert your code here to take some action based upon the path and query.
  return YES;
}

App Transport Security (ATS)

Selon la définition d’Apple, « App Transport Security est une fonctionnalité qui améliore la sécurité des connexions entre une application et les services web. La fonctionnalité consiste en des exigences de connexion par défaut conformes aux meilleures pratiques visant les connexions sécurisées. Les applications peuvent remplacer ce comportement par défaut et désactiver la sécurité du transport. »

L’ATS est appliqué par défaut. Il nécessite que toutes les connexions utilisent HTTPS et soient chiffrées à l’aide de TLS 1.2 avec confidentialité de transmission. Pour plus d’informations, reportez-vous à la section Exigences pour la connexion à l’aide de l’ATS. Toutes les images servies par Braze aux terminaux sont gérées par un réseau de diffusion de contenu (« CDN ») qui prend en charge TLS 1.2 et est compatible avec ATS.

À moins qu’elles ne soient spécifiées comme exceptions dans le fichier Info.plist de votre application, les connexions qui ne respectent pas ces exigences échoueront et généreront des erreurs similaires à celles ci-dessous.

Exemple d’erreur 1 :

1
2
CFNetwork SSLHandshake failed (-9801)
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred, and a secure connection to the server cannot be made."

Exemple d’erreur 2 :

1
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

La conformité ATS est appliquée aux liens ouverts dans l’application mobile (notre gestion par défaut des liens cliqués) et ne s’applique pas aux sites ouverts à l’extérieur via un navigateur web.

Utilisation de l’ATS

Vous pouvez gérer l’ATS de l’une des manières suivantes, mais nous vous recommandons de vous conformer aux exigences de l’ATS.

Votre intégration Braze peut satisfaire aux exigences ATS en s’assurant que tous les liens existants vers lesquels vous dirigez les utilisateurs (par exemple, via des messages in-app et des campagnes de notifications push) satisfont aux exigences ATS. Bien qu’il existe des moyens de contourner les restrictions ATS, nous vous recommandons de vous assurer que toutes les URL liées sont conformes à l’ATS. Compte tenu de l’importance croissante accordée par Apple à la sécurité des applications, il n’est pas garanti que les approches suivantes pour autoriser les exceptions ATS soient prises en charge par Apple.

Vous pouvez autoriser un sous-ensemble de liens avec certains domaines ou schémas à être traités comme des exceptions aux règles ATS. Votre intégration Braze satisfera aux exigences ATS si chaque lien que vous utilisez dans un canal de communication Braze est soit conforme à l’ATS, soit géré par une exception.

Pour ajouter un domaine comme exception de l’ATS, ajoutez ce qui suit au fichier Info.plist de votre application :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

Pour plus d’informations, consultez l’article d’Apple sur les clés de sécurité pour le transport d’applications.

Vous pouvez désactiver complètement l’ATS. Notez que ce n’est pas une pratique recommandée, en raison à la fois des protections de sécurité perdues et de la future compatibilité iOS. Pour désactiver l’ATS, insérez les éléments suivants dans le fichier Info.plist de votre application :

1
2
3
4
5
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Décodage des URL

Le SDK encode les liens en pourcentage pour créer des URL valides. Tous les caractères de lien qui ne sont pas autorisés dans une URL correctement formée, tels que les caractères Unicode, seront échappés en pourcentage.

Pour décoder un lien encodé, utilisez la propriété String removingPercentEncoding. Vous devez également renvoyer true dans BrazeDelegate.braze(_:shouldOpenURL:). Un appel à l’action est nécessaire pour déclencher le traitement de l’URL par votre application. Par exemple :

1
2
3
4
5
  func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let urlString = url.absoluteString.removingPercentEncoding
    // Handle urlString
    return true
  }
1
2
3
4
5
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options {
  NSString *urlString = [url.absoluteString stringByRemovingPercentEncoding];
  // Handle urlString
  return YES;
}

Création de liens profonds vers les paramètres de l’application

Vous pouvez utiliser UIApplicationOpenSettingsURLString pour créer des liens profonds redirigeant les utilisateurs vers les paramètres de votre application à partir des notifications push Braze et des messages in-app.

Pour diriger les utilisateurs de votre application vers les paramètres iOS :

  1. Tout d’abord, assurez-vous que votre application est configurée pour les liens profonds basés sur un schéma ou les liens universels.
  2. Choisissez un URI pour le lien profond vers la page Paramètres (par exemple, myapp://settings ou https://www.braze.com/settings).
  3. Si vous utilisez des liens profonds basés sur un schéma personnalisé, ajoutez le code suivant à votre méthode application:openURL:options: :
1
2
3
4
5
6
7
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  let path = url.path
  if (path == "settings") {
    UIApplication.shared.openURL(URL(string:UIApplication.openSettingsURLString)!)
  }
  return true
}
1
2
3
4
5
6
7
8
9
10
- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  NSString *path  = [url path];
  if ([path isEqualToString:@"settings"]) {
    NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    [[UIApplication sharedApplication] openURL:settingsURL];
  }
  return YES;
}

Options de personnalisation

Personnalisation de la WebView par défaut

La classe Braze.WebViewController affiche les URL web ouvertes par le SDK, généralement lorsque l’option « Ouvrir l’URL Web dans l’application » est sélectionnée pour un lien profond web.

Vous pouvez personnaliser le Braze.WebViewController via la méthode de délégué BrazeDelegate.braze(_:willPresentModalWithContext:).

Personnalisation de la gestion des liens

Le protocole BrazeDelegate peut être utilisé pour personnaliser la gestion des URL telles que les liens profonds, les URL web et les liens universels. Pour définir le délégué lors de l’initialisation de Braze, définissez un objet délégué sur l’instance Braze. Braze appellera ensuite l’implémentation de shouldOpenURL de votre délégué avant de gérer les URI.

Lorsqu’une notification push ou un message in-app utilise Ouvrir l’URL web dans l’application mobile, Braze transmet context.useWebView == true sur Braze.URLContext. Lorsque le message ouvre l’URL dans le navigateur système, useWebView est false. Inspectez context.useWebView dans braze(_:shouldOpenURL:) pour adapter votre gestion personnalisée — par exemple, pour ouvrir un WebViewController in-app uniquement lorsque la campagne a demandé un affichage in-app.

Braze prend en charge les liens universels dans les notifications push, les messages in-app et les Content Cards. Pour activer la prise en charge des liens universels, configuration.forwardUniversalLinks doit être défini sur true.

Lorsque cette option est activée, Braze transmet les liens universels à l’AppDelegate de votre application via la méthode application:continueUserActivity:restorationHandler:.

Votre application doit également être configurée pour gérer les liens universels. Reportez-vous à la documentation d’Apple pour vous assurer que votre application est configurée correctement pour les liens universels.

Exemples

BrazeDelegate

Voici un exemple utilisant BrazeDelegate. Pour plus d’informations, consultez la référence du SDK Swift de Braze.

1
2
3
4
5
6
7
8
func braze(_ braze: Braze, shouldOpenURL context: Braze.URLContext) -> Bool {
  if context.url.host == "MY-DOMAIN.com" {
    // Custom handle link here
    return false
  }
  // Let Braze handle links otherwise
  return true
}
1
2
3
4
5
6
7
8
- (BOOL)braze:(Braze *)braze shouldOpenURL:(BRZURLContext *)context {
  if ([[context.url.host lowercaseString] isEqualToString:@"MY-DOMAIN.com"]) {
    // Custom handle link here
    return NO;
  }
  // Let Braze handle links otherwise
  return YES;
}
New Stuff!