ログコンテンツカードのデータを記録する
Content Cards用のカスタムUIを構築する場合、インプレッション、クリック、非表示といった分析データを手動で記録する必要があります。これらはデフォルトのカードモデルでのみ自動的に処理されるためです。これらのイベントの記録は、コンテンツカード統合の標準的な部分であり、正確なキャンペーンレポートと請求に不可欠です。これを行うには、カスタムUIにBrazeのデータモデルからデータを入力し、その後手動でイベントを記録します。分析の記録方法を理解したら、Brazeの顧客がカスタムContent Cardsを作成する一般的な方法を確認できます。
分析のログ記録
カスタムContent Cardsを実装する際、Content Cardオブジェクトを解析し、title、cardDescription、imageUrlなどのペイロードデータを抽出できます。その後、取得したモデルデータを使用してカスタムUIに表示できます。
Content Cardのデータモデルを取得するには、Content Cardの更新を購読します。特に注意すべきプロパティが2つあります。
id:Content CardのID文字列を表します。カスタムContent Cardsから分析をログに記録するために使用される一意の識別子です。extras:Brazeダッシュボードからのすべてのキーと値のペアを含みます。
idとextras以外のすべてのプロパティは、カスタムContent Cardsの解析においてオプションです。データモデルの詳細については、各プラットフォームの統合記事を参照してください:Android、iOS、Web。
カードが更新されたときに更新を購読するコールバック関数を登録します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import * as braze from "@braze/web-sdk";
braze.subscribeToContentCardsUpdates((updates) => {
const cards = updates.cards;
// For example:
cards.forEach(card => {
if (card.isControl) {
// Do not display the control card, but remember to call `logContentCardImpressions([card])`
}
else if (card instanceof braze.ClassicCard || card instanceof braze.CaptionedImage) {
// Use `card.title`, `card.imageUrl`, etc.
}
else if (card instanceof braze.ImageOnly) {
// Use `card.imageUrl`, etc.
}
})
});
braze.openSession();

ステップ1:プライベートサブスクライバー変数を作成する
カードの更新を購読するには、まずカスタムクラスでサブスクライバーを保持するプライベート変数を宣言します。
1
2
// subscriber variable
private IEventSubscriber<ContentCardsUpdatedEvent> mContentCardsUpdatedSubscriber;
ステップ2:更新を購読する
次に、以下のコードを追加してBrazeからのContent Cardの更新を購読します。通常、カスタムContent CardsアクティビティのActivity.onCreate()内に配置します。
1
2
3
4
5
6
7
8
9
10
11
12
13
// Remove the previous subscriber before rebuilding a new one with our new activity.
Braze.getInstance(context).removeSingleSubscription(mContentCardsUpdatedSubscriber, ContentCardsUpdatedEvent.class);
mContentCardsUpdatedSubscriber = new IEventSubscriber<ContentCardsUpdatedEvent>() {
@Override
public void trigger(ContentCardsUpdatedEvent event) {
// List of all Content Cards
List<Card> allCards = event.getAllCards();
// Your logic below
}
};
Braze.getInstance(context).subscribeToContentCardsUpdates(mContentCardsUpdatedSubscriber);
Braze.getInstance(context).requestContentCardsRefresh();
ステップ3:購読を解除する
カスタムアクティビティが画面外に移動する際に購読を解除することも推奨します。アクティビティのonDestroy()ライフサイクルメソッドに以下のコードを追加してください。
1
Braze.getInstance(context).removeSingleSubscription(mContentCardsUpdatedSubscriber, ContentCardsUpdatedEvent.class);
ステップ1:プライベートサブスクライバー変数を作成する
カードの更新を購読するには、まずカスタムクラスでサブスクライバーを保持するプライベート変数を宣言します。
1
private var contentCardsUpdatedSubscriber: IEventSubscriber<ContentCardsUpdatedEvent>? = null
ステップ2:更新を購読する
次に、以下のコードを追加してBrazeからのContent Cardの更新を購読します。通常、カスタムContent CardsアクティビティのActivity.onCreate()内に配置します。
1
2
3
4
5
6
7
8
9
10
// Remove the previous subscriber before rebuilding a new one with our new activity.
Braze.getInstance(context).removeSingleSubscription(contentCardsUpdatedSubscriber, ContentCardsUpdatedEvent::class.java)
contentCardsUpdatedSubscriber = IEventSubscriber { event ->
// List of all Content Cards
val allCards = event.allCards
// Your logic below
}
Braze.getInstance(context).subscribeToContentCardsUpdates(contentCardsUpdatedSubscriber)
Braze.getInstance(context).requestContentCardsRefresh(true)
ステップ3:購読を解除する
カスタムアクティビティが画面外に移動する際に購読を解除することも推奨します。アクティビティのonDestroy()ライフサイクルメソッドに以下のコードを追加してください。
1
Braze.getInstance(context).removeSingleSubscription(contentCardsUpdatedSubscriber, ContentCardsUpdatedEvent::class.java)
Content Cardsのデータモデルにアクセスするには、brazeインスタンスでcontentCards.cardsを呼び出します。
1
let cards: [Braze.ContentCard] = AppDelegate.braze?.contentCards.cards

