Skip to content

高度なプッシュ通知の例

次のガイドでは、Braze SDKの高度なプッシュ通知のいくつかの例について説明します。

前提条件

この機能を使用する前に、Android Braze SDKを統合する必要がある。 また、プッシュ通知sを設定する必要があります。

カスタム通知レイアウト

Braze 通知 s はデータメッセージ として送信されます。つまり、アプリライセンスは、バックグラウンド内でも(アプリがバックグラウンドにいるときにシステムによって自動的に処理される通知 メッセージとは対照的に)、それに応じて応答し、動作を実行する機会を常に持っています。そのため、通知トレイに配信される通知にパーソナライズされた UI 要素を表示するなどして、アプリケーションでエクスペリエンスをカスタマイズできます。この方法でプッシュを実装することに慣れていない方もいるかもしれませんが、Braze でよく知られている機能の 1 つであるプッシュ通知ストーリーは、カスタムビューコンポーネントを使用して魅力的なエクスペリエンスを生み出す機能の良い例です。

IBrazeNotificationFactory インターフェイスを使用して、Braze プッシュ通知の表示方法をカスタマイズできます。BrazeNotificationFactory を拡張することで、通知がユーザーに表示される前に Braze はファクトリーのcreateNotification() メソッドを呼び出します。その後、Braze ダッシュボードまたは REST API を通じて送信されたカスタムのキーと値のペアを含むペイロードを渡します。

このセクションでは、野生動物救助チームが誰が一番多くのフクロウを救えるかを競う新しいゲーム番組の司会者、スーパーブクロウとパートナーを組むことになる。通知 s をAndroid アプリでライブアップデートすることで、進行中の試合のステータスを表示し、リアルタイムでダイナミックな 更新を作成できるようにすることを求めています。

Superb Owlが見せたいライブアップデート。「ワイルドバード・ファンド」と「オール・レスキュー」の間で進行中の試合を表示する。現在のところ第4四半期で、OWLがリードしているスコアは2-4です。

ステップ 1: カスタムレイアウトの追加

1 つ以上のカスタム通知 リモートビューレイアウトをプロジェクトに追加できます。これらは、折りたたんだり展開したりしたときに通知sがどのように表示されるかを扱うのに役立ちます。ディレクトリ構造は、次のようになります。

1
2
3
4
5
6
.
├── app/
└── res/
    └── layout/
        ├── liveupdate_collapsed.xml
        └── liveupdate_expanded.xml

各XMLファイルで、カスタムレイアウトを作成します。Superb Owl は、折りたたまれて展開されたRemoteView レイアウト用に次のレイアウトを作成しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/notification_title"
        style="@style/TextAppearance.Compat.Notification.Title"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>
Show the sample code
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_gravity="center"

        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/team1logo"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_gravity="center"
            android:src="@drawable/team_default1"/>

        <TextView
            android:id="@+id/team1name"
            android:textAlignment="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1.6"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/score"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="2-4"
            android:textColor="#555555"
            android:textAlignment="center"
            android:textSize="32sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/timeInfo"
            android:textAlignment="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>


    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/team2logo"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:src="@drawable/team_default2"/>

        <TextView
            android:id="@+id/team2name"
            android:textAlignment="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</LinearLayout>

ステップ 2:カスタム通知ファクトリーを作成する

アプリ ライセンスで、BrazeNotificationFactory という名前の新しいファイルを作成し、カスタムRemoteView レイアウトの表示方法を処理します。

次の例では、Superb Owlがカスタム通知ファクトリを作成し、現在のマッチングのRemoteViewレイアウトを表示しました。next ステップ では、getTeamInfo という新しいメソッドを作成して、チームデータをアクティビティにマッピングします。

Show the sample code
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
55
56
57
58
59
60
61
import android.app.Notification
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.braze.models.push.BrazeNotificationPayload
import com.braze.push.BrazeNotificationFactory
import com.braze.push.BrazeNotificationUtils.getOrCreateNotificationChannelId
import com.braze.support.BrazeLogger.brazelog

