Using multiple Content Card feeds
Content Cards can be filtered on the app to only display specific cards, enabling you to have multiple Content Card feeds for different use cases (for example, a transactional feed or a marketing feed).
The following documentation demonstrates an example implementation that can be changed to fit your specific integration.
Step 1: Setting key-value pairs on cards
When creating a Content Card campaign, key-value pair data can be set on each card. Our filtering logic will use this key-value pair data to categorize cards. Note that we do not recommend sending nested JSON values as key-value pairs. Instead, we recommend flattening the JSON before sending it.
For this example, we’ll set a key-value pair with the key feed_type
that will designate which Content Card feed the card should be displayed in. The value will be whatever your custom feeds will be, as in Transactional
, Marketing
, and more.
Step 2: Create a Content Card update handler
To perform filtering on a ContentCardsFragment
, we will create a use a custom IContentCardsUpdateHandler
. A IContentCardsUpdateHandler
takes a ContentCardsUpdatedEvent
from the Braze SDK and returns a list of cards to display.
In our example handler, we’ll first sort the cards using the default IContentCardsUpdateHandler
. The default Braze IContentCardsUpdateHandler
only sorts cards and, by default, doesn’t perform any removals or filtering on its own. Next, we’ll remove any cards from the list that don’t match our desired value for the feed_type
that we set earlier:
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
private IContentCardsUpdateHandler getUpdateHandlerForFeedType(final String desiredFeedType) {
return new IContentCardsUpdateHandler() {
@Override
public List<Card> handleCardUpdate(ContentCardsUpdatedEvent event) {
// Use the default card update handler for a first
// pass at sorting the cards. This is not required
// but is done for convenience.
final List<Card> cards = new DefaultContentCardsUpdateHandler().handleCardUpdate(event);
final Iterator<Card> cardIterator = cards.iterator();
while (cardIterator.hasNext()) {
final Card card = cardIterator.next();
// Make sure the card has our custom KVP
// from the dashboard with the key "feed_type"
if (card.getExtras().containsKey("feed_type")) {
final String feedType = card.getExtras().get("feed_type");
if (!desiredFeedType.equals(feedType)) {
// The card has a feed type, but it doesn't match
// our desired feed type, remove it.
cardIterator.remove();
}
} else {
// The card doesn't have a feed
// type at all, remove it
cardIterator.remove();
}
}
// At this point, all of the cards in this list have
// a feed type that explicitly matches the value we put
// in the dashboard.
return cards;
}
};
}
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
private fun getUpdateHandlerForFeedType(desiredFeedType: String): IContentCardsUpdateHandler {
return IContentCardsUpdateHandler { event ->
// Use the default card update handler for a first
// pass at sorting the cards. This is not required
// but is done for convenience.
val cards = DefaultContentCardsUpdateHandler().handleCardUpdate(event)
val cardIterator = cards.iterator()
while (cardIterator.hasNext()) {
val card = cardIterator.next()
// Make sure the card has our custom KVP
// from the dashboard with the key "feed_type"
if (card.extras.containsKey("feed_type")) {
val feedType = card.extras["feed_type"]
if (desiredFeedType != feedType) {
// The card has a feed type, but it doesn't match
// our desired feed type, remove it.
cardIterator.remove()
}
} else {
// The card doesn't have a feed
// type at all, remove it
cardIterator.remove()
}
}
// At this point, all of the cards in this list have
// a feed type that explicitly matches the value we put
// in the dashboard.
cards
}
}
Step 3: Create a Content Card feed using the custom update handler
Now that we have a custom IContentCardsUpdateHandler
, we can create a ContentCardsFragment
that uses it. In the following example code, we’ll create a ContentCardsFragment
that only displays cards where the feed_type
is “Transactional”:
1
2
3
// We want a Content Cards feed that only shows "Transactional" cards.
ContentCardsFragment customContentCardsFragment = new ContentCardsFragment();
customContentCardsFragment.setContentCardUpdateHandler(getUpdateHandlerForFeedType("Transactional"));
1
2
3
// We want a Content Cards feed that only shows "Transactional" cards.
val customContentCardsFragment = ContentCardsFragment()
customContentCardsFragment.contentCardUpdateHandler = getUpdateHandlerForFeedType("Transactional")
Step 4: Using the Content Cards fragment
This custom feed can be used like any other ContentCardsFragment
. In the different parts of your app, you can display different Content Card feeds based on the key provided on the dashboard. Each ContentCardsFragment
feed will have a unique set of cards displayed thanks to the custom IContentCardsUpdateHandler
on each fragment.
When creating a Content Card campaign, set your key-value pair where the key is feed_type
and the value is Transactional
.