contentCards.cards、contentCards.unviewedCards、またはcontentCards.lastUpdateを読み取ると、SDKが初期化後の操作を完了するまで呼び出しスレッドがブロックされます。メインスレッドやレイテンシに敏感なコンテキストでは、ノンブロッキングスナップショットアクセサーのノンブロッキングゲッターを使用してください。
さらに、Content Cardsの変更を監視するための購読を維持することもできます。以下の2つの方法があります。
- キャンセル可能オブジェクトを維持する方法
AsyncStreamを維持する方法
キャンセル可能オブジェクト
1
2
3
4
5
6
// This subscription is maintained through a Braze cancellable, which will observe for changes until the subscription is cancelled.
// You must keep a strong reference to the cancellable to keep the subscription active.
// The subscription is canceled either when the cancellable is deinitialized or when you call its `.cancel()` method.
let cancellable = AppDelegate.braze?.contentCards.subscribeToUpdates { [weak self] contentCards in
// Implement your completion handler to respond to updates in `contentCards`.
}
AsyncStream
1
let stream: AsyncStream<[Braze.ContentCard]> = AppDelegate.braze?.contentCards.cardsStream
ノンブロッキングスナップショットアクセサー
これらのメソッドを使用して、呼び出しスレッドをブロックせずに現在のキャッシュ状態を読み取ります。各完了ハンドラーは常にメインスレッドで配信されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// All cached cards.
AppDelegate.braze?.contentCards.getCachedContentCards { cards in
// Use `cards` here.
}
// Unviewed cards only (excludes control cards).
AppDelegate.braze?.contentCards.getUnviewedCards { cards in
// Use `cards` here.
}
// Date of the last server sync for the current user (nil until the first sync completes).
AppDelegate.braze?.contentCards.getLastUpdate { date in
// Use `date` here.
}
1
NSArray<BRZContentCardRaw *> *contentCards = AppDelegate.braze.contentCards.cards;
さらに、Content Cardsの購読を維持したい場合は、subscribeToUpdatesを呼び出すことができます。
1
2
3
4
// This subscription is maintained through Braze cancellable, which will continue to observe for changes until the subscription is cancelled.
BRZCancellable *cancellable = [self.braze.contentCards subscribeToUpdates:^(NSArray<BRZContentCardRaw *> *contentCards) {
// Implement your completion handler to respond to updates in `contentCards`.
}];
呼び出しスレッドをブロックせずに現在のキャッシュ状態を読み取るには、以下のメソッドを使用します。各完了ハンドラーはメインスレッドで配信されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// All cached cards.
[AppDelegate.braze.contentCards getCachedContentCardsWithCompletion:^(NSArray<BRZContentCardRaw *> *cards) {
// Use `cards` here.
}];
// Unviewed cards only (excludes control cards).
[AppDelegate.braze.contentCards getUnviewedCardsWithCompletion:^(NSArray<BRZContentCardRaw *> *cards) {
// Use `cards` here.
}];
// Date of the last server sync for the current user (nil until the first sync completes).
[AppDelegate.braze.contentCards getLastUpdateWithCompletion:^(NSDate * _Nullable date) {
// Use `date` here.
}];
更新をリッスンするには、Content Cardの更新イベントを購読します。
1
2
3
4
5
6
7
8
9
10
const subscription = Braze.addListener(Braze.Events.CONTENT_CARDS_UPDATED, (update) => {
const cards = update.cards;
cards.forEach(card => {
if (card.isControl) {
// Do not display the control card, but remember to log an impression
} else {
// Use card.title, card.cardDescription, card.image, etc.
}
});
});
最新のキャッシュされたContent Cardデータを取得するには:
1
2
3
import Braze from "@braze/react-native-sdk";
const cachedCards = await Braze.getCachedContentCards();
Brazeサーバーからの手動でのContent Cards更新をリクエストするには:
1
Braze.requestContentCardsRefresh();
イベントのログ記録
インプレッション、クリック、非表示などの重要な指標のログ記録は、迅速かつ簡単に行えます。カスタムクリックリスナーを設定して、これらの分析を手動で処理できます。
ユーザーがカードを閲覧した際に、logContentCardImpressionsを使用してインプレッションイベントをログに記録します。
1
2
3
import * as braze from "@braze/web-sdk";
braze.logContentCardImpressions([card1, card2, card3]);
ユーザーがカードを操作した際に、logContentCardClickを使用してカードクリックイベントをログに記録します。
1
2
3
import * as braze from "@braze/web-sdk";
braze.logContentCardClick(card);
BrazeManagerは、Content Cardsオブジェクト配列リストなどのBraze SDKの依存関係を参照して、Cardを取得し、Brazeのログ記録メソッドを呼び出すことができます。ContentCardable基底クラスを使用して、BrazeManagerにデータを簡単に参照・提供できます。
カードのインプレッションまたはクリックをログに記録するには、それぞれCard.logClick()またはCard.logImpression()を呼び出します。
特定のカードに対して、Content Cardsを手動でログに記録したり、Brazeに「非表示」として設定したりするには、isDismissedを使用します。カードがすでに非表示としてマークされている場合、再度非表示としてマークすることはできません。
カスタムクリックリスナーを作成するには、IContentCardsActionListenerを実装するクラスを作成し、BrazeContentCardsManagerに登録します。ユーザーがContent Cardsをクリックしたときに呼び出されるonContentCardClicked()メソッドを実装します。次に、BrazeにContent Cardsのクリックリスナーを使用するよう指示します。
例:
1
2
3
4
5
6
7
8
9
10
11
BrazeContentCardsManager.getInstance().setContentCardsActionListener(new IContentCardsActionListener() {
@Override
public boolean onContentCardClicked(Context context, Card card, IAction cardAction) {
return false;
}
@Override
public void onContentCardDismissed(Context context, Card card) {
}
});
例:
1
2
3
4
5
6
7
8
9
BrazeContentCardsManager.getInstance().contentCardsActionListener = object : IContentCardsActionListener {
override fun onContentCardClicked(context: Context, card: Card, cardAction: IAction): Boolean {
return false
}
override fun onContentCardDismissed(context: Context, card: Card) {
}
}