class MyCustomNotificationFactory : BrazeNotificationFactory() {
    override fun createNotification(payload: BrazeNotificationPayload): Notification? {
        if (payload.extras.containsKey("live_update")) {
            val kvp = payload.extras
            val notificationChannelId = getOrCreateNotificationChannelId(payload)
            val context = payload.context

            if (context == null) {
                brazelog { "BrazeNotificationPayload has null context. Not creating notification" }
                return null
            }

            val team1 = kvp["team1"]
            val team2 = kvp["team2"]
            val score1 = kvp["score1"]
            val score2 = kvp["score2"]
            val time = kvp["time"]
            val quarter = kvp["quarter"]

            // Superb Owl will define the 'getTeamInfo' method in the next step.
            val (team1name, team1icon) = getTeamInfo(team1)
            val (team2name, team2icon) = getTeamInfo(team2)

            // Get the layouts to use in the custom notification.
            val notificationLayoutCollapsed = RemoteViews(BuildConfig.APPLICATION_ID, R.layout.liveupdate_collapsed)
            val notificationLayoutExpanded = RemoteViews(BuildConfig.APPLICATION_ID, R.layout.liveupdate_expanded)

            // Very simple notification for the small layout
            notificationLayoutCollapsed.setTextViewText(
                R.id.notification_title,
                "$team1 $score1 - $score2 $team2\n$time $quarter"
            )

            notificationLayoutExpanded.setTextViewText(R.id.score, "$score1 - $score2")
            notificationLayoutExpanded.setTextViewText(R.id.team1name, team1name)
            notificationLayoutExpanded.setTextViewText(R.id.team2name, team2name)
            notificationLayoutExpanded.setTextViewText(R.id.timeInfo, "$time - $quarter")
            notificationLayoutExpanded.setImageViewResource(R.id.team1logo, team1icon)
            notificationLayoutExpanded.setImageViewResource(R.id.team2logo, team2icon)

            val customNotification = NotificationCompat.Builder(context, notificationChannelId)
                .setSmallIcon(R.drawable.notification_small_icon)
                .setStyle(NotificationCompat.DecoratedCustomViewStyle())
                .setCustomContentView(notificationLayout)
                .setCustomBigContentView(notificationLayoutExpanded)
                .build()
            return customNotification
        } else {
            // Use the BrazeNotificationFactory for all other notifications
            return super.createNotification(payload)
        }
    }
}

ステップ 3:顧客データをマップする

MyCustomNotificationFactory.kt で、ライブ更新が表示されたときにデータを処理するための新しいメソッドを作成する。

Superb Owlは、各チームの名前とロゴを拡大されたライブ更新に対応させるために、以下の方法を作成した:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CustomNotificationFactory : BrazeNotificationFactory() {
    override fun createNotification(payload: BrazeNotificationPayload): Notification? {
        // Your existing code
        return super.createNotification(payload)
    }

    // Your new method
    private fun getTeamInfo(team: String?): Pair<String, Int> {
        return when (team) {
            "WBF" -> Pair("Wild Bird Fund", R.drawable.team_wbf)
            "OWL" -> Pair("Owl Rehab", R.drawable.team_owl)
            else  -> Pair("Unknown", R.drawable.notification_small_icon)
        }
    }
}

ステップ 4: カスタム通知ファクトリーを設定する

アプリケーションクラスで customBrazeNotificationFactory を使用して、カスタム通知ファクトリを設定します。

1
2
3
4
5
6
7
8
9
10
import com.braze.Braze

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // Tell Braze to use your custom factory for notifications
        Braze.customBrazeNotificationFactory = MyCustomNotificationFactory()
    }
}

ステップ 5: アクティビティを送信する

あなたは /messages/sendREST APIエンドポイントを使用して、ユーザーのAndroidデバイスにプッシュ通知を送信できる。

curlコマンドの例

