RT-1064: Implement tracking metrics for personalizations#24
Conversation
| options?: AddRecordOptions | ||
| ) => { | ||
| return this._sdk.addRecord(table, record, success, error) | ||
| return this._sdk.addRecord(table, record, success, error, options) |
There was a problem hiding this comment.
Hm, this means that customers can choose a different db for emitting events. Let's see what Integrations says.
| expect(spy).not.toHaveBeenCalled() | ||
| }) | ||
|
|
||
| it('does not report an unattributable spot even when it injects', () => { |
There was a problem hiding this comment.
Is this unattributable because it's missing campaign and creative ids? IMO, we should still emit these because:
- they reflect a bug in campaign launch logic.
- neither us nor customers will have visibility into unattributable offers
- if a user sees a personalization, it is an impression irrespective of whether it's attributable to a campaign or creative.
There was a problem hiding this comment.
If we don't have the IDs... we can't link the data to any campaign or creatives.
This is mostly to protect against the fact we don't encode this for existing campaigns yet.
| it('leaves impression null when the offer has no campaign', () => { | ||
| const payload: PersonalizationPayload = { | ||
| offers: { | ||
| w: { | ||
| attributes: { | ||
| 'td_personalization.audience_rank': '1', | ||
| 'td_personalization.content': p13n([ | ||
| { | ||
| id: 'cr-1', | ||
| css_selector: '#ok', | ||
| html_value: '<p>x</p>', | ||
| css_value: '', | ||
| }, | ||
| ]), | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
| expect(decodeOffers(payload, 1000)[0]?.impression).toBeNull() | ||
| }) | ||
|
|
||
| it('leaves impression null when the entry has no id', () => { | ||
| const payload: PersonalizationPayload = { | ||
| offers: { | ||
| w: { |
There was a problem hiding this comment.
I understand the reasoning behind nulling offers without creative or campaign id. But I wonder what would lead to this. If there is a bug in our logic that results in empty creative or campaign id, would we want to lose the metrics emitted while we fix and deploy the bug?
There was a problem hiding this comment.
Backwards compatibility, for the most part.
Assisted-by: Claude Opus 4.8
This is done by installing a handler on the shadow roots we installed, and tagging them with data attributes to record their campaign and creative IDs. Assisted-by: Claude Opus 4.8
243508d to
136b49b
Compare
|
|
||
| export interface AddRecordOptions { | ||
| /** Defaults to the SDK's configured database when omitted. */ | ||
| database?: string |
There was a problem hiding this comment.
Is it a requirement to have another database configured besides the one that is in the default config? Can we just use the one in the default config?
There was a problem hiding this comment.
Yes, it is. We are looking to store all metrics in a known database to simplify report generation by Personalization Studio and AI Studio in the future.
|
|
||
| const PERSONALIZATION_DATABASE = 'td_c360_personalization' | ||
| const PERSONALIZATION_TABLE = 'events' | ||
| const CLICKABLE_SELECTOR = 'a, button, [role="button"], [role="link"]' |
There was a problem hiding this comment.
nit: ideally the clickable selector should be something like td-personalization-clickable but it's fine for now since you're scope the trackClicks event listener to the spot.
There was a problem hiding this comment.
We can do that once the editor can generate those 😆
Summary
After applying personalizations on to a page, we will send events to record their application as impressions and record all clicks within the replaced elements.
Details
All events are recorded into
td_c360_personalization.events. We are hardcoding the database to simplify querying in the console in the future.On application, we are now:
impression.data-td-personalization-{campaign,creative}to the host element.All records to the events table contains:
impressionorclick.