0
# User Event Tracking
1
2
Collection and management of user interaction events that power recommendation algorithms and analytics. The User Event Service enables comprehensive tracking of customer behavior including page views, purchases, add-to-cart actions, and custom events.
3
4
## Capabilities
5
6
### Event Collection
7
8
Real-time and batch collection of user interaction events for recommendation training and analytics.
9
10
```python { .api }
11
class UserEventServiceClient:
12
def write_user_event(self, request: WriteUserEventRequest) -> UserEvent:
13
"""
14
Records a single user event in real-time.
15
16
Args:
17
request: Contains parent catalog and user event data
18
19
Returns:
20
UserEvent: The recorded event with server-generated metadata
21
22
Raises:
23
InvalidArgument: If event data is invalid or incomplete
24
"""
25
26
def collect_user_event(self, request: CollectUserEventRequest) -> HttpBody:
27
"""
28
Collects user events via HTTP GET request (typically used with pixel tracking).
29
30
Args:
31
request: Contains parent, user_event query parameter, and optional parameters
32
33
Returns:
34
HttpBody: Response suitable for pixel tracking (usually empty)
35
"""
36
37
def import_user_events(self, request: ImportUserEventsRequest) -> Operation:
38
"""
39
Imports user events in bulk from external sources (long-running operation).
40
41
Args:
42
request: Contains parent, input configuration, and error handling settings
43
44
Returns:
45
Operation: Resolves to ImportUserEventsResponse with import statistics
46
"""
47
48
def rejoin_user_events(self, request: RejoinUserEventsRequest) -> Operation:
49
"""
50
Re-associates user events with updated product catalog (long-running operation).
51
52
Args:
53
request: Contains parent and rejoin configuration
54
55
Returns:
56
Operation: Resolves to RejoinUserEventsResponse with rejoin statistics
57
"""
58
59
def purge_user_events(self, request: PurgeUserEventsRequest) -> Operation:
60
"""
61
Permanently deletes user events matching filter criteria (long-running operation).
62
63
Args:
64
request: Contains parent, filter, and force flag
65
66
Returns:
67
Operation: Resolves to PurgeUserEventsResponse with purge count
68
"""
69
```
70
71
```python { .api }
72
class UserEventServiceAsyncClient:
73
async def write_user_event(self, request: WriteUserEventRequest) -> UserEvent:
74
"""
75
Records a single user event in real-time (async).
76
77
Args:
78
request: Contains parent catalog and user event data
79
80
Returns:
81
UserEvent: The recorded event with server-generated metadata
82
83
Raises:
84
InvalidArgument: If event data is invalid or incomplete
85
"""
86
87
async def collect_user_event(self, request: CollectUserEventRequest) -> HttpBody:
88
"""
89
Collects user events via HTTP GET request - async version (typically used with pixel tracking).
90
91
Args:
92
request: Contains parent, user_event query parameter, and optional parameters
93
94
Returns:
95
HttpBody: Response suitable for pixel tracking (usually empty)
96
"""
97
98
async def import_user_events(self, request: ImportUserEventsRequest) -> Operation:
99
"""
100
Imports user events in bulk from external sources - async version (long-running operation).
101
102
Args:
103
request: Contains parent, input configuration, and error handling settings
104
105
Returns:
106
Operation: Resolves to ImportUserEventsResponse with import statistics
107
"""
108
109
async def rejoin_user_events(self, request: RejoinUserEventsRequest) -> Operation:
110
"""
111
Re-associates user events with updated product catalog - async version (long-running operation).
112
113
Args:
114
request: Contains parent and rejoin configuration
115
116
Returns:
117
Operation: Resolves to RejoinUserEventsResponse with rejoin statistics
118
"""
119
120
async def purge_user_events(self, request: PurgeUserEventsRequest) -> Operation:
121
"""
122
Permanently deletes user events matching filter criteria - async version (long-running operation).
123
124
Args:
125
request: Contains parent, filter, and force flag
126
127
Returns:
128
Operation: Resolves to PurgeUserEventsResponse with purge count
129
"""
130
```
131
132
## Data Types
133
134
### User Event
135
136
Comprehensive user interaction event with product details and context information.
137
138
```python { .api }
139
class UserEvent:
140
event_type: str # Event type (required): page-view, add-to-cart, purchase, etc.
141
visitor_id: str # Unique visitor identifier (required)
142
session_id: str # Session identifier for grouping events
143
event_time: Timestamp # When event occurred (auto-set if not provided)
144
experiment_ids: List[str] # A/B test experiment identifiers
145
attribution_token: str # Token from search/prediction response
146
product_details: List[ProductDetail] # Products involved in the event
147
completion_detail: CompletionDetail # Details for search completion events
148
attributes: Dict[str, CustomAttribute] # Custom event attributes
149
cart_id: str # Shopping cart identifier
150
purchase_transaction: PurchaseTransaction # Transaction details for purchase events
151
search_query: str # Search query for search events
152
filter: str # Applied filters for search events
153
order_by: str # Sort order for search events
154
offset: int # Pagination offset for search events
155
page_categories: List[str] # Page context categories
156
user_info: UserInfo # User context information
157
uri: str # Page URI where event occurred
158
referrer_uri: str # Referrer page URI
159
page_view_id: str # Unique page view identifier
160
```
161
162
### Product Detail
163
164
Product-specific information within user events including quantities and custom data.
165
166
```python { .api }
167
class ProductDetail:
168
product: Product # Product information (id is required, other fields optional)
169
quantity: int # Quantity involved in the event (default: 1)
170
171
# For purchases, ratings, and other detailed interactions
172
rating: float # User rating for the product (1-5 scale)
173
value: Money # Monetary value associated with this product
174
cost: Money # Cost associated with this product
175
promotion_id: str # Promotion identifier if applicable
176
```
177
178
### Purchase Transaction
179
180
Comprehensive transaction information for purchase events and revenue tracking.
181
182
```python { .api }
183
class PurchaseTransaction:
184
id: str # Unique transaction identifier
185
revenue: float # Total transaction revenue (required)
186
tax: float # Tax amount
187
cost: float # Total cost of goods sold
188
currency_code: str # ISO 4217 currency code (required)
189
190
# Additional transaction metadata
191
transaction_attributes: Dict[str, CustomAttribute] # Custom transaction attributes
192
```
193
194
### Completion Detail
195
196
Details for search query auto-completion interaction events.
197
198
```python { .api }
199
class CompletionDetail:
200
completion_attribution_token: str # Attribution token from completion response
201
selected_suggestion: str # The completion suggestion selected by user
202
selected_position: int # Position of selected suggestion in completion list
203
```
204
205
### Request Types
206
207
Comprehensive request configurations for various user event operations.
208
209
```python { .api }
210
class WriteUserEventRequest:
211
parent: str # Catalog resource name (required)
212
user_event: UserEvent # User event to record (required)
213
write_async: bool # Whether to write asynchronously (default: false)
214
215
class CollectUserEventRequest:
216
parent: str # Catalog resource name (required)
217
user_event: str # URL-encoded user event data (required)
218
uri: str # Page URI where event occurred
219
ets: int # Event timestamp (Unix timestamp in milliseconds)
220
raw_json: str # Raw JSON event data (alternative to user_event parameter)
221
222
class ImportUserEventsRequest:
223
parent: str # Catalog resource name (required)
224
input_config: UserEventInputConfig # Data source configuration (required)
225
errors_config: ImportErrorsConfig # Error handling configuration
226
227
class RejoinUserEventsRequest:
228
parent: str # Catalog resource name (required)
229
rejoin_type: RejoinUserEventsRequestRejoinType # Type of rejoin operation
230
231
class PurgeUserEventsRequest:
232
parent: str # Catalog resource name (required)
233
filter: str # Filter expression for events to purge (required)
234
force: bool # Force purge without confirmation (required)
235
```
236
237
### Import Configuration
238
239
Configuration for bulk user event import from various data sources.
240
241
```python { .api }
242
class UserEventInputConfig:
243
user_event_inline_source: UserEventInlineSource # Inline event data
244
gcs_source: GcsSource # Google Cloud Storage source
245
big_query_source: BigQuerySource # BigQuery source
246
247
class UserEventInlineSource:
248
user_events: List[UserEvent] # List of events to import
249
250
class UserEventImportSummary:
251
joined_events_count: int # Number of events successfully joined with products
252
unjoined_events_count: int # Number of events that couldn't be joined
253
```
254
255
### Event Types
256
257
Standard event types for different user interactions and custom event support.
258
259
```python { .api }
260
# Standard Event Types
261
EVENT_TYPE_PAGE_VIEW = "page-view" # User viewed a page/product
262
EVENT_TYPE_ADD_TO_CART = "add-to-cart" # User added item to cart
263
EVENT_TYPE_REMOVE_FROM_CART = "remove-from-cart" # User removed item from cart
264
EVENT_TYPE_PURCHASE_COMPLETE = "purchase-complete" # User completed purchase
265
EVENT_TYPE_SEARCH = "search" # User performed search
266
EVENT_TYPE_DETAIL_PAGE_VIEW = "detail-page-view" # User viewed product detail page
267
EVENT_TYPE_HOME_PAGE_VIEW = "home-page-view" # User viewed homepage
268
EVENT_TYPE_CATEGORY_PAGE_VIEW = "category-page-view" # User viewed category page
269
EVENT_TYPE_SHOPPING_CART_PAGE_VIEW = "shopping-cart-page-view" # User viewed cart
270
EVENT_TYPE_LOGIN = "login" # User logged in
271
EVENT_TYPE_SIGNUP = "signup" # User signed up
272
273
# Custom event types are also supported - use descriptive names
274
```
275
276
## Usage Examples
277
278
### Recording Real-time User Events
279
280
```python
281
from google.cloud import retail
282
from google.protobuf.timestamp_pb2 import Timestamp
283
import time
284
285
client = retail.UserEventServiceClient()
286
287
# Record a product page view
288
page_view_event = retail.UserEvent(
289
event_type="detail-page-view",
290
visitor_id="visitor-123",
291
session_id="session-456",
292
user_info=retail.UserInfo(
293
user_id="user-789",
294
ip_address="192.168.1.100",
295
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
296
),
297
product_details=[
298
retail.ProductDetail(
299
product=retail.Product(id="product-123"),
300
quantity=1
301
)
302
],
303
uri="https://example.com/products/product-123",
304
page_categories=["Electronics", "Laptops"]
305
)
306
307
request = retail.WriteUserEventRequest(
308
parent="projects/my-project/locations/global/catalogs/default_catalog",
309
user_event=page_view_event
310
)
311
312
recorded_event = client.write_user_event(request=request)
313
print(f"Recorded event: {recorded_event.event_type} at {recorded_event.event_time}")
314
```
315
316
### Recording Purchase Events
317
318
```python
319
# Record a purchase transaction
320
purchase_event = retail.UserEvent(
321
event_type="purchase-complete",
322
visitor_id="visitor-123",
323
session_id="session-456",
324
user_info=retail.UserInfo(
325
user_id="user-789",
326
ip_address="192.168.1.100"
327
),
328
product_details=[
329
retail.ProductDetail(
330
product=retail.Product(id="laptop-456"),
331
quantity=1
332
),
333
retail.ProductDetail(
334
product=retail.Product(id="mouse-789"),
335
quantity=2
336
)
337
],
338
purchase_transaction=retail.PurchaseTransaction(
339
id="txn-12345",
340
revenue=1599.97,
341
tax=128.00,
342
cost=1200.00,
343
currency_code="USD"
344
),
345
uri="https://example.com/checkout/success",
346
cart_id="cart-abc123"
347
)
348
349
request = retail.WriteUserEventRequest(
350
parent="projects/my-project/locations/global/catalogs/default_catalog",
351
user_event=purchase_event
352
)
353
354
recorded_event = client.write_user_event(request=request)
355
print(f"Recorded purchase: ${purchase_event.purchase_transaction.revenue}")
356
```
357
358
### Recording Search Events
359
360
```python
361
# Record a search event with results
362
search_event = retail.UserEvent(
363
event_type="search",
364
visitor_id="visitor-123",
365
session_id="session-456",
366
search_query="gaming laptop",
367
filter='(categories: ANY("Electronics")) AND (price_info.price: [500, 2000])',
368
order_by="price_info.price desc",
369
offset=0,
370
user_info=retail.UserInfo(
371
user_id="user-789"
372
),
373
uri="https://example.com/search?q=gaming+laptop",
374
page_categories=["Search Results"]
375
)
376
377
request = retail.WriteUserEventRequest(
378
parent="projects/my-project/locations/global/catalogs/default_catalog",
379
user_event=search_event
380
)
381
382
recorded_event = client.write_user_event(request=request)
383
print(f"Recorded search for: {search_event.search_query}")
384
```
385
386
### Recording Add-to-Cart Events
387
388
```python
389
# Record add-to-cart event
390
add_to_cart_event = retail.UserEvent(
391
event_type="add-to-cart",
392
visitor_id="visitor-123",
393
session_id="session-456",
394
user_info=retail.UserInfo(
395
user_id="user-789"
396
),
397
product_details=[
398
retail.ProductDetail(
399
product=retail.Product(id="laptop-456"),
400
quantity=1
401
)
402
],
403
cart_id="cart-abc123",
404
uri="https://example.com/products/laptop-456",
405
attribution_token="attribution_token_from_search_or_prediction" # If user came from search/recommendations
406
)
407
408
request = retail.WriteUserEventRequest(
409
parent="projects/my-project/locations/global/catalogs/default_catalog",
410
user_event=add_to_cart_event
411
)
412
413
recorded_event = client.write_user_event(request=request)
414
print(f"Recorded add-to-cart for product: {add_to_cart_event.product_details[0].product.id}")
415
```
416
417
### Bulk Import User Events
418
419
```python
420
# Import events from Google Cloud Storage
421
input_config = retail.UserEventInputConfig(
422
gcs_source=retail.GcsSource(
423
input_uris=["gs://my-bucket/user-events/events-2024-01.jsonl"]
424
)
425
)
426
427
errors_config = retail.ImportErrorsConfig(
428
gcs_prefix="gs://my-bucket/import-errors/"
429
)
430
431
request = retail.ImportUserEventsRequest(
432
parent="projects/my-project/locations/global/catalogs/default_catalog",
433
input_config=input_config,
434
errors_config=errors_config
435
)
436
437
operation = client.import_user_events(request=request)
438
print(f"Import operation: {operation.name}")
439
440
# Wait for import to complete
441
result = operation.result()
442
print(f"Import completed:")
443
print(f"- Joined events: {result.import_summary.joined_events_count}")
444
print(f"- Unjoined events: {result.import_summary.unjoined_events_count}")
445
print(f"- Total errors: {len(result.error_samples)}")
446
```
447
448
### Inline Event Import
449
450
```python
451
# Import events directly from code
452
events_to_import = [
453
retail.UserEvent(
454
event_type="page-view",
455
visitor_id="visitor-111",
456
product_details=[retail.ProductDetail(product=retail.Product(id="product-1"))]
457
),
458
retail.UserEvent(
459
event_type="add-to-cart",
460
visitor_id="visitor-111",
461
product_details=[retail.ProductDetail(product=retail.Product(id="product-1"), quantity=2)]
462
),
463
retail.UserEvent(
464
event_type="purchase-complete",
465
visitor_id="visitor-111",
466
product_details=[retail.ProductDetail(product=retail.Product(id="product-1"), quantity=2)],
467
purchase_transaction=retail.PurchaseTransaction(
468
id="txn-inline-1",
469
revenue=199.98,
470
currency_code="USD"
471
)
472
)
473
]
474
475
input_config = retail.UserEventInputConfig(
476
user_event_inline_source=retail.UserEventInlineSource(
477
user_events=events_to_import
478
)
479
)
480
481
request = retail.ImportUserEventsRequest(
482
parent="projects/my-project/locations/global/catalogs/default_catalog",
483
input_config=input_config
484
)
485
486
operation = client.import_user_events(request=request)
487
result = operation.result()
488
print(f"Imported {result.import_summary.joined_events_count} events")
489
```
490
491
### Event Data Maintenance
492
493
```python
494
# Rejoin user events after product catalog updates
495
rejoin_request = retail.RejoinUserEventsRequest(
496
parent="projects/my-project/locations/global/catalogs/default_catalog",
497
rejoin_type=retail.RejoinUserEventsRequest.RejoinType.UNJOINED_EVENTS
498
)
499
500
operation = client.rejoin_user_events(request=rejoin_request)
501
rejoin_result = operation.result()
502
print(f"Rejoined {rejoin_result.rejoined_user_events_count} events")
503
504
# Purge old user events (be very careful with this operation!)
505
purge_request = retail.PurgeUserEventsRequest(
506
parent="projects/my-project/locations/global/catalogs/default_catalog",
507
filter='(event_time: ["2023-01-01T00:00:00Z", "2023-12-31T23:59:59Z"])', # Purge 2023 events
508
force=True
509
)
510
511
operation = client.purge_user_events(request=purge_request)
512
purge_result = operation.result()
513
print(f"Purged {purge_result.purged_events_count} events")
514
```
515
516
### Pixel Tracking Integration
517
518
```python
519
# For web pixel tracking, you would typically use the collect_user_event method
520
# This is usually called from JavaScript, but here's how to use it from Python:
521
522
import urllib.parse
523
524
# Construct event data
525
event_data = {
526
"eventType": "page-view",
527
"visitorId": "visitor-123",
528
"productDetails": [{"product": {"id": "product-456"}}],
529
"uri": "https://example.com/products/product-456"
530
}
531
532
# URL encode the event data
533
encoded_event = urllib.parse.quote(json.dumps(event_data))
534
535
request = retail.CollectUserEventRequest(
536
parent="projects/my-project/locations/global/catalogs/default_catalog",
537
user_event=encoded_event,
538
uri="https://example.com/products/product-456"
539
)
540
541
# This returns HttpBody suitable for pixel tracking
542
response = client.collect_user_event(request=request)
543
print("Event collected via pixel tracking")
544
```