カスタムUIでコントロールバリアントのContent Cardsを処理するには、com.braze.models.cards.Cardオブジェクトを渡し、他のContent Cardsタイプと同様にlogImpressionメソッドを呼び出します。このオブジェクトは、ユーザーがコントロールカードを閲覧したタイミングを分析に通知するために、コントロールインプレッションを暗黙的にログに記録します。
BrazeContentCardUIViewControllerDelegateプロトコルを実装し、デリゲートオブジェクトをBrazeContentCardUI.ViewControllerのdelegateプロパティとして設定します。このデリゲートは、カスタムオブジェクトのデータをBrazeに渡してログに記録する処理を行います。例については、Content Cards UIチュートリアルを参照してください。
1
2
3
4
5
6
7
8
9
10
11
12
// Set the delegate when creating the Content Cards controller
contentCardsController.delegate = delegate
// Method to implement in delegate
func contentCard(
_ controller: BrazeContentCardUI.ViewController,
shouldProcess clickAction: Braze.ContentCard.ClickAction,
card: Braze.ContentCard
) -> Bool {
// Intercept the content card click action here.
return true
}
1
2
3
4
5
6
7
8
9
10
// Set the delegate when creating the Content Cards controller
contentCardsController.delegate = delegate;
// Method to implement in delegate
- (BOOL)contentCardController:(BRZContentCardUIViewController *)controller
shouldProcess:(NSURL *)url
card:(BRZContentCardRaw *)card {
// Intercept the content card click action here.
return YES;
}