Superb Owl は以下の curl コマンドを使ってリクエストを送信しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
curl -X POST "https://BRAZE_REST_ENDPOINT/messages/send" \
  -H "Authorization: Bearer {REST_API_KEY}" \
  -H "Content-Type: application/json" \
  --data '{
    "external_user_ids": ["USER_ID"],
    "messages": {
      "android_push": {
        "title": "WBF vs OWL",
        "alert": "2 to 4 1:33 Q4",
        "extra": {
          "live_update": "true",
          "team1": "WBF",
          "team2": "OWL",
          "score1": "2",
          "score2": "4",
          "time": "1:33",
          "quarter": "Q4"
        },
        "notification_id": "ASSIGNED_NOTIFICATION_ID"
      }
    }
  }'

リクエストパラメーター

ステップ 6: アクティビティを更新する

既存のRemoteView 通知を新しいデータで更新するには、messages.extra に割り当てられた関連するキーと値のペアを変更し、同じnotification_id を使用して/messages/send エンドポイントを再度呼び出します。

パーソナライズされたプッシュ通知

プッシュ通知では、カスタムビュー階層内にユーザー固有の情報を表示できます。次の例では、API-トリガーを使用してパーソナライズされた プッシュ通知をユーザーに送信し、アプリで特定のタスクを完了した後に現在の進行状況を追跡できるようにします。

パーソナライズされたプッシュダッシュボード例

ダッシュボードでパーソナライズされたプッシュを設定するには、表示するカテゴリを登録し、リキッドを使用して表示する関連ユーザー 属性を設定します。

パーソナライズされたプッシュダッシュボード例

前提条件

この機能を使う前に、Swift Braze SDKを統合する必要がある。 また、プッシュ通知の設定も必要です。

通知コンテンツアプリ拡張機能

並んで表示される2つのプッシュメッセージ。左側のメッセージはデフォルトのUIでのプッシュの見た目を示しています。右側のメッセージはカスタムプッシュUIを実装して作成したコーヒーパンチカードプッシュを表示しています。

通知コンテンツアプリ拡張機能は、プッシュ通知のカスタマイズに最適なオプションを提供します。プッシュ通知を展開すると、通知コンテンツアプリ拡張機能によって、アプリの通知のカスタムインターフェイスが表示されます。

プッシュ通知は、次の3つの方法で展開できます。

  • プッシュバナーを長押しする
  • プッシュバナーを下にスワイプする
  • バナーを左にスワイプして「表示」を選択する

これらのカスタムビューでは、インタラクティブな通知、ユーザーデータを含む通知、電話番号やメールなどの情報を取得できるプッシュメッセージなど、さまざまな種類のコンテンツを表示して顧客をエンゲージするスマートな方法を提供します。Brazeでよく知られている機能の1つであるPush Storiesは、プッシュ通知コンテンツアプリ拡張機能がどのようなものかを示す代表的な例です。

要件

  • プッシュ通知がアプリに正常に統合されていること
  • コーディング言語に基づいてXcodeによって生成される以下のファイル:

Swift

  • NotificationViewController.swift
  • MainInterface.storyboard

Objective-C

  • NotificationViewController.h
  • NotificationViewController.m
  • MainInterface.storyboard

インタラクティブなプッシュ通知

プッシュ通知は、コンテンツアプリ拡張機能内でユーザーのアクションに応答できます。iOS 12以降を使用しているユーザーの場合、プッシュ通知を完全にインタラクティブなメッセージに変えることができます。これにより、プロモーションやアプリケーションにインタラクティビティを導入するエキサイティングなオプションが提供されます。例えば、プッシュ通知にユーザーがプレイできるゲーム、割引のためのスピン・トゥ・ウィンホイール、リストや曲を保存するための「いいね」ボタンなどを含めることができます。

次の例は、ユーザーが展開された通知内でマッチゲームをプレイできるプッシュ通知を示しています。

インタラクティブなプッシュ通知のフェーズがどのように見えるかを示す図。シーケンスは、ユーザーがインタラクティブなマッチングゲームを表示するプッシュ通知を押す様子を示しています。

ダッシュボードの設定

インタラクティブなプッシュ通知を作成するには、ダッシュボードにカスタムビューを設定する必要があります。

  1. Campaignsページから、Create Campaignをクリックして新しいプッシュ通知キャンペーンを開始します。
  2. Composeタブで、Notification Buttonsをオンに切り替えます。
  3. iOS Notification CategoryフィールドにカスタムiOSカテゴリを入力します。
  4. 通知コンテンツ拡張ターゲットの.plistで、UNNotificationExtensionCategory属性をカスタムiOSカテゴリに設定します。ここに指定する値は、BrazeダッシュボードのiOS Notification Categoryで設定されているものと一致する必要があります。
  5. UNNotificationExtensionInteractionEnabledキーをtrueに設定して、プッシュ通知でのユーザー操作を有効にします。

プッシュメッセージ作成画面の設定にある通知ボタンオプション。

パーソナライズ済みプッシュ通知

2台のiPhoneが並んで表示されています。1台目のiPhoneにはプッシュメッセージの展開前のビューが表示されています。2台目のiPhoneにはプッシュメッセージの展開バージョンが表示され、コースの進捗状況、次のセッション名、次のセッションの完了期限が表示されています。

プッシュ通知では、コンテンツ拡張機能内にユーザー固有の情報を表示できます。これにより、さまざまなプラットフォームで進捗を共有するオプションの追加、アンロックされた実績の表示、オンボーディングチェックリストの表示など、ユーザー中心のプッシュコンテンツを作成できます。この例は、ユーザーがBrazeラーニングコースで特定のタスクを完了した後に表示されるプッシュ通知を示しています。通知を展開することで、ユーザーは学習パスの進捗を確認できます。ここで提供される情報はユーザー固有であり、セッションが完了するか、APIトリガーを利用して特定のユーザーアクションが実行されたときに発火させることができます。

ダッシュボードの設定

パーソナライズ済みプッシュ通知を作成するには、ダッシュボードにカスタムビューを設定する必要があります。

  1. Campaignsページから、Create Campaignをクリックして新しいプッシュ通知キャンペーンを開始します。
  2. Composeタブで、Notification Buttonsをオンに切り替えます。
  3. iOS Notification CategoryフィールドにカスタムiOSカテゴリを入力します。
  4. Settingsタブで、標準のLiquidを使用してキーと値のペアを作成します。メッセージに表示したい適切なユーザー属性を設定します。これらのビューは、特定のユーザープロファイルの特定のユーザー属性に基づいてパーソナライズできます。
  5. 通知コンテンツ拡張ターゲットの.plistで、UNNotificationExtensionCategory属性をカスタムiOSカテゴリに設定します。ここに指定する値は、BrazeダッシュボードのiOS Notification Categoryで設定されているものと一致する必要があります。

Liquidを使用してAPIトリガープロパティとして「next_session_name」と「next_session_complete_date」が設定され、Liquidを使用してカスタムユーザー属性として「completed_session count」と「total_session_count」が設定された4組のキーと値のペア。

キーと値のペアの処理

メソッドdidReceiveは、通知コンテンツアプリ拡張機能が通知を受信したときに呼び出されます。このメソッドはNotificationViewController内にあります。ダッシュボードで提供されるキーと値のペアは、userInfo辞書を使用してコード内で表現されます。

プッシュ通知からのキーと値のペアの解析

1
2
3
4
5
6
7
8
9
func didReceive(_ notification: UNNotification) {
  let userInfo = notification.request.content.userInfo

  guard let value = userInfo["YOUR-KEY-VALUE-PAIR"] as? String,
        let otherValue = userInfo["YOUR-OTHER-KEY-VALUE-PAIR"] as? String,
  else { fatalError("Key-Value Pairs are incorrect.")}

  ...
}
1
2
3
4
5
6
7
8
9
10
11
- (void)didReceiveNotification:(nonnull UNNotification *)notification {
  NSDictionary *userInfo = notification.request.content.userInfo;

  if (userInfo[@"YOUR-KEY-VALUE-PAIR"] && userInfo[@"YOUR-OTHER-KEY-VALUE-PAIR"]) {

  ...

  } else {
    [NSException raise:NSGenericException format:@"Key-Value Pairs are incorrect"];
  }
}

情報取得プッシュ通知

プッシュ通知は、コンテンツアプリ拡張機能内でユーザー情報をキャプチャし、プッシュで可能なことの限界を押し広げます。プッシュ通知を通じてユーザー入力をリクエストすることで、名前やメールなどの基本的な情報をリクエストできるだけでなく、フィードバックの送信や未完成のユーザープロファイルの完成をユーザーに促すこともできます。

次のフローでは、カスタムビューは状態の変化に応答できます。これらの状態変更コンポーネントは、各画像に表示されています。

  1. ユーザーがプッシュ通知を受信します。
  2. プッシュが開封されます。展開後、プッシュはユーザーに情報を求めます。この例では、ユーザーのメールアドレスがリクエストされますが、任意の種類の情報をリクエストすることもできます。
  3. 情報が提供され、期待される形式であれば、登録ボタンが表示されます。
  4. 確認ビューが表示され、プッシュが閉じられます。

ダッシュボードの設定

情報取得プッシュ通知を作成するには、ダッシュボードにカスタムビューを設定する必要があります。

  1. Campaignsページから、Create Campaignをクリックして新しいプッシュ通知キャンペーンを開始します。
  2. Composeタブで、Notification Buttonsをオンに切り替えます。
  3. iOS Notification CategoryフィールドにカスタムiOSカテゴリを入力します。
  4. Settingsタブで、標準のLiquidを使用してキーと値のペアを作成します。メッセージに表示したい適切なユーザー属性を設定します。
  5. 通知コンテンツ拡張ターゲットの.plistで、UNNotificationExtensionCategory属性をカスタムiOSカテゴリに設定します。ここに指定する値は、BrazeダッシュボードのiOS Notification Categoryで設定されているものと一致する必要があります。

例に見られるように、プッシュ通知に画像を含めることもできます。これを行うには、リッチプッシュ通知を統合し、キャンペーンの通知スタイルをリッチプッシュ通知に設定し、リッチプッシュ画像を含める必要があります。

キーと値のペアが3セットあるプッシュメッセージ。1.「Braze_id」はBraze IDを取得するためのLiquidコールとして設定。2.「cert_title」は「Braze Marketer Certification」として設定。3.「Cert_description」は「Certified Braze marketers drive...」として設定。

ボタンアクションの処理

各アクションボタンは一意に識別されます。コードは、応答識別子がactionIdentifierと等しいかどうかをチェックし、等しい場合はユーザーがアクションボタンをクリックしたことを認識します。

プッシュ通知アクションボタンの応答の処理

1
2
3
4
5
6
7
func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
  if response.actionIdentifier == "YOUR-REGISTER-IDENTIFIER" {
    // do something
  } else {
    // do something else
  }
}
1
2
3
4
5
6
7
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion {
  if ([response.actionIdentifier isEqualToString:@"YOUR-REGISTER-IDENTIFIER"]) {
    completion(UNNotificationContentExtensionResponseOptionDismiss);
  } else {
    completion(UNNotificationContentExtensionResponseOptionDoNotDismiss);
  }
}

プッシュの閉じ方

プッシュ通知は、アクションボタンを押すと自動的に閉じることができます。推奨される組み込みのプッシュ閉じオプションは3つあります。

  1. completion(.dismiss) - 通知を閉じます
  2. completion(.doNotDismiss) - 通知は開いたままになります
  3. completion(.dismissAndForward) - プッシュが閉じられ、ユーザーがアプリケーションに転送されます
New Stuff!