Track events
This page sends commerce events to Grona. Grona logs its own campaign events, such as exposures and taps, but it needs your app to report what the shopper did next: products viewed, cart changes, checkout and purchase. Forward them from the same analytics layer that feeds your other tools.
The events
Section titled “The events”Build each event with a GronaEvent factory and pass it to Grona.track. Money is in minor units, so 349 is 3.49.
| Factory | Send it when |
|---|---|
GronaEvent.viewItem(productId, priceMinor) |
A product page opens. |
GronaEvent.addToCart(productId, qty, priceMinor) |
A quantity of a product is added to the cart. priceMinor is the unit price. |
GronaEvent.removeFromCart(productId, qty) |
A quantity of a product is removed from the cart. |
GronaEvent.beginCheckout(totalMinor) |
The shopper starts checkout. |
GronaEvent.purchase(orderId, totalMinor, productIds, treatments) |
Your order backend has confirmed an order. |
Grona.track is safe from any thread.
-
Send
viewItemfrom your product screen:import ai.grona.sdk.Gronaimport ai.grona.sdk.GronaEventGrona.track(GronaEvent.viewItem("sku_10432", 349)) -
Send
addToCartandremoveFromCartfrom your cart store’s change listener, once per product whose quantity moved. That covers changes from Grona actions and from your own screens alike.fun onCartChanged(before: AcmeCart, after: AcmeCart) {val ids = (before.lines.map { it.productId } + after.lines.map { it.productId }).toSet()for (id in ids) {val delta = after.qty(id) - before.qty(id)when {delta > 0 -> Grona.track(GronaEvent.addToCart(id, delta, after.unitPriceMinor(id)))delta < 0 -> Grona.track(GronaEvent.removeFromCart(id, -delta))}}} -
Send
beginCheckoutwhen checkout opens:Grona.track(GronaEvent.beginCheckout(cart.totalMinor)) // 897 is 8.97 -
Send
purchaseafter your order backend answers. Pass every product id in the order, and only the treatments the backend applied:Grona.track(GronaEvent.purchase(orderId = order.id,totalMinor = order.totalMinor,productIds = order.lines.map { it.productId },treatments = appliedTreatments, // from Grona.activeTreatments(), filtered to what the backend applied),)
For how to collect the treatments at checkout, see Offers and grants.
What leaves the device
Section titled “What leaves the device”The SDK minimises what it sends. You pass full data and it strips what Grona does not need.
- Session products. A session product is one that a Grona campaign showed or added in this session.
viewItem,addToCartandremoveFromCartare always counted, but they carry the product id and price only for session products. For any other product those fields are left out. - Purchases.
purchasekeeps the order id, the total, the currency of your latest basket snapshot, the treatments and only the session products in the order. The full basket never leaves the device. - Exception: keyed placements. On keyed placements such as
cart_line, campaign events carry the line’s product id as theirkey, in every arm. So while acart_linecampaign is live, the product ids of the cart lines bound to it leave the device. - Never sent. Search text, names, phone numbers, emails and browsing history. Pass only an opaque customer id to
identify.
Events Grona logs itself
Section titled “Events Grona logs itself”Do not send these. The SDK logs them for every placement it serves.
| Event | When |
|---|---|
eligible |
A decision is computed for a placement, once per visit, for every arm |
anchor_visible |
The slot or anchor’s top edge has been on screen for one second, for every arm |
served |
A treatment first reaches its slot or listener |
exposure |
Half the content has been visible for one second (diagnostic) |
action |
An add, add-all, replace or navigate from a tap or your call on a decision |
dismiss |
A dismiss |
For how these are analysed, see Events and exposure.
Delivery
Section titled “Delivery”Events are held or sent according to the shopper’s consent. Once consent is granted:
- The SDK sends events while the app is in the foreground every 30 seconds, once 20 are queued, and when the app goes to the background.
- A batch holds at most 50 events and is gzipped and sent over https.
- The queue on disk holds at most 1,000 events or 7 days of events. The oldest go first.
- A failed batch is retried at most 3 times with backoff.
Without an eventsUrl in your options, the SDK sends no events and keeps no event queue. Debuggable builds keep the last 200 events in memory for the debug view.
Next steps
Section titled “Next steps”- Set consent.
- Test and debug your events.