カスタムUIでコントロールバリアントのContent Cardsを処理するには、Braze.ContentCard.Controlオブジェクトを渡し、他のContent Cardsタイプと同様にlogImpressionメソッドを呼び出します。このオブジェクトは、ユーザーがコントロールカードを閲覧したタイミングを分析に通知するために、コントロールインプレッションを暗黙的にログに記録します。
ユーザーがカードを閲覧した際に、インプレッションイベントをログに記録します。
1
Braze.logContentCardImpression(card.id);
ユーザーがカードを操作した際に、カードクリックイベントをログに記録します。
1
Braze.logContentCardClicked(card.id);
ユーザーがカードを非表示にした際に、非表示イベントをログに記録します。
1
Braze.logContentCardDismissed(card.id);
クリック時の動作の処理
カスタムフィードでユーザーがContent Cardsをクリックした場合、クリック時の動作(URLへの遷移、ディープリンク、カスタムイベントのログ記録など)は自動的には処理されません。handleBrazeActionを使用して、カードのURLを処理し、Brazeアクション(brazeActions:// URL)を含む設定済みのクリック時アクションを実行します。
1
2
3
4
5
6
7
8
9
10
11
12
import * as braze from "@braze/web-sdk";
// In your card click handler
function onCardClick(card) {
// Log the click
braze.logContentCardClick(card);
// Handle the on-click behavior
if (card.url) {
braze.handleBrazeAction(card.url);
}
}
| パラメーター | 説明 |
|---|---|
url |
有効なURL、またはスキームbrazeActions://を持つ有効なBrazeアクションURL。 |
openLinkInNewTab |
(オプション)URLを新しいタブで開くかどうか。デフォルトはfalseです。 |

handleBrazeAction()を呼び出さない場合、Brazeダッシュボードで設定されたクリック時の動作(「カスタムイベントをログに記録」や「URLに遷移」など)は、カスタムフィードに表示されるカードに対して実行されません。
クリック時の動作は、デフォルトのContent Cards UIによって自動的に処理されます。カスタム実装の場合は、分析のログ記録で説明されているIContentCardsActionListenerインターフェイスを使用します。
クリック時の動作は、デフォルトのContent Cards UIによって自動的に処理されます。カスタム実装の場合は、分析のログ記録で説明されているBrazeContentCardUIViewControllerDelegateプロトコルを使用します。
カスタムフィードでユーザーがContent Cardsをクリックした場合、クリック時の動作は自動的には処理されません。Braze.logContentCardClicked(cardId)でクリックをログに記録した後、Braze.processContentCardClickAction(cardId)を呼び出して、ディープリンク、URL、およびbrazeActions://アクションを処理します。メソッドリファレンスについては、React Native Content Cardsを参照してください。
1
2
3
4
5
6
7
8
9
import Braze from "@braze/react-native-sdk";
function onCardPress(card) {
Braze.logContentCardClicked(card.id);
if (card.url) {
Braze.processContentCardClickAction(card.id);
}
}

processContentCardClickAction()を呼び出さない場合、Brazeダッシュボードで設定されたクリック時の動作は、カスタムフィード内のカードに対して実行されません。