Skip to main content

Product hydration

Product hydration allows your app to supply enriched product data (pricing, images, variants, stock) to the Bambuser live player at runtime. When a live show starts, the player fires a provide-product-data event listing all products it needs data for. Your app looks up each product by SKU and pushes the data back into the player using viewActions.invoke("updateProductWithData", ...).

Prerequisites​

currency and locale must be set in your player configuration — product hydration will not work without them.

application.globalBambuserSDK.GetLiveView(
modifier = Modifier.fillMaxSize(),
videoConfiguration = BambuserVideoConfiguration(
events = listOf("*"),
configuration = mapOf(
"currency" to "USD", // Required for product hydration
"locale" to "en-US" // Required for product hydration
),
videoType = BambuserVideoAsset.Live(showId)
),
videoPlayerDelegate = videoPlayerDelegate
)

Handle the provide-product-data Event​

The player fires provide-product-data at show start, and again whenever a new product needs to be displayed. Handle it in your BambuserVideoPlayerDelegate:

videoPlayerDelegate = object : BambuserVideoPlayerDelegate {
override fun onNewEventReceived(
playerId: String,
event: BambuserEventPayload,
viewActions: ViewActions
) {
when (event.event) {
"provide-product-data" -> {
(event.data["products"] as? List<Map<String, Any>>)?.let { products ->
products.forEach { product ->
val productId = product["id"]?.toString() ?: return@forEach
val sku = product["ref"]?.toString() ?: return@forEach

lifecycleScope.launch {
viewActions.invoke(
function = "updateProductWithData",
arguments = buildHydrationArguments(productId, sku)
)
}
}
}
}
}
}
}

The event payload products array has:

FieldTypeDescription
idStringBambuser-generated product ID — pass this back to the player
refStringYour product SKU — use this to look up your own data
urlStringProduct URL as set in the Bambuser dashboard

Send Product Data Back to the Player​

The arguments string must start with the Bambuser product id in single quotes, followed by a comma and the product object as a JavaScript object literal:

fun buildHydrationArguments(productId: String, sku: String): String {
// Look up your product data by SKU
val product = YourProductService.findBySku(sku) ?: return "'$productId', {}"

return """
'$productId', {
sku: '${product.sku}',
name: '${product.name}',
brandName: '${product.brand}',
introduction: '${product.shortDescription}',
description: '${product.description}',
variations: [
{
sku: '${product.variationSku}',
name: '${product.variationName}',
colorName: '${product.colorName}',
imageUrls: ['${product.imageUrl}'],
sizes: [
{
sku: '${product.sizeSku}',
currency: 'USD',
current: ${product.price},
original: ${product.originalPrice},
name: '${product.sizeName}',
inStock: ${product.stock}
}
]
}
]
}
""".trimIndent()
}

Full Product Data Structure​

Product​

FieldTypeRequiredDescription
skuStringYesYour product SKU / identifier
nameStringYesProduct display name
brandNameStringYesBrand name
introductionStringNoShort introductory text
descriptionStringNoFull description — supports HTML
variationsArrayYesList of product variations (colors/styles)

Variation​

FieldTypeRequiredDescription
skuStringYesVariation SKU
nameStringYesVariation display name
colorNameStringYesColor name shown in the variation selector
colorHexCodeStringNoHex color code e.g. "#000000"
imageUrls[String]YesOrdered list of image URLs for this variation
sizesArrayYesList of sizes/SKUs for this variation

Size​

FieldTypeRequiredDescription
skuStringYesSize-level SKU
nameStringYesSize name e.g. "Small", "XL"
currentDoubleYesCurrent (sale) price
originalDoubleNoOriginal price — shown as strike-through
currencyStringYesThree-letter currency code e.g. "USD"
inStockIntYesAvailable stock quantity (0 = out of stock)
perUnitDoubleNoPrice per unit (for bundle/multi-pack pricing)
unitAmountIntNoQuantity per unit
unitDisplayNameStringNoUnit label e.g. "kg", "L", "st"

Complete Example​

fun buildHydrationArguments(productId: String) = """
'$productId', {
sku: '7777',
name: 'Bambuser Hoodie',
brandName: 'Bambuser',
introduction: 'A nice hoodie that keeps you warm',
description: "<div><h2>World's best hoodie</h2><p>Comes in all sizes!</p></div>",
variations: [
{
sku: '1111-black',
name: 'Black Bambuser Hoodie',
colorName: 'black',
imageUrls: [
'https://demo.bambuser.shop/wp-content/uploads/2021/07/black-hoodie-front.png',
'https://demo.bambuser.shop/wp-content/uploads/2021/07/black-hoodie-back.jpeg',
],
sizes: [
{
sku: '1111-black-small',
currency: 'USD',
current: 120,
original: 120,
name: 'Small',
inStock: 9,
},
{
sku: '1111-black-xlarge',
currency: 'USD',
current: 100,
original: 120,
name: 'X-Large',
inStock: 3,
},
],
},
{
sku: '1111-white',
name: 'White Bambuser Hoodie',
colorName: 'white',
imageUrls: [
'https://demo.bambuser.shop/wp-content/uploads/2021/07/white-hoodie-front.png',
'https://demo.bambuser.shop/wp-content/uploads/2021/07/white-hoodie-back.jpeg',
],
sizes: [
{
sku: '1111-white-small',
currency: 'USD',
current: 100,
original: 120,
name: 'Small',
inStock: 8,
},
{
sku: '1111-white-xlarge',
currency: 'USD',
current: 100,
original: 120,
name: 'X-Large',
inStock: 0,
},
],
},
],
}
"""

Notes​

  • The player may fire provide-product-data multiple times during a show as products are highlighted. Your handler must be idempotent.
  • Fields not provided in your hydration response fall back to data previously scraped or manually set in the Bambuser dashboard.
  • Builder functions are available for iOS only (see the iOS SDK example app). Android requires raw string construction.
  • viewActions.invoke is a suspend function — always call it inside a coroutine scope (lifecycleScope.launch {}).