SRGSSR / pillarbox-apple

A next-generation reactive media playback ecosystem for Apple platforms.
https://testflight.apple.com/join/TS6ngLqf
MIT License
51 stars 7 forks source link

Override cookie_id on media_events #945

Closed rabufeti closed 1 month ago

rabufeti commented 1 month ago

Can your answer be found elsewhere?

Detailed question

Hello there, we received an alert from the UDP (SRF) team about an issue related to the media_events and our native events.

Here is a quote of the received message:

Becker, Gosia (SRF) 11:22 Hello Guys, we noticed, that we receive different cookie_id from native events and TC events. In TC, the sdk_id or TcId are used as an unique user identifier. They do not match the cookie_id we receive with page_views and other ui_events. I cannot find any value in media_events in TC, which matches our cookie_id from page_views and other native events. It is problematic, because we cannot build a correct session without matching IDs.

In each event (page_view and ui_event) we include a "cookie_id" parameter in order to track the user sessions. The problem is that obviosly this ID is different from the one generated by Pillarbox.

Our question is: There is a way to override the ID sent by the player with the one generated by the app? Please note that the issue is present also on the Android version.

defagos commented 1 month ago

Hi @rabufeti ,

Looking at your source code I see that you are supplying as cookie_id to UDP the value returned by TCPredefinedVariables.sharedInstance().uniqueIdentifier(). This unique identifier generated by Commanders Act is sent in all Commanders Act events under user.consistent_anonymous_id, both in page views as well as media events JSON payloads.

Note that Pillarbox itself does not provide this label under a cookie_id key, since this key is not part of the official SRG specification. You can use an AnalyticsDataSource to attach custom labels if needed (e.g. such a cookie_id field) but since this label is readily officially available from user.consistent_anonymous_id I am not sure it would make sense.

Hope this helps.

defagos commented 1 month ago

I checked the behavior of the SRF News app on develop and I can confirm that the cookie_id sent to UDP matches the value found in Commanders Act user.consistent_anonymous_id event payloads, including of course media events. So you should be able to match events received by UDP with those received by Commanders Act reliably.

I namely still had a doubt that, depending on when you were fetching the unique id from the Commanders Act API to pass to UDP (before or after our Pillarbox Analytics SDK initialization) you might get different values, but this is not the case. The value you get from TCPredefinedVariables.sharedInstance().uniqueIdentifier() is a constant that is not affected by our SDK startup phase in any way.

rabufeti commented 1 month ago

Hi @defagos thanks for the reply. The behavior is a little bit more complex, let me explain better.

In partnership with SUPSI and Claranet (an external company), we've developed a machine-learning environment that based on the user preferences can suggest the content to the apps.

This environment is feeded by the UDP database but since the tables are populated only ones per night, the events for page_view and ui_event are sent to UDP through a middleware that store the data on a local storage before forward it to the UDP endpoint. This was made for a real-time ad light analysis purpose. In a second instance, the ML made some queries on the UDP tables and refine the user profiling.

Now let me show you some example of code.

When the app starts, we instantiate a custom UDPTracker with some configurations and the cookied_id is generated directly by us using a simple UUID generator:

// UDP
var customInfo = [String: Any]()
customInfo["schema_version"] = "0.1.0"
customInfo["product"] = "app"
customInfo["backend_system"] = "news"
customInfo["business_unit"] = "rsi"

if let cookieId = UserDefaults.standard.object(forKey: "COOKIE_ID") as? String{
    customInfo["cookie_id"] = cookieId
}
else{
    let cookieId = UUID()
    UserDefaults.standard.set("\(cookieId)", forKey: "COOKIE_ID")
    customInfo["cookie_id"] = "\(cookieId)"
}

UDPTrackerService.shared.customInfo = customInfo

We handle three type of events to send to UDP and all of them are sent only inside the article details:

Now, in order to use the same cookie_id, we can get the UUID generated by the TC SDK and edit our code like this:

let cookieId = TCPredefinedVariables.sharedInstance().uniqueIdentifier()

My doubt is only what will happen when we will integrate also a user authentication. In that case I think we'll must use a UserID if we want maintain a consistent profiling in our ML environment. But maybe this is another issue :)

Anyway I'll discuss with @antoniodamico1 about integrating the TCPredefinedVariables in Android. Maybe could you send us also the counterpart for Android for getting the cookie_id?

defagos commented 1 month ago

If you need to have a UUID to identify a user (first locally, then possibly bound to some remote user account), you should avoid relying on Commanders Act variables IMHO. This is risky since this variable is outside your control and could possibly be changed / dropped at any time by Commanders Act.

Instead, just manage your own UUID, generated locally and possibly later reconciled with some remote user account. You can then pass this UUID to UDP, as well as to Commanders Act using AnalyticsDataSource custom global labels. This should be much safer.

The conversation we have in this issue should be applicable to Android. I'll mention @MGaetan89 and @StaehliJ here so that they can decide whether they prefer discussing the same matter on a dedicated Android issue.

rabufeti commented 1 month ago

Hi @defagos, yes I agree about passing a user id using a custom label. Anyway we can discuss about this in the future since at the moment we don't have a final version of the SRGLogin.

Discussing with @antoniodamico1 we realized that using the TC identifier may result in a loss of the past tracked data. We must wind a solution to match the old UUIDs with the new ones.

I'll discuss about this with the SRF team.

defagos commented 1 month ago

Seems reasonable. You probably need a way to reconcile data belong to several UUIDs anyway in the long term since, for products with an optional login, you might have to track data with a temporary UUID while the user is not connected, before being able to later associate this local UUID with a remote one that would be delivered with their user account.

These are interesting needs for which our friends at the EBU provided a standard, not sure whether our login provider will offer some similar feature, though.

If you need more information feel free to ask. If you have all you need, though, I'll let you close the issue. Thanks in advance.