@bigcrunch/react-native-ads 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchAds.kt +434 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchBannerView.kt +484 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchInterstitial.kt +403 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchRewarded.kt +409 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/adapters/GoogleAdsAdapter.kt +592 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/AdOrchestrator.kt +623 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/AnalyticsClient.kt +719 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/BidRequestClient.kt +364 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/ConfigManager.kt +301 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/DeviceContext.kt +385 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/RewardedCallback.kt +42 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/SessionManager.kt +330 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/DeviceHelper.kt +60 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/HttpClient.kt +114 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Logger.kt +71 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/PrivacyStore.kt +125 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Storage.kt +88 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/BannerAdListener.kt +55 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/InterstitialAdListener.kt +55 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/RewardedAdListener.kt +58 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/AdEvent.kt +880 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/AppConfig.kt +90 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/DeviceData.kt +18 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/PlacementConfig.kt +70 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/SessionInfo.kt +21 -0
- package/android/build.gradle +22 -10
- package/android/settings.gradle +2 -6
- package/ios/BigCrunchAds/Sources/Adapters/GoogleAdsAdapter.swift +512 -0
- package/ios/BigCrunchAds/Sources/BigCrunchAds.swift +387 -0
- package/ios/BigCrunchAds/Sources/BigCrunchBannerView.swift +448 -0
- package/ios/BigCrunchAds/Sources/BigCrunchInterstitial.swift +412 -0
- package/ios/BigCrunchAds/Sources/BigCrunchRewarded.swift +523 -0
- package/ios/BigCrunchAds/Sources/Core/AdOrchestrator.swift +514 -0
- package/ios/BigCrunchAds/Sources/Core/AnalyticsClient.swift +874 -0
- package/ios/BigCrunchAds/Sources/Core/BidRequestClient.swift +344 -0
- package/ios/BigCrunchAds/Sources/Core/ConfigManager.swift +306 -0
- package/ios/BigCrunchAds/Sources/Core/DeviceContext.swift +284 -0
- package/ios/BigCrunchAds/Sources/Core/SessionManager.swift +392 -0
- package/ios/BigCrunchAds/Sources/Internal/HTTPClient.swift +146 -0
- package/ios/BigCrunchAds/Sources/Internal/Logger.swift +62 -0
- package/ios/BigCrunchAds/Sources/Internal/PrivacyStore.swift +129 -0
- package/ios/BigCrunchAds/Sources/Internal/Storage.swift +73 -0
- package/ios/BigCrunchAds/Sources/Models/AdEvent.swift +784 -0
- package/ios/BigCrunchAds/Sources/Models/AppConfig.swift +100 -0
- package/ios/BigCrunchAds/Sources/Models/DeviceData.swift +68 -0
- package/ios/BigCrunchAds/Sources/Models/PlacementConfig.swift +137 -0
- package/ios/BigCrunchAds/Sources/Models/SessionInfo.swift +48 -0
- package/ios/BigCrunchAdsModule.swift +0 -1
- package/ios/BigCrunchBannerViewManager.swift +0 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -2
- package/package.json +8 -2
- package/react-native-bigcrunch-ads.podspec +0 -1
- package/scripts/inject-version.js +55 -0
- package/src/index.ts +3 -2
|
@@ -0,0 +1,880 @@
|
|
|
1
|
+
package com.bigcrunch.ads.models
|
|
2
|
+
|
|
3
|
+
import com.bigcrunch.ads.core.DeviceContextData
|
|
4
|
+
import com.squareup.moshi.Json
|
|
5
|
+
import com.squareup.moshi.JsonClass
|
|
6
|
+
import java.util.UUID
|
|
7
|
+
|
|
8
|
+
// MARK: - Legacy Event (keeping for backward compatibility)
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Analytics event sent to BigCrunch backend
|
|
12
|
+
*
|
|
13
|
+
* All ad-related events (impressions, clicks, revenue) are tracked and sent
|
|
14
|
+
* to the analytics endpoint in this format.
|
|
15
|
+
*/
|
|
16
|
+
@JsonClass(generateAdapter = true)
|
|
17
|
+
internal data class AdEvent(
|
|
18
|
+
@Json(name = "eventType")
|
|
19
|
+
val eventType: String, // "screen_view", "ad_request", "ad_impression", "ad_revenue", "ad_click", "ad_viewable"
|
|
20
|
+
|
|
21
|
+
@Json(name = "placementId")
|
|
22
|
+
val placementId: String? = null,
|
|
23
|
+
|
|
24
|
+
@Json(name = "format")
|
|
25
|
+
val format: String? = null, // "banner", "interstitial", "rewarded"
|
|
26
|
+
|
|
27
|
+
@Json(name = "timestamp")
|
|
28
|
+
val timestamp: Long = System.currentTimeMillis(),
|
|
29
|
+
|
|
30
|
+
@Json(name = "sessionId")
|
|
31
|
+
val sessionId: String,
|
|
32
|
+
|
|
33
|
+
@Json(name = "deviceInfo")
|
|
34
|
+
val deviceInfo: DeviceInfo,
|
|
35
|
+
|
|
36
|
+
@Json(name = "revenue")
|
|
37
|
+
val revenue: RevenueData? = null
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Device and app information included with every event
|
|
42
|
+
*/
|
|
43
|
+
@JsonClass(generateAdapter = true)
|
|
44
|
+
internal data class DeviceInfo(
|
|
45
|
+
@Json(name = "platform")
|
|
46
|
+
val platform: String = "android",
|
|
47
|
+
|
|
48
|
+
@Json(name = "osVersion")
|
|
49
|
+
val osVersion: String,
|
|
50
|
+
|
|
51
|
+
@Json(name = "appVersion")
|
|
52
|
+
val appVersion: String,
|
|
53
|
+
|
|
54
|
+
@Json(name = "deviceId")
|
|
55
|
+
val deviceId: String
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Revenue data from ILRD (Impression-Level Revenue Data)
|
|
60
|
+
*
|
|
61
|
+
* Only present in ad_revenue events. Values are in micros (1/1,000,000 of currency unit).
|
|
62
|
+
*/
|
|
63
|
+
@JsonClass(generateAdapter = true)
|
|
64
|
+
internal data class RevenueData(
|
|
65
|
+
@Json(name = "valueMicros")
|
|
66
|
+
val valueMicros: Long,
|
|
67
|
+
|
|
68
|
+
@Json(name = "currency")
|
|
69
|
+
val currency: String
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
// MARK: - Enhanced Analytics Events (matching web SDK data model)
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Screen/Page view event - matches `/pageviews` endpoint
|
|
76
|
+
*
|
|
77
|
+
* Sent when a new screen is viewed. Contains session context and device info.
|
|
78
|
+
*/
|
|
79
|
+
@JsonClass(generateAdapter = true)
|
|
80
|
+
internal data class PageViewEvent(
|
|
81
|
+
// Web schema common fields
|
|
82
|
+
@Json(name = "payload_version")
|
|
83
|
+
val payloadVersion: String,
|
|
84
|
+
|
|
85
|
+
@Json(name = "config_version")
|
|
86
|
+
val configVersion: Int = 1,
|
|
87
|
+
|
|
88
|
+
@Json(name = "browser_timestamp")
|
|
89
|
+
val browserTimestamp: String, // ISO 8601
|
|
90
|
+
|
|
91
|
+
// Session/user context
|
|
92
|
+
@Json(name = "session_id")
|
|
93
|
+
val sessionId: String,
|
|
94
|
+
|
|
95
|
+
@Json(name = "user_id")
|
|
96
|
+
val userId: String,
|
|
97
|
+
|
|
98
|
+
@Json(name = "property_id")
|
|
99
|
+
val propertyId: String,
|
|
100
|
+
|
|
101
|
+
@Json(name = "new_user")
|
|
102
|
+
val newUser: Boolean,
|
|
103
|
+
|
|
104
|
+
// Page context
|
|
105
|
+
@Json(name = "page_id")
|
|
106
|
+
val pageId: String,
|
|
107
|
+
|
|
108
|
+
@Json(name = "session_depth")
|
|
109
|
+
val sessionDepth: Int,
|
|
110
|
+
|
|
111
|
+
@Json(name = "page_url")
|
|
112
|
+
val pageUrl: String,
|
|
113
|
+
|
|
114
|
+
@Json(name = "page_search")
|
|
115
|
+
val pageSearch: String = "",
|
|
116
|
+
|
|
117
|
+
@Json(name = "page_referrer")
|
|
118
|
+
val pageReferrer: String = "",
|
|
119
|
+
|
|
120
|
+
// Device context (flattened)
|
|
121
|
+
@Json(name = "browser")
|
|
122
|
+
val browser: String,
|
|
123
|
+
|
|
124
|
+
@Json(name = "device")
|
|
125
|
+
val device: String,
|
|
126
|
+
|
|
127
|
+
@Json(name = "os")
|
|
128
|
+
val os: String,
|
|
129
|
+
|
|
130
|
+
@Json(name = "country")
|
|
131
|
+
val country: String,
|
|
132
|
+
|
|
133
|
+
@Json(name = "region")
|
|
134
|
+
val region: String,
|
|
135
|
+
|
|
136
|
+
// Attribution
|
|
137
|
+
@Json(name = "session_source")
|
|
138
|
+
val sessionSource: String,
|
|
139
|
+
|
|
140
|
+
@Json(name = "session_medium")
|
|
141
|
+
val sessionMedium: String,
|
|
142
|
+
|
|
143
|
+
@Json(name = "utm_source")
|
|
144
|
+
val utmSource: String = "",
|
|
145
|
+
|
|
146
|
+
@Json(name = "utm_medium")
|
|
147
|
+
val utmMedium: String = "",
|
|
148
|
+
|
|
149
|
+
@Json(name = "utm_campaign")
|
|
150
|
+
val utmCampaign: String = "",
|
|
151
|
+
|
|
152
|
+
@Json(name = "utm_term")
|
|
153
|
+
val utmTerm: String = "",
|
|
154
|
+
|
|
155
|
+
@Json(name = "utm_content")
|
|
156
|
+
val utmContent: String = "",
|
|
157
|
+
|
|
158
|
+
// Click IDs for attribution
|
|
159
|
+
@Json(name = "gclid")
|
|
160
|
+
val gclid: String = "",
|
|
161
|
+
|
|
162
|
+
@Json(name = "fbclid")
|
|
163
|
+
val fbclid: String = "",
|
|
164
|
+
|
|
165
|
+
// Account & Identity
|
|
166
|
+
@Json(name = "acct_type")
|
|
167
|
+
val acctType: String = "anonymous",
|
|
168
|
+
|
|
169
|
+
@Json(name = "dii_source")
|
|
170
|
+
val diiSource: String = "",
|
|
171
|
+
|
|
172
|
+
// Ad platform IDs
|
|
173
|
+
@Json(name = "gam_network_code")
|
|
174
|
+
val gamNetworkCode: String = "",
|
|
175
|
+
|
|
176
|
+
@Json(name = "amzn_pub_id")
|
|
177
|
+
val amznPubId: String = "",
|
|
178
|
+
|
|
179
|
+
// Custom dimensions
|
|
180
|
+
@Json(name = "custom_dimensions")
|
|
181
|
+
val customDimensions: Map<String, String> = emptyMap()
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Individual impression record - nested inside ImpressionBatchEvent
|
|
186
|
+
*
|
|
187
|
+
* Represents a single ad impression with auction/bid data.
|
|
188
|
+
* All string fields default to empty string to ensure they're serialized (server requires all fields).
|
|
189
|
+
*/
|
|
190
|
+
@JsonClass(generateAdapter = true)
|
|
191
|
+
internal data class ImpressionRecord(
|
|
192
|
+
/** Placement identifier (slot_id in web SDK) */
|
|
193
|
+
@Json(name = "slot_id")
|
|
194
|
+
val slotId: String,
|
|
195
|
+
|
|
196
|
+
/** GAM ad unit path */
|
|
197
|
+
@Json(name = "gam_unit")
|
|
198
|
+
val gamUnit: String,
|
|
199
|
+
|
|
200
|
+
/** GAM price bucket */
|
|
201
|
+
@Json(name = "gam_price_bucket")
|
|
202
|
+
val gamPriceBucket: String = "",
|
|
203
|
+
|
|
204
|
+
/** Unique identifier for this impression */
|
|
205
|
+
@Json(name = "impression_id")
|
|
206
|
+
val impressionId: String,
|
|
207
|
+
|
|
208
|
+
/** Auction ID (from Prebid) */
|
|
209
|
+
@Json(name = "auction_id")
|
|
210
|
+
val auctionId: String = "",
|
|
211
|
+
|
|
212
|
+
/** Refresh count for this placement */
|
|
213
|
+
@Json(name = "refresh_count")
|
|
214
|
+
val refreshCount: Int = 0,
|
|
215
|
+
|
|
216
|
+
/** Winning bidder name */
|
|
217
|
+
@Json(name = "ad_bidder")
|
|
218
|
+
val adBidder: String = "",
|
|
219
|
+
|
|
220
|
+
/** Ad size (e.g., "320x50") */
|
|
221
|
+
@Json(name = "ad_size")
|
|
222
|
+
val adSize: String = "",
|
|
223
|
+
|
|
224
|
+
/** Bid price/revenue in CPM */
|
|
225
|
+
@Json(name = "ad_price")
|
|
226
|
+
val adPrice: Double = 0.0,
|
|
227
|
+
|
|
228
|
+
/** Floor price */
|
|
229
|
+
@Json(name = "ad_floor_price")
|
|
230
|
+
val adFloorPrice: Double = 0.0,
|
|
231
|
+
|
|
232
|
+
/** Minimum bid to win */
|
|
233
|
+
@Json(name = "min_bid_to_win")
|
|
234
|
+
val minBidToWin: Double = 0.0,
|
|
235
|
+
|
|
236
|
+
/** Advertiser ID from GAM */
|
|
237
|
+
@Json(name = "advertiser_id")
|
|
238
|
+
val advertiserId: String = "",
|
|
239
|
+
|
|
240
|
+
/** Campaign ID from GAM */
|
|
241
|
+
@Json(name = "campaign_id")
|
|
242
|
+
val campaignId: String = "",
|
|
243
|
+
|
|
244
|
+
/** Line item ID from GAM */
|
|
245
|
+
@Json(name = "line_item_id")
|
|
246
|
+
val lineItemId: String = "",
|
|
247
|
+
|
|
248
|
+
/** Creative ID from GAM response */
|
|
249
|
+
@Json(name = "creative_id")
|
|
250
|
+
val creativeId: String = "",
|
|
251
|
+
|
|
252
|
+
/** Amazon bid data (if applicable) */
|
|
253
|
+
@Json(name = "ad_amznbid")
|
|
254
|
+
val adAmznbid: String = "",
|
|
255
|
+
|
|
256
|
+
/** Amazon price data (if applicable) */
|
|
257
|
+
@Json(name = "ad_amznp")
|
|
258
|
+
val adAmznp: String = "",
|
|
259
|
+
|
|
260
|
+
/** Demand type (banner, video, etc.) */
|
|
261
|
+
@Json(name = "ad_demand_type")
|
|
262
|
+
val adDemandType: String = "",
|
|
263
|
+
|
|
264
|
+
/** Demand channel (e.g., "Prebid Header", "GAM Direct") */
|
|
265
|
+
@Json(name = "demand_channel")
|
|
266
|
+
val demandChannel: String = "",
|
|
267
|
+
|
|
268
|
+
/** Slot-level custom dimensions */
|
|
269
|
+
@Json(name = "custom_dimensions")
|
|
270
|
+
val customDimensions: Map<String, String> = emptyMap()
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Impression batch event - matches `/impressions` endpoint
|
|
275
|
+
*
|
|
276
|
+
* Contains session/page context with nested array of impression records.
|
|
277
|
+
* This matches the web SDK format where impressions are batched with pageview context.
|
|
278
|
+
*/
|
|
279
|
+
@JsonClass(generateAdapter = true)
|
|
280
|
+
internal data class ImpressionBatchEvent(
|
|
281
|
+
// Web schema common fields
|
|
282
|
+
@Json(name = "payload_version")
|
|
283
|
+
val payloadVersion: String,
|
|
284
|
+
|
|
285
|
+
@Json(name = "config_version")
|
|
286
|
+
val configVersion: Int = 1,
|
|
287
|
+
|
|
288
|
+
@Json(name = "browser_timestamp")
|
|
289
|
+
val browserTimestamp: String, // ISO 8601
|
|
290
|
+
|
|
291
|
+
// Session/user context
|
|
292
|
+
@Json(name = "session_id")
|
|
293
|
+
val sessionId: String,
|
|
294
|
+
|
|
295
|
+
@Json(name = "user_id")
|
|
296
|
+
val userId: String,
|
|
297
|
+
|
|
298
|
+
@Json(name = "property_id")
|
|
299
|
+
val propertyId: String,
|
|
300
|
+
|
|
301
|
+
@Json(name = "new_user")
|
|
302
|
+
val newUser: Boolean,
|
|
303
|
+
|
|
304
|
+
@Json(name = "page_id")
|
|
305
|
+
val pageId: String,
|
|
306
|
+
|
|
307
|
+
@Json(name = "session_depth")
|
|
308
|
+
val sessionDepth: Int,
|
|
309
|
+
|
|
310
|
+
@Json(name = "page_url")
|
|
311
|
+
val pageUrl: String = "",
|
|
312
|
+
|
|
313
|
+
@Json(name = "page_search")
|
|
314
|
+
val pageSearch: String = "",
|
|
315
|
+
|
|
316
|
+
@Json(name = "page_referrer")
|
|
317
|
+
val pageReferrer: String = "",
|
|
318
|
+
|
|
319
|
+
// Device context (flattened)
|
|
320
|
+
@Json(name = "browser")
|
|
321
|
+
val browser: String,
|
|
322
|
+
|
|
323
|
+
@Json(name = "device")
|
|
324
|
+
val device: String,
|
|
325
|
+
|
|
326
|
+
@Json(name = "os")
|
|
327
|
+
val os: String,
|
|
328
|
+
|
|
329
|
+
@Json(name = "country")
|
|
330
|
+
val country: String,
|
|
331
|
+
|
|
332
|
+
@Json(name = "region")
|
|
333
|
+
val region: String,
|
|
334
|
+
|
|
335
|
+
// Attribution
|
|
336
|
+
@Json(name = "session_source")
|
|
337
|
+
val sessionSource: String,
|
|
338
|
+
|
|
339
|
+
@Json(name = "session_medium")
|
|
340
|
+
val sessionMedium: String,
|
|
341
|
+
|
|
342
|
+
@Json(name = "utm_source")
|
|
343
|
+
val utmSource: String = "",
|
|
344
|
+
|
|
345
|
+
@Json(name = "utm_medium")
|
|
346
|
+
val utmMedium: String = "",
|
|
347
|
+
|
|
348
|
+
@Json(name = "utm_campaign")
|
|
349
|
+
val utmCampaign: String = "",
|
|
350
|
+
|
|
351
|
+
@Json(name = "utm_term")
|
|
352
|
+
val utmTerm: String = "",
|
|
353
|
+
|
|
354
|
+
@Json(name = "utm_content")
|
|
355
|
+
val utmContent: String = "",
|
|
356
|
+
|
|
357
|
+
// Click IDs for attribution
|
|
358
|
+
@Json(name = "gclid")
|
|
359
|
+
val gclid: String = "",
|
|
360
|
+
|
|
361
|
+
@Json(name = "fbclid")
|
|
362
|
+
val fbclid: String = "",
|
|
363
|
+
|
|
364
|
+
// Account & Identity
|
|
365
|
+
@Json(name = "acct_type")
|
|
366
|
+
val acctType: String = "anonymous",
|
|
367
|
+
|
|
368
|
+
@Json(name = "dii_source")
|
|
369
|
+
val diiSource: String = "",
|
|
370
|
+
|
|
371
|
+
// Ad platform IDs
|
|
372
|
+
@Json(name = "gam_network_code")
|
|
373
|
+
val gamNetworkCode: String = "",
|
|
374
|
+
|
|
375
|
+
@Json(name = "amzn_pub_id")
|
|
376
|
+
val amznPubId: String = "",
|
|
377
|
+
|
|
378
|
+
// Custom dimensions
|
|
379
|
+
@Json(name = "custom_dimensions")
|
|
380
|
+
val customDimensions: Map<String, String> = emptyMap(),
|
|
381
|
+
|
|
382
|
+
// Nested impressions array
|
|
383
|
+
@Json(name = "impressions")
|
|
384
|
+
val impressions: List<ImpressionRecord>
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Ad click event - matches `/clicks` endpoint
|
|
389
|
+
*
|
|
390
|
+
* Sent when a user clicks on an ad.
|
|
391
|
+
*/
|
|
392
|
+
@JsonClass(generateAdapter = true)
|
|
393
|
+
internal data class ClickEvent(
|
|
394
|
+
// Web schema common fields
|
|
395
|
+
@Json(name = "payload_version")
|
|
396
|
+
val payloadVersion: String,
|
|
397
|
+
|
|
398
|
+
@Json(name = "config_version")
|
|
399
|
+
val configVersion: Int = 1,
|
|
400
|
+
|
|
401
|
+
@Json(name = "browser_timestamp")
|
|
402
|
+
val browserTimestamp: String, // ISO 8601
|
|
403
|
+
|
|
404
|
+
// Session/user context
|
|
405
|
+
@Json(name = "session_id")
|
|
406
|
+
val sessionId: String,
|
|
407
|
+
|
|
408
|
+
@Json(name = "user_id")
|
|
409
|
+
val userId: String,
|
|
410
|
+
|
|
411
|
+
@Json(name = "property_id")
|
|
412
|
+
val propertyId: String,
|
|
413
|
+
|
|
414
|
+
@Json(name = "new_user")
|
|
415
|
+
val newUser: Boolean,
|
|
416
|
+
|
|
417
|
+
@Json(name = "page_id")
|
|
418
|
+
val pageId: String,
|
|
419
|
+
|
|
420
|
+
@Json(name = "session_depth")
|
|
421
|
+
val sessionDepth: Int,
|
|
422
|
+
|
|
423
|
+
@Json(name = "page_url")
|
|
424
|
+
val pageUrl: String = "",
|
|
425
|
+
|
|
426
|
+
@Json(name = "page_search")
|
|
427
|
+
val pageSearch: String = "",
|
|
428
|
+
|
|
429
|
+
@Json(name = "page_referrer")
|
|
430
|
+
val pageReferrer: String = "",
|
|
431
|
+
|
|
432
|
+
// Device context (flattened)
|
|
433
|
+
@Json(name = "browser")
|
|
434
|
+
val browser: String,
|
|
435
|
+
|
|
436
|
+
@Json(name = "device")
|
|
437
|
+
val device: String,
|
|
438
|
+
|
|
439
|
+
@Json(name = "os")
|
|
440
|
+
val os: String,
|
|
441
|
+
|
|
442
|
+
@Json(name = "country")
|
|
443
|
+
val country: String,
|
|
444
|
+
|
|
445
|
+
@Json(name = "region")
|
|
446
|
+
val region: String,
|
|
447
|
+
|
|
448
|
+
// Attribution
|
|
449
|
+
@Json(name = "session_source")
|
|
450
|
+
val sessionSource: String,
|
|
451
|
+
|
|
452
|
+
@Json(name = "session_medium")
|
|
453
|
+
val sessionMedium: String,
|
|
454
|
+
|
|
455
|
+
@Json(name = "utm_source")
|
|
456
|
+
val utmSource: String = "",
|
|
457
|
+
|
|
458
|
+
@Json(name = "utm_medium")
|
|
459
|
+
val utmMedium: String = "",
|
|
460
|
+
|
|
461
|
+
@Json(name = "utm_campaign")
|
|
462
|
+
val utmCampaign: String = "",
|
|
463
|
+
|
|
464
|
+
@Json(name = "utm_term")
|
|
465
|
+
val utmTerm: String = "",
|
|
466
|
+
|
|
467
|
+
@Json(name = "utm_content")
|
|
468
|
+
val utmContent: String = "",
|
|
469
|
+
|
|
470
|
+
// Click IDs for attribution
|
|
471
|
+
@Json(name = "gclid")
|
|
472
|
+
val gclid: String = "",
|
|
473
|
+
|
|
474
|
+
@Json(name = "fbclid")
|
|
475
|
+
val fbclid: String = "",
|
|
476
|
+
|
|
477
|
+
// Account & Identity
|
|
478
|
+
@Json(name = "acct_type")
|
|
479
|
+
val acctType: String = "anonymous",
|
|
480
|
+
|
|
481
|
+
@Json(name = "dii_source")
|
|
482
|
+
val diiSource: String = "",
|
|
483
|
+
|
|
484
|
+
// Ad platform IDs
|
|
485
|
+
@Json(name = "gam_network_code")
|
|
486
|
+
val gamNetworkCode: String = "",
|
|
487
|
+
|
|
488
|
+
@Json(name = "amzn_pub_id")
|
|
489
|
+
val amznPubId: String = "",
|
|
490
|
+
|
|
491
|
+
// Custom dimensions
|
|
492
|
+
@Json(name = "custom_dimensions")
|
|
493
|
+
val customDimensions: Map<String, String> = emptyMap(),
|
|
494
|
+
|
|
495
|
+
// Click-specific fields (nested click object per schema)
|
|
496
|
+
@Json(name = "click")
|
|
497
|
+
val click: ClickData
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Click data object nested inside ClickEvent
|
|
502
|
+
*/
|
|
503
|
+
@JsonClass(generateAdapter = true)
|
|
504
|
+
internal data class ClickData(
|
|
505
|
+
@Json(name = "click_id")
|
|
506
|
+
val clickId: String,
|
|
507
|
+
|
|
508
|
+
@Json(name = "slot_id")
|
|
509
|
+
val slotId: String,
|
|
510
|
+
|
|
511
|
+
@Json(name = "impression_id")
|
|
512
|
+
val impressionId: String,
|
|
513
|
+
|
|
514
|
+
@Json(name = "refresh_count")
|
|
515
|
+
val refreshCount: Int = 0,
|
|
516
|
+
|
|
517
|
+
@Json(name = "ad_amznp")
|
|
518
|
+
val adAmznp: String = "",
|
|
519
|
+
|
|
520
|
+
@Json(name = "ad_bidder")
|
|
521
|
+
val adBidder: String = "",
|
|
522
|
+
|
|
523
|
+
@Json(name = "ad_size")
|
|
524
|
+
val adSize: String = "",
|
|
525
|
+
|
|
526
|
+
@Json(name = "advertiser_id")
|
|
527
|
+
val advertiserId: String = "",
|
|
528
|
+
|
|
529
|
+
@Json(name = "campaign_id")
|
|
530
|
+
val campaignId: String = "",
|
|
531
|
+
|
|
532
|
+
@Json(name = "line_item_id")
|
|
533
|
+
val lineItemId: String = "",
|
|
534
|
+
|
|
535
|
+
@Json(name = "creative_id")
|
|
536
|
+
val creativeId: String = "",
|
|
537
|
+
|
|
538
|
+
@Json(name = "ad_demand_type")
|
|
539
|
+
val adDemandType: String = "",
|
|
540
|
+
|
|
541
|
+
@Json(name = "demand_channel")
|
|
542
|
+
val demandChannel: String = "",
|
|
543
|
+
|
|
544
|
+
/** Custom dimensions - values must be string arrays per backend schema */
|
|
545
|
+
@Json(name = "custom_dimensions")
|
|
546
|
+
val customDimensions: Map<String, List<String>> = emptyMap()
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Viewability event - matches `/viewability` endpoint
|
|
551
|
+
*
|
|
552
|
+
* Sent when an ad meets viewability thresholds (e.g., 50% visible for 1 second).
|
|
553
|
+
*/
|
|
554
|
+
@JsonClass(generateAdapter = true)
|
|
555
|
+
internal data class ViewabilityEvent(
|
|
556
|
+
// Web schema common fields
|
|
557
|
+
@Json(name = "payload_version")
|
|
558
|
+
val payloadVersion: String,
|
|
559
|
+
|
|
560
|
+
@Json(name = "config_version")
|
|
561
|
+
val configVersion: Int = 1,
|
|
562
|
+
|
|
563
|
+
@Json(name = "browser_timestamp")
|
|
564
|
+
val browserTimestamp: String, // ISO 8601
|
|
565
|
+
|
|
566
|
+
// Session/user context
|
|
567
|
+
@Json(name = "session_id")
|
|
568
|
+
val sessionId: String,
|
|
569
|
+
|
|
570
|
+
@Json(name = "user_id")
|
|
571
|
+
val userId: String,
|
|
572
|
+
|
|
573
|
+
@Json(name = "property_id")
|
|
574
|
+
val propertyId: String,
|
|
575
|
+
|
|
576
|
+
@Json(name = "new_user")
|
|
577
|
+
val newUser: Boolean,
|
|
578
|
+
|
|
579
|
+
@Json(name = "page_id")
|
|
580
|
+
val pageId: String,
|
|
581
|
+
|
|
582
|
+
@Json(name = "session_depth")
|
|
583
|
+
val sessionDepth: Int,
|
|
584
|
+
|
|
585
|
+
@Json(name = "page_url")
|
|
586
|
+
val pageUrl: String = "",
|
|
587
|
+
|
|
588
|
+
@Json(name = "page_search")
|
|
589
|
+
val pageSearch: String = "",
|
|
590
|
+
|
|
591
|
+
@Json(name = "page_referrer")
|
|
592
|
+
val pageReferrer: String = "",
|
|
593
|
+
|
|
594
|
+
// Device context (flattened)
|
|
595
|
+
@Json(name = "browser")
|
|
596
|
+
val browser: String,
|
|
597
|
+
|
|
598
|
+
@Json(name = "device")
|
|
599
|
+
val device: String,
|
|
600
|
+
|
|
601
|
+
@Json(name = "os")
|
|
602
|
+
val os: String,
|
|
603
|
+
|
|
604
|
+
@Json(name = "country")
|
|
605
|
+
val country: String,
|
|
606
|
+
|
|
607
|
+
@Json(name = "region")
|
|
608
|
+
val region: String,
|
|
609
|
+
|
|
610
|
+
// Attribution
|
|
611
|
+
@Json(name = "session_source")
|
|
612
|
+
val sessionSource: String,
|
|
613
|
+
|
|
614
|
+
@Json(name = "session_medium")
|
|
615
|
+
val sessionMedium: String,
|
|
616
|
+
|
|
617
|
+
@Json(name = "utm_source")
|
|
618
|
+
val utmSource: String = "",
|
|
619
|
+
|
|
620
|
+
@Json(name = "utm_medium")
|
|
621
|
+
val utmMedium: String = "",
|
|
622
|
+
|
|
623
|
+
@Json(name = "utm_campaign")
|
|
624
|
+
val utmCampaign: String = "",
|
|
625
|
+
|
|
626
|
+
@Json(name = "utm_term")
|
|
627
|
+
val utmTerm: String = "",
|
|
628
|
+
|
|
629
|
+
@Json(name = "utm_content")
|
|
630
|
+
val utmContent: String = "",
|
|
631
|
+
|
|
632
|
+
// Click IDs for attribution
|
|
633
|
+
@Json(name = "gclid")
|
|
634
|
+
val gclid: String = "",
|
|
635
|
+
|
|
636
|
+
@Json(name = "fbclid")
|
|
637
|
+
val fbclid: String = "",
|
|
638
|
+
|
|
639
|
+
// Account & Identity
|
|
640
|
+
@Json(name = "acct_type")
|
|
641
|
+
val acctType: String = "anonymous",
|
|
642
|
+
|
|
643
|
+
@Json(name = "dii_source")
|
|
644
|
+
val diiSource: String = "",
|
|
645
|
+
|
|
646
|
+
// Ad platform IDs
|
|
647
|
+
@Json(name = "gam_network_code")
|
|
648
|
+
val gamNetworkCode: String = "",
|
|
649
|
+
|
|
650
|
+
@Json(name = "amzn_pub_id")
|
|
651
|
+
val amznPubId: String = "",
|
|
652
|
+
|
|
653
|
+
// Custom dimensions
|
|
654
|
+
@Json(name = "custom_dimensions")
|
|
655
|
+
val customDimensions: Map<String, String> = emptyMap(),
|
|
656
|
+
|
|
657
|
+
// Viewability-specific fields (nested array per schema)
|
|
658
|
+
@Json(name = "viewability")
|
|
659
|
+
val viewability: List<ViewabilityData>
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Viewability data object nested inside ViewabilityEvent
|
|
664
|
+
*/
|
|
665
|
+
@JsonClass(generateAdapter = true)
|
|
666
|
+
internal data class ViewabilityData(
|
|
667
|
+
@Json(name = "slot_id")
|
|
668
|
+
val slotId: String,
|
|
669
|
+
|
|
670
|
+
@Json(name = "impression_id")
|
|
671
|
+
val impressionId: String,
|
|
672
|
+
|
|
673
|
+
@Json(name = "refresh_count")
|
|
674
|
+
val refreshCount: Int = 0,
|
|
675
|
+
|
|
676
|
+
@Json(name = "ad_amznp")
|
|
677
|
+
val adAmznp: String = "",
|
|
678
|
+
|
|
679
|
+
@Json(name = "ad_bidder")
|
|
680
|
+
val adBidder: String = "",
|
|
681
|
+
|
|
682
|
+
@Json(name = "ad_size")
|
|
683
|
+
val adSize: String = "",
|
|
684
|
+
|
|
685
|
+
@Json(name = "advertiser_id")
|
|
686
|
+
val advertiserId: String = "",
|
|
687
|
+
|
|
688
|
+
@Json(name = "campaign_id")
|
|
689
|
+
val campaignId: String = "",
|
|
690
|
+
|
|
691
|
+
@Json(name = "line_item_id")
|
|
692
|
+
val lineItemId: String = "",
|
|
693
|
+
|
|
694
|
+
@Json(name = "creative_id")
|
|
695
|
+
val creativeId: String = "",
|
|
696
|
+
|
|
697
|
+
@Json(name = "ad_demand_type")
|
|
698
|
+
val adDemandType: String = "",
|
|
699
|
+
|
|
700
|
+
@Json(name = "demand_channel")
|
|
701
|
+
val demandChannel: String = "",
|
|
702
|
+
|
|
703
|
+
/** Custom dimensions - values must be string arrays per backend schema */
|
|
704
|
+
@Json(name = "custom_dimensions")
|
|
705
|
+
val customDimensions: Map<String, List<String>> = emptyMap()
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Engagement event - matches `/engagement` endpoint
|
|
710
|
+
*
|
|
711
|
+
* Tracks user engagement with content/screens.
|
|
712
|
+
*/
|
|
713
|
+
@JsonClass(generateAdapter = true)
|
|
714
|
+
internal data class EngagementEvent(
|
|
715
|
+
// Web schema common fields
|
|
716
|
+
@Json(name = "payload_version")
|
|
717
|
+
val payloadVersion: String,
|
|
718
|
+
|
|
719
|
+
@Json(name = "config_version")
|
|
720
|
+
val configVersion: Int = 1,
|
|
721
|
+
|
|
722
|
+
@Json(name = "browser_timestamp")
|
|
723
|
+
val browserTimestamp: String, // ISO 8601
|
|
724
|
+
|
|
725
|
+
// Session/user context
|
|
726
|
+
@Json(name = "session_id")
|
|
727
|
+
val sessionId: String,
|
|
728
|
+
|
|
729
|
+
@Json(name = "user_id")
|
|
730
|
+
val userId: String,
|
|
731
|
+
|
|
732
|
+
@Json(name = "property_id")
|
|
733
|
+
val propertyId: String,
|
|
734
|
+
|
|
735
|
+
@Json(name = "new_user")
|
|
736
|
+
val newUser: Boolean,
|
|
737
|
+
|
|
738
|
+
@Json(name = "page_id")
|
|
739
|
+
val pageId: String,
|
|
740
|
+
|
|
741
|
+
@Json(name = "session_depth")
|
|
742
|
+
val sessionDepth: Int,
|
|
743
|
+
|
|
744
|
+
@Json(name = "page_url")
|
|
745
|
+
val pageUrl: String = "",
|
|
746
|
+
|
|
747
|
+
@Json(name = "page_search")
|
|
748
|
+
val pageSearch: String = "",
|
|
749
|
+
|
|
750
|
+
@Json(name = "page_referrer")
|
|
751
|
+
val pageReferrer: String = "",
|
|
752
|
+
|
|
753
|
+
// Device context (flattened)
|
|
754
|
+
@Json(name = "browser")
|
|
755
|
+
val browser: String,
|
|
756
|
+
|
|
757
|
+
@Json(name = "device")
|
|
758
|
+
val device: String,
|
|
759
|
+
|
|
760
|
+
@Json(name = "os")
|
|
761
|
+
val os: String,
|
|
762
|
+
|
|
763
|
+
@Json(name = "country")
|
|
764
|
+
val country: String,
|
|
765
|
+
|
|
766
|
+
@Json(name = "region")
|
|
767
|
+
val region: String,
|
|
768
|
+
|
|
769
|
+
// Attribution
|
|
770
|
+
@Json(name = "session_source")
|
|
771
|
+
val sessionSource: String,
|
|
772
|
+
|
|
773
|
+
@Json(name = "session_medium")
|
|
774
|
+
val sessionMedium: String,
|
|
775
|
+
|
|
776
|
+
@Json(name = "utm_source")
|
|
777
|
+
val utmSource: String = "",
|
|
778
|
+
|
|
779
|
+
@Json(name = "utm_medium")
|
|
780
|
+
val utmMedium: String = "",
|
|
781
|
+
|
|
782
|
+
@Json(name = "utm_campaign")
|
|
783
|
+
val utmCampaign: String = "",
|
|
784
|
+
|
|
785
|
+
@Json(name = "utm_term")
|
|
786
|
+
val utmTerm: String = "",
|
|
787
|
+
|
|
788
|
+
@Json(name = "utm_content")
|
|
789
|
+
val utmContent: String = "",
|
|
790
|
+
|
|
791
|
+
// Click IDs for attribution
|
|
792
|
+
@Json(name = "gclid")
|
|
793
|
+
val gclid: String = "",
|
|
794
|
+
|
|
795
|
+
@Json(name = "fbclid")
|
|
796
|
+
val fbclid: String = "",
|
|
797
|
+
|
|
798
|
+
// Account & Identity
|
|
799
|
+
@Json(name = "acct_type")
|
|
800
|
+
val acctType: String = "anonymous",
|
|
801
|
+
|
|
802
|
+
@Json(name = "dii_source")
|
|
803
|
+
val diiSource: String = "",
|
|
804
|
+
|
|
805
|
+
// Ad platform IDs
|
|
806
|
+
@Json(name = "gam_network_code")
|
|
807
|
+
val gamNetworkCode: String = "",
|
|
808
|
+
|
|
809
|
+
@Json(name = "amzn_pub_id")
|
|
810
|
+
val amznPubId: String = "",
|
|
811
|
+
|
|
812
|
+
/** Custom dimensions - values must be string arrays per backend schema */
|
|
813
|
+
@Json(name = "custom_dimensions")
|
|
814
|
+
val customDimensions: Map<String, List<String>> = emptyMap(),
|
|
815
|
+
|
|
816
|
+
// Engagement-specific fields
|
|
817
|
+
/** Time actively engaged in seconds */
|
|
818
|
+
@Json(name = "engaged_time")
|
|
819
|
+
val engagedTime: Int,
|
|
820
|
+
|
|
821
|
+
/** Total time on page/screen in seconds */
|
|
822
|
+
@Json(name = "time_on_page")
|
|
823
|
+
val timeOnPage: Int,
|
|
824
|
+
|
|
825
|
+
/** Maximum scroll depth percentage (0-100) */
|
|
826
|
+
@Json(name = "scroll_depth")
|
|
827
|
+
val scrollDepth: Int = 0
|
|
828
|
+
)
|
|
829
|
+
|
|
830
|
+
// MARK: - Auction Data
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Auction data from Prebid response
|
|
834
|
+
*
|
|
835
|
+
* Captures bidding information for analytics.
|
|
836
|
+
*/
|
|
837
|
+
internal data class AuctionData(
|
|
838
|
+
/** Prebid auction ID */
|
|
839
|
+
val auctionId: String? = null,
|
|
840
|
+
|
|
841
|
+
/** Winning bidder name */
|
|
842
|
+
val bidder: String? = null,
|
|
843
|
+
|
|
844
|
+
/** Winning bid price in CPM */
|
|
845
|
+
val bidPriceCpm: Double? = null,
|
|
846
|
+
|
|
847
|
+
/** Creative ID from winning bid */
|
|
848
|
+
val creativeId: String? = null
|
|
849
|
+
) {
|
|
850
|
+
companion object {
|
|
851
|
+
val EMPTY = AuctionData()
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// MARK: - Impression Context
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Context for tracking an ad impression
|
|
859
|
+
*
|
|
860
|
+
* Aggregates all data needed to track an impression through its lifecycle.
|
|
861
|
+
*/
|
|
862
|
+
internal data class ImpressionContext(
|
|
863
|
+
/** Unique impression identifier */
|
|
864
|
+
val impressionId: String = UUID.randomUUID().toString(),
|
|
865
|
+
|
|
866
|
+
/** Placement configuration */
|
|
867
|
+
val placementId: String,
|
|
868
|
+
val gamAdUnit: String,
|
|
869
|
+
val format: String,
|
|
870
|
+
|
|
871
|
+
/** Size (for banners) */
|
|
872
|
+
val width: Int? = null,
|
|
873
|
+
val height: Int? = null,
|
|
874
|
+
|
|
875
|
+
/** Auction data (populated after Prebid response) */
|
|
876
|
+
var auctionData: AuctionData = AuctionData.EMPTY,
|
|
877
|
+
|
|
878
|
+
/** Timestamp when impression was created */
|
|
879
|
+
val createdAt: Long = System.currentTimeMillis()
|
|
880
|
+
)
|