@walkeros/server-destination-datamanager 4.1.0-next-1778668930820 → 4.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,305 @@
1
+ # @walkeros/server-destination-datamanager
2
+
3
+ ## 4.1.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [e155ff8]
8
+ - Updated dependencies [e800974]
9
+ - Updated dependencies [e155ff8]
10
+ - Updated dependencies [1a8f2d7]
11
+ - Updated dependencies [1a8f2d7]
12
+ - Updated dependencies [b276173]
13
+ - Updated dependencies [dd9f5ad]
14
+ - Updated dependencies [c60ef35]
15
+ - Updated dependencies [adeebea]
16
+ - Updated dependencies [13aaeaa]
17
+ - Updated dependencies [e800974]
18
+ - Updated dependencies [adeebea]
19
+ - Updated dependencies [e800974]
20
+ - Updated dependencies [e800974]
21
+ - Updated dependencies [058f7ed]
22
+ - Updated dependencies [28a8ac2]
23
+ - Updated dependencies [fd6076e]
24
+ - @walkeros/core@4.1.0
25
+ - @walkeros/server-core@4.1.0
26
+
27
+ ## 4.0.2
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [a6a0ea7]
32
+ - @walkeros/core@4.0.2
33
+ - @walkeros/server-core@4.0.2
34
+
35
+ ## 4.0.1
36
+
37
+ ### Patch Changes
38
+
39
+ - Updated dependencies [381dfe7]
40
+ - Updated dependencies [1524275]
41
+ - Updated dependencies [03d7055]
42
+ - @walkeros/core@4.0.1
43
+ - @walkeros/server-core@4.0.1
44
+
45
+ ## 4.0.0
46
+
47
+ ### Major Changes
48
+
49
+ - 93ea9c4: Event model v4: breaking changes to the `Event`, `Source`, and
50
+ `Entity` shapes.
51
+ - `event.id` is now a W3C span_id (16 lowercase hex chars), generated by the
52
+ collector. Reference: W3C Trace Context (W3C Recommendation, January 2020).
53
+ - `event.version`, `event.group`, `event.count` are removed.
54
+ - `source.type` is now the source kind (e.g. `browser`, `gtag`, `mcp`, `cli`).
55
+ New `source.platform` holds the runtime (`web` | `server` | `app` | ...).
56
+ - `source.id` and `source.previous_id` are removed.
57
+ - Browser source now sets `source.url` and `source.referrer`.
58
+ - MCP source sets `source.tool` per emission. CLI source sets
59
+ `source.command`.
60
+ - `Entity.nested` and `Entity.context` are now optional. Root `event.nested`
61
+ and `event.context` remain required.
62
+ - Each source self-registers via TypeScript module augmentation of `SourceMap`
63
+ in `@walkeros/core`.
64
+ - App-side coordination (`/workspaces/developer/app`) is a follow-up plan, not
65
+ part of this release. Telemetry from v4 CLI/MCP will not validate against
66
+ the existing app schema until that follow-up ships.
67
+ - `Mapping.Rule.skip` is renamed to `Mapping.Rule.silent`. Customer flow.json
68
+ configs using `skip: true` in mapping rules must rename to `silent: true`.
69
+ Hard cut: no legacy alias, the field is gone.
70
+
71
+ ### Patch Changes
72
+
73
+ - Updated dependencies [93ea9c4]
74
+ - Updated dependencies [465775c]
75
+ - Updated dependencies [942a7fe]
76
+ - Updated dependencies [cfc7469]
77
+ - Updated dependencies [8e06b1f]
78
+ - Updated dependencies [3d50dd6]
79
+ - Updated dependencies [1ef33d9]
80
+ - @walkeros/core@4.0.0
81
+ - @walkeros/server-core@4.0.0
82
+
83
+ ## 3.4.2
84
+
85
+ ### Patch Changes
86
+
87
+ - @walkeros/core@3.4.2
88
+ - @walkeros/server-core@3.4.2
89
+
90
+ ## 3.4.1
91
+
92
+ ### Patch Changes
93
+
94
+ - Updated dependencies [12adf24]
95
+ - Updated dependencies [75aa26b]
96
+ - @walkeros/core@3.4.1
97
+ - @walkeros/server-core@3.4.1
98
+
99
+ ## 3.4.0
100
+
101
+ ### Minor Changes
102
+
103
+ - 724f97e: Migrate every step example in every walkerOS package to the
104
+ standardized `[callable, ...args][]` shape introduced in `@walkeros/core`.
105
+ Every step example's `out` is now an array of effect tuples whose first
106
+ element is the callable's public SDK name (`'gtag'`, `'analytics.track'`,
107
+ `'fbq'`, `'dataLayer.push'`, `'sendServer'`, `'fetch'`, `'trackClient.track'`,
108
+ `'amplitude.track'`, `'fs.writeFile'`, `'producer.send'`, `'client.xadd'`,
109
+ `'client.send'`, `'dataset.table.insert'`, etc.). Source examples use `'elb'`
110
+ as the callable; transformer examples use the reserved `'return'` keyword;
111
+ store examples use store-operation callables (`'get'`, `'set'`). Tests capture
112
+ real calls on each component's spy and assert against `example.out` directly —
113
+ the hardcoded `PACKAGE_CALLS` registry in the app is no longer consulted
114
+ (emptied; plan #3 removes it structurally).
115
+
116
+ ### Patch Changes
117
+
118
+ - Updated dependencies [74940cc]
119
+ - Updated dependencies [525f5d9]
120
+ - @walkeros/core@3.4.0
121
+ - @walkeros/server-core@3.4.0
122
+
123
+ ## 3.3.1
124
+
125
+ ### Patch Changes
126
+
127
+ - @walkeros/server-core@3.3.1
128
+ - @walkeros/core@3.3.1
129
+
130
+ ## 3.3.0
131
+
132
+ ### Patch Changes
133
+
134
+ - Updated dependencies [2849acb]
135
+ - Updated dependencies [08c365a]
136
+ - Updated dependencies [08c365a]
137
+ - Updated dependencies [08c365a]
138
+ - Updated dependencies [08c365a]
139
+ - @walkeros/core@3.3.0
140
+ - @walkeros/server-core@3.3.0
141
+
142
+ ## 3.2.0
143
+
144
+ ### Patch Changes
145
+
146
+ - Updated dependencies [eb865e1]
147
+ - Updated dependencies [c0a53f9]
148
+ - Updated dependencies [f007c9f]
149
+ - Updated dependencies [bf2dc5b]
150
+ - Updated dependencies [da0b640]
151
+ - @walkeros/core@3.2.0
152
+ - @walkeros/server-core@3.2.0
153
+
154
+ ## 3.1.1
155
+
156
+ ### Patch Changes
157
+
158
+ - @walkeros/core@3.1.1
159
+ - @walkeros/server-core@3.1.1
160
+
161
+ ## 3.1.0
162
+
163
+ ### Patch Changes
164
+
165
+ - Updated dependencies [dfc6738]
166
+ - Updated dependencies [966342b]
167
+ - Updated dependencies [bee8ba7]
168
+ - Updated dependencies [966342b]
169
+ - Updated dependencies [df990d4]
170
+ - @walkeros/core@3.1.0
171
+ - @walkeros/server-core@3.1.0
172
+
173
+ ## 3.0.2
174
+
175
+ ### Patch Changes
176
+
177
+ - @walkeros/core@3.0.2
178
+ - @walkeros/server-core@3.0.2
179
+
180
+ ## 3.0.1
181
+
182
+ ### Patch Changes
183
+
184
+ - @walkeros/core@3.0.1
185
+ - @walkeros/server-core@3.0.1
186
+
187
+ ## 3.0.0
188
+
189
+ ### Patch Changes
190
+
191
+ - 499e27a: Add sideEffects declarations to all packages for bundler tree-shaking
192
+ support.
193
+ - Updated dependencies [2b259b6]
194
+ - Updated dependencies [2614014]
195
+ - Updated dependencies [6ae0ee3]
196
+ - Updated dependencies [37299a9]
197
+ - Updated dependencies [499e27a]
198
+ - Updated dependencies [0e5eede]
199
+ - Updated dependencies [d11f574]
200
+ - Updated dependencies [d11f574]
201
+ - Updated dependencies [1fe337a]
202
+ - Updated dependencies [5cb84c1]
203
+ - Updated dependencies [23f218a]
204
+ - Updated dependencies [499e27a]
205
+ - Updated dependencies [c83d909]
206
+ - Updated dependencies [b6c8fa8]
207
+ - @walkeros/core@3.0.0
208
+ - @walkeros/server-core@3.0.0
209
+
210
+ ## 2.1.1
211
+
212
+ ### Patch Changes
213
+
214
+ - Updated dependencies [fab477d]
215
+ - @walkeros/core@2.1.1
216
+ - @walkeros/server-core@2.1.1
217
+
218
+ ## 2.1.0
219
+
220
+ ### Minor Changes
221
+
222
+ - 97df0b2: Step examples: upgrade all packages to blueprint pattern with inline
223
+ mapping, no intermediate variables, no `all` export
224
+
225
+ ### Patch Changes
226
+
227
+ - Updated dependencies [7fc4cee]
228
+ - Updated dependencies [7fc4cee]
229
+ - Updated dependencies [cb2da05]
230
+ - Updated dependencies [2bbe8c8]
231
+ - Updated dependencies [3eb6416]
232
+ - Updated dependencies [02a7958]
233
+ - Updated dependencies [97df0b2]
234
+ - Updated dependencies [97df0b2]
235
+ - Updated dependencies [026c412]
236
+ - Updated dependencies [7d38d9d]
237
+ - @walkeros/core@2.1.0
238
+ - @walkeros/server-core@2.1.0
239
+
240
+ ## 2.0.1
241
+
242
+ ## 1.0.6
243
+
244
+ ### Patch Changes
245
+
246
+ - Updated dependencies [7b2d750]
247
+ - @walkeros/core@1.4.0
248
+ - @walkeros/server-core@2.0.0
249
+
250
+ ## 1.0.5
251
+
252
+ ### Patch Changes
253
+
254
+ - Updated dependencies [a4cc1ea]
255
+ - @walkeros/core@1.3.0
256
+ - @walkeros/server-core@1.0.5
257
+
258
+ ## 1.0.4
259
+
260
+ ### Patch Changes
261
+
262
+ - Updated dependencies [7ad6cfb]
263
+ - @walkeros/core@1.2.2
264
+ - @walkeros/server-core@1.0.4
265
+
266
+ ## 1.0.3
267
+
268
+ ### Patch Changes
269
+
270
+ - Updated dependencies [6256c12]
271
+ - @walkeros/core@1.2.1
272
+ - @walkeros/server-core@1.0.3
273
+
274
+ ## 1.0.2
275
+
276
+ ### Patch Changes
277
+
278
+ - Updated dependencies [f39d9fb]
279
+ - Updated dependencies [888bbdf]
280
+ - @walkeros/core@1.2.0
281
+ - @walkeros/server-core@1.0.2
282
+
283
+ ## 1.0.1
284
+
285
+ ### Patch Changes
286
+
287
+ - Updated dependencies [b65b773]
288
+ - Updated dependencies [20eca6e]
289
+ - @walkeros/core@1.1.0
290
+ - @walkeros/server-core@1.0.1
291
+
292
+ ## 1.0.0
293
+
294
+ ### Major Changes
295
+
296
+ - 67c9e1d: Hello World! walkerOS v1.0.0
297
+
298
+ Open-source event data collection. Collect event data for digital analytics in
299
+ a unified and privacy-centric way.
300
+
301
+ ### Patch Changes
302
+
303
+ - Updated dependencies [67c9e1d]
304
+ - @walkeros/core@1.0.0
305
+ - @walkeros/server-core@1.0.0
package/README.md CHANGED
@@ -1,19 +1,19 @@
1
- # @walkeros/server-destination-datamanager
1
+ <p align="left">
2
+ <a href="https://www.walkeros.io">
3
+ <img alt="walkerOS" title="walkerOS" src="https://www.walkeros.io/img/walkerOS_logo.svg" width="256px"/>
4
+ </a>
5
+ </p>
2
6
 
3
- Google Data Manager server destination for walkerOS - send conversion events and
4
- audience data to Google Ads, Display & Video 360, and Google Analytics 4 through
5
- a single unified API.
7
+ # @walkeros/server-destination-datamanager
6
8
 
7
- ## Features
9
+ Server-side event ingestion via the Google Data Manager API to Google Ads,
10
+ Display & Video 360, and Google Analytics 4.
8
11
 
9
- - **Multi-platform reach**: Single API call sends data to Google Ads, DV360, and
10
- GA4
11
- - **Privacy-first**: SHA-256 hashing of PII with Gmail-specific email
12
- normalization
13
- - **DMA compliance**: Built-in consent management for EEA/UK/Switzerland
14
- - **Explicit mapping**: Transform walkerOS events to Data Manager format using
15
- declarative mapping rules
16
- - **Type-safe**: Full TypeScript support with comprehensive type definitions
12
+ [Documentation](https://www.walkeros.io/docs/destinations/server/datamanager)
13
+ &bull;
14
+ [NPM Package](https://www.npmjs.com/package/@walkeros/server-destination-datamanager)
15
+ &bull;
16
+ [Source Code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/datamanager)
17
17
 
18
18
  ## Installation
19
19
 
@@ -21,868 +21,37 @@ a single unified API.
21
21
  npm install @walkeros/server-destination-datamanager
22
22
  ```
23
23
 
24
- ## Quick Start
25
-
26
- ### Minimal Configuration (AWS Lambda / Serverless)
27
-
28
- ```typescript
29
- import { destinationDataManager } from '@walkeros/server-destination-datamanager';
30
- import { startFlow } from '@walkeros/collector';
31
-
32
- const { collector, elb } = await startFlow({
33
- destinations: {
34
- datamanager: {
35
- ...destinationDataManager,
36
- config: {
37
- settings: {
38
- // Service account credentials from environment variables
39
- credentials: {
40
- client_email: process.env.GOOGLE_CLIENT_EMAIL!,
41
- private_key: process.env.GOOGLE_PRIVATE_KEY!.replace(/\\n/g, '\n'),
42
- },
43
-
44
- // Destination accounts
45
- destinations: [
46
- {
47
- operatingAccount: {
48
- accountId: '123-456-7890',
49
- accountType: 'GOOGLE_ADS',
50
- },
51
- productDestinationId: 'AW-CONVERSION-123',
52
- },
53
- ],
54
- },
55
- },
56
- },
57
- },
58
- });
59
-
60
- // Track a conversion
61
- await elb('order complete', {
62
- id: 'ORDER-123',
63
- total: 99.99,
64
- currency: 'USD',
65
- });
66
- ```
67
-
68
- ### GCP Cloud Functions (Application Default Credentials)
69
-
70
- ```typescript
71
- import { destinationDataManager } from '@walkeros/server-destination-datamanager';
72
- import { startFlow } from '@walkeros/collector';
73
-
74
- // No auth config needed - ADC works automatically on GCP!
75
- const { collector, elb } = await startFlow({
76
- destinations: {
77
- datamanager: {
78
- ...destinationDataManager,
79
- config: {
80
- settings: {
81
- destinations: [
82
- {
83
- operatingAccount: {
84
- accountId: '123-456-7890',
85
- accountType: 'GOOGLE_ADS',
86
- },
87
- productDestinationId: 'AW-CONVERSION-123',
88
- },
89
- ],
90
- },
91
- },
92
- },
93
- },
94
- });
95
- ```
96
-
97
- ### Local Development
98
-
99
- ```typescript
100
- import { destinationDataManager } from '@walkeros/server-destination-datamanager';
101
-
102
- const config = {
103
- ...destinationDataManager,
104
- config: {
105
- settings: {
106
- // Service account JSON file
107
- keyFilename: './service-account.json',
108
-
109
- // Multiple destinations (max 10)
110
- destinations: [
111
- {
112
- operatingAccount: {
113
- accountId: '123-456-7890',
114
- accountType: 'GOOGLE_ADS',
115
- },
116
- productDestinationId: 'AW-CONVERSION-123',
117
- },
118
- {
119
- operatingAccount: {
120
- accountId: '987654321',
121
- accountType: 'GOOGLE_ANALYTICS_PROPERTY',
122
- },
123
- productDestinationId: 'G-XXXXXXXXXX',
124
- },
125
- ],
126
-
127
- // Optional settings
128
- eventSource: 'WEB', // Default event source
129
- batchSize: 100, // Events per batch (max 2000)
130
- batchInterval: 5000, // Batch flush interval in ms
131
- validateOnly: false, // Test mode (validate without ingestion)
132
- testEventCode: 'TEST12345', // For debugging
133
-
134
- // Request-level consent
135
- consent: {
136
- adUserData: 'CONSENT_GRANTED',
137
- adPersonalization: 'CONSENT_GRANTED',
138
- },
139
-
140
- // Guided helpers (apply to all events)
141
- userData: {
142
- email: 'user.id',
143
- phone: 'data.phone',
144
- },
145
- userId: 'user.id',
146
- clientId: 'user.device',
147
- sessionAttributes: 'context.sessionAttributes',
148
- },
149
-
150
- // Event mapping
151
- mapping: {
152
- order: {
153
- complete: {
154
- name: 'purchase',
155
- data: {
156
- map: {
157
- transactionId: 'data.id',
158
- conversionValue: 'data.total',
159
- currency: { key: 'data.currency', value: 'USD' },
160
- eventName: { value: 'purchase' }, // For GA4
161
- },
162
- },
163
- },
164
- },
165
- },
166
- },
167
- };
168
- ```
169
-
170
- ## Authentication
171
-
172
- The Data Manager destination uses Google Cloud service accounts with automatic
173
- token refresh. The library handles token management automatically - you just
174
- provide credentials and tokens are cached and refreshed as needed.
175
-
176
- ### Authentication Methods
177
-
178
- The destination supports three authentication methods (in priority order):
179
-
180
- 1. **Inline Credentials** - Best for serverless (AWS Lambda, Docker, K8s)
181
- 2. **Service Account File** - Best for local development
182
- 3. **Application Default Credentials (ADC)** - Automatic on GCP
183
-
184
- ### 1. Inline Credentials (Recommended for Serverless)
185
-
186
- Best for AWS Lambda, Docker, Kubernetes, and other containerized environments
187
- where you manage secrets via environment variables.
188
-
189
- ```typescript
190
- import { destinationDataManager } from '@walkeros/server-destination-datamanager';
191
-
192
- const config = {
193
- ...destinationDataManager,
194
- config: {
195
- settings: {
196
- credentials: {
197
- client_email: process.env.GOOGLE_CLIENT_EMAIL!,
198
- private_key: process.env.GOOGLE_PRIVATE_KEY!.replace(/\\n/g, '\n'),
199
- },
200
- destinations: [
201
- /* ... */
202
- ],
203
- },
204
- },
205
- };
206
- ```
207
-
208
- **Environment Variables:**
209
-
210
- ```bash
211
- GOOGLE_CLIENT_EMAIL=service-account@project.iam.gserviceaccount.com
212
- GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n"
213
- ```
214
-
215
- **Note:** Use `.replace(/\\n/g, '\n')` to convert escaped newlines from
216
- environment variables.
217
-
218
- ### 2. Service Account File (Local Development)
219
-
220
- Best for local development with filesystem access.
221
-
222
- ```typescript
223
- const config = {
224
- ...destinationDataManager,
225
- config: {
226
- settings: {
227
- keyFilename: './service-account.json',
228
- destinations: [
229
- /* ... */
230
- ],
231
- },
232
- },
233
- };
234
- ```
235
-
236
- ### 3. Application Default Credentials (GCP)
237
-
238
- Automatic on Google Cloud Platform - no configuration needed!
239
-
240
- ```typescript
241
- const config = {
242
- ...destinationDataManager,
243
- config: {
244
- settings: {
245
- // No auth config needed - ADC used automatically!
246
- destinations: [
247
- /* ... */
248
- ],
249
- },
250
- },
251
- };
252
- ```
253
-
254
- **Works automatically on:**
255
-
256
- - Google Cloud Functions
257
- - Google Cloud Run
258
- - Google Compute Engine
259
- - Google Kubernetes Engine
260
- - Any GCP environment with default service account
261
-
262
- **Also works with:**
263
-
264
- - `GOOGLE_APPLICATION_CREDENTIALS` environment variable
265
- - gcloud CLI: `gcloud auth application-default login`
266
-
267
- ### Creating a Service Account
268
-
269
- 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
270
- 2. Navigate to **IAM & Admin > Service Accounts**
271
- 3. Click **Create Service Account**
272
- 4. Name: `walkeros-datamanager` (or your choice)
273
- 5. Grant role: **Data Manager Admin** or custom role with datamanager
274
- permissions
275
- 6. Click **Keys > Add Key > Create New Key**
276
- 7. Select **JSON** format and download
277
-
278
- **For inline credentials:**
279
-
280
- - Extract `client_email` and `private_key` from the JSON
281
- - Store in environment variables or secrets manager
282
-
283
- **For keyFilename:**
284
-
285
- - Set `keyFilename: '/path/to/downloaded-key.json'`
286
-
287
- **For ADC:**
288
-
289
- - Set `GOOGLE_APPLICATION_CREDENTIALS=/path/to/downloaded-key.json`
290
- - Or deploy to GCP where ADC works automatically
291
-
292
- ### Required OAuth Scope
24
+ ## Quick start
293
25
 
294
- ```
295
- https://www.googleapis.com/auth/datamanager
296
- ```
297
-
298
- This scope is automatically applied - no configuration needed.
299
-
300
- ### Token Management
301
-
302
- - **Lifetime:** 1 hour (3600 seconds)
303
- - **Refresh:** Automatic - library handles expiration
304
- - **Caching:** Tokens are cached and reused until expiration
305
- - **Performance:** ~10-50ms overhead per request for token validation
306
-
307
- ## Guided Mapping Helpers
308
-
309
- Define common fields once in Settings instead of repeating them in every event
310
- mapping:
311
-
312
- ```typescript
313
- {
314
- settings: {
315
- credentials: { /* ... */ },
316
- destinations: [...],
317
-
318
- // Guided helpers (apply to all events)
319
- userData: {
320
- email: 'user.id',
321
- phone: 'data.phone',
322
- firstName: 'data.firstName',
323
- lastName: 'data.lastName',
324
- },
325
- userId: 'user.id',
326
- clientId: 'user.device', // GA4 web stream
327
- appInstanceId: 'user.appInstanceId', // GA4 app stream (Firebase)
328
- sessionAttributes: 'context.sessionAttributes',
329
-
330
- // Consent mapping (string = field name, boolean = static value)
331
- consentAdUserData: 'marketing', // Read event.consent.marketing
332
- consentAdPersonalization: 'personalization', // Read event.consent.personalization
333
- // OR use static values:
334
- // consentAdUserData: true, // Always CONSENT_GRANTED
335
- },
336
- }
337
- ```
338
-
339
- **Precedence**: Settings helpers < config.data < event mapping
340
-
341
- Event mappings always override Settings:
342
-
343
- ```typescript
344
- {
345
- settings: {
346
- userId: 'user.id', // Default for all events
347
- },
348
- mapping: {
349
- order: {
350
- complete: {
351
- data: {
352
- map: {
353
- userId: 'data.customerId', // Override for this event
354
- },
355
- },
356
- },
357
- },
358
- },
359
- }
360
- ```
361
-
362
- ## Data Mapping
363
-
364
- ### Event Data Mapping
365
-
366
- All event data must be explicitly mapped. The destination does not auto-extract
367
- fields from events.
368
-
369
- ```typescript
370
- {
371
- mapping: {
372
- order: {
373
- complete: {
374
- name: 'purchase',
375
- data: {
376
- map: {
377
- // Transaction data
378
- transactionId: 'data.id',
379
- conversionValue: 'data.total',
380
- currency: { key: 'data.currency', value: 'USD' },
381
- eventName: { value: 'purchase' },
382
-
383
- // User identification
384
- userId: 'user.id',
385
- email: 'user.id', // Will be SHA-256 hashed
386
- phone: 'data.phone', // Will be SHA-256 hashed
387
-
388
- // Attribution identifiers
389
- gclid: 'context.gclid',
390
- gbraid: 'context.gbraid',
391
- },
392
- },
393
- },
394
- },
395
- },
396
- }
397
- ```
398
-
399
- ### Attribution Identifiers
400
-
401
- Attribution identifiers must be explicitly mapped:
402
-
403
- ```typescript
404
- {
405
- mapping: {
406
- order: {
407
- complete: {
408
- data: {
409
- map: {
410
- gclid: 'context.gclid', // From URL: ?gclid=TeSter
411
- gbraid: 'context.gbraid', // iOS attribution
412
- wbraid: 'context.wbraid', // Web-to-app
413
- },
414
- },
415
- },
416
- },
417
- },
418
- }
419
- ```
420
-
421
- ### Consent Mapping
422
-
423
- Map your consent field names to Data Manager's required fields:
424
-
425
- ```typescript
26
+ ```json
426
27
  {
427
- settings: {
428
- // Map from your consent field names
429
- consentAdUserData: 'marketing', // Read event.consent.marketing
430
- consentAdPersonalization: 'personalization', // Read event.consent.personalization
431
- },
432
- }
433
-
434
- // Your event with standard consent field names
435
- await elb('order complete', { total: 99.99 }, {
436
- consent: {
437
- marketing: true,
438
- personalization: false,
439
- },
440
- });
441
-
442
- // Becomes Data Manager format
443
- {
444
- consent: {
445
- adUserData: 'CONSENT_GRANTED',
446
- adPersonalization: 'CONSENT_DENIED'
28
+ "version": 4,
29
+ "flows": {
30
+ "default": {
31
+ "config": { "platform": "server" },
32
+ "destinations": {
33
+ "datamanager": {
34
+ "package": "@walkeros/server-destination-datamanager",
35
+ "config": {}
36
+ }
37
+ }
38
+ }
447
39
  }
448
40
  }
449
41
  ```
450
42
 
451
- **Static values** for always-on consent:
452
-
453
- ```typescript
454
- {
455
- settings: {
456
- consentAdUserData: true, // Always CONSENT_GRANTED
457
- consentAdPersonalization: false, // Always CONSENT_DENIED
458
- },
459
- }
460
- ```
461
-
462
- **Fallback**: Without consent mapping, uses `event.consent.marketing` →
463
- `adUserData` and `event.consent.personalization` → `adPersonalization`.
464
-
465
- ## Event Mapping Examples
466
-
467
- ### E-commerce Purchase
468
-
469
- ```typescript
470
- {
471
- mapping: {
472
- order: {
473
- complete: {
474
- name: 'purchase',
475
- data: {
476
- map: {
477
- transactionId: 'data.id',
478
- conversionValue: 'data.total',
479
- currency: { key: 'data.currency', value: 'USD' },
480
- eventName: { value: 'purchase' },
481
-
482
- // Map nested products to cart items
483
- cartData: {
484
- map: {
485
- items: {
486
- loop: [
487
- 'nested',
488
- {
489
- condition: (entity) => entity.entity === 'product',
490
- map: {
491
- merchantProductId: 'data.id',
492
- price: 'data.price',
493
- quantity: { key: 'data.quantity', value: 1 },
494
- },
495
- },
496
- ],
497
- },
498
- },
499
- },
500
- },
501
- },
502
- },
503
- },
504
- },
505
- }
506
- ```
507
-
508
- ### Lead Generation
509
-
510
- ```typescript
511
- {
512
- mapping: {
513
- lead: {
514
- submit: {
515
- name: 'generate_lead',
516
- data: {
517
- map: {
518
- eventName: { value: 'generate_lead' },
519
- conversionValue: { value: 10 },
520
- currency: { value: 'USD' },
521
- },
522
- },
523
- },
524
- },
525
- },
526
- }
527
- ```
528
-
529
- ### Page View (GA4)
530
-
531
- ```typescript
532
- {
533
- mapping: {
534
- page: {
535
- view: {
536
- name: 'page_view',
537
- data: {
538
- map: {
539
- eventName: { value: 'page_view' },
540
- },
541
- },
542
- },
543
- },
544
- },
545
- }
546
- ```
547
-
548
- ### Store Sales (Google Ads, IN_STORE)
549
-
550
- For physical store conversions, set `eventSource: 'IN_STORE'` and map a
551
- `storeId`. The destination wraps it into the API's required
552
- `eventLocation.storeId` shape.
553
-
554
- ```typescript
555
- {
556
- settings: {
557
- eventSource: 'IN_STORE',
558
- destinations: [{
559
- operatingAccount: { accountId: '123-456-7890', accountType: 'GOOGLE_ADS' },
560
- productDestinationId: 'AW-CONVERSION-123',
561
- }],
562
- },
563
- mapping: {
564
- order: {
565
- complete: {
566
- name: 'purchase',
567
- data: {
568
- map: {
569
- transactionId: 'data.id',
570
- conversionValue: 'data.total',
571
- currency: 'data.currency',
572
- storeId: 'data.storeId',
573
- // Optional: hashed PII still applies for in-store matching
574
- email: 'user.email',
575
- phone: 'data.phone',
576
- },
577
- },
578
- },
579
- },
580
- },
581
- }
582
- ```
583
-
584
- ### App Conversions (GA4 app stream)
585
-
586
- For GA4 app event ingestion, set `eventSource: 'APP'` and provide an
587
- `appInstanceId` (Firebase install ID). It can be set per-event via mapping or as
588
- a Settings guided helper.
43
+ ## Documentation
589
44
 
590
- ```typescript
591
- {
592
- settings: {
593
- eventSource: 'APP',
594
- appInstanceId: 'user.appInstanceId', // Settings helper
595
- destinations: [{
596
- operatingAccount: { accountId: '123456789', accountType: 'GOOGLE_ANALYTICS_PROPERTY' },
597
- productDestinationId: 'G-XXXXXXXXXX',
598
- }],
599
- },
600
- }
601
- ```
602
-
603
- ## Account Types
604
-
605
- ### Google Ads
606
-
607
- ```typescript
608
- {
609
- operatingAccount: {
610
- accountId: '123-456-7890', // Format: XXX-XXX-XXXX
611
- accountType: 'GOOGLE_ADS',
612
- },
613
- productDestinationId: 'AW-CONVERSION-123', // Conversion action ID
614
- }
615
- ```
616
-
617
- ### Display & Video 360
618
-
619
- ```typescript
620
- {
621
- operatingAccount: {
622
- accountId: '12345', // Advertiser ID
623
- accountType: 'DISPLAY_VIDEO_ADVERTISER',
624
- },
625
- productDestinationId: 'FL-ACTIVITY-123', // Floodlight activity ID
626
- }
627
- ```
45
+ Full configuration, mapping, and examples live in the docs:
46
+ **https://www.walkeros.io/docs/destinations/server/datamanager**
628
47
 
629
- ### Google Analytics 4
630
-
631
- ```typescript
632
- {
633
- operatingAccount: {
634
- accountId: '123456789', // Property ID
635
- accountType: 'GOOGLE_ANALYTICS_PROPERTY',
636
- },
637
- productDestinationId: 'G-XXXXXXXXXX', // Measurement ID
638
- }
639
- ```
640
-
641
- ## Data Formatting
642
-
643
- ### Email Normalization
644
-
645
- - Trim whitespace
646
- - Convert to lowercase
647
- - Remove dots (.) for gmail.com/googlemail.com
648
- - SHA-256 hash
649
-
650
- **Example:**
651
-
652
- ```
653
- Input: John.Doe@Gmail.com
654
- Output: <SHA-256 hash of "johndoe@gmail.com">
655
- ```
656
-
657
- ### Phone Normalization
658
-
659
- - Convert to E.164 format: `+[country][number]`
660
- - Remove all non-digit characters except leading +
661
- - SHA-256 hash
662
-
663
- **Example:**
664
-
665
- ```
666
- Input: (800) 555-0100
667
- Output: <SHA-256 hash of "+18005550100">
668
- ```
669
-
670
- ### Address Formatting
671
-
672
- - **Names**: Lowercase, remove titles/suffixes, SHA-256 hash
673
- - **Region Code**: ISO-3166-1 alpha-2, NOT hashed (e.g., "US")
674
- - **Postal Code**: NOT hashed
675
-
676
- ### Hash encoding
677
-
678
- Every request is sent with `encoding: 'HEX'`, which Google requires whenever the
679
- payload contains hashed `userData`. The value is pinned because all hashing in
680
- this destination produces lowercase hex SHA-256 digests; exposing encoding as a
681
- setting would risk silently mismatched identifiers between the hashed value and
682
- the declared encoding.
683
-
684
- ## Consent Management (DMA)
685
-
686
- ### Required for EEA/UK/Switzerland
687
-
688
- ```typescript
689
- // Event-level consent
690
- await elb('order complete', {
691
- total: 99.99,
692
- }, {
693
- consent: {
694
- marketing: true,
695
- personalization: false,
696
- },
697
- });
698
-
699
- // Request-level consent (applies to all events)
700
- {
701
- settings: {
702
- consent: {
703
- adUserData: 'CONSENT_GRANTED',
704
- adPersonalization: 'CONSENT_GRANTED',
705
- },
706
- },
707
- }
708
- ```
48
+ ## Contribute
709
49
 
710
- ## Testing
711
-
712
- ### Validate Mode
713
-
714
- Test requests without actually ingesting data:
715
-
716
- ```typescript
717
- {
718
- settings: {
719
- validateOnly: true, // Validates structure without ingestion
720
- testEventCode: 'TEST12345', // For debugging
721
- },
722
- }
723
- ```
724
-
725
- ### Test Event Code
726
-
727
- Add test event code for debugging in production:
728
-
729
- ```typescript
730
- {
731
- settings: {
732
- testEventCode: 'TEST12345',
733
- },
734
- }
735
- ```
736
-
737
- ## Debug Mode
738
-
739
- Enable debug logging to see API requests and responses:
740
-
741
- ```typescript
742
- {
743
- settings: {
744
- logLevel: 'debug', // Shows all API calls and responses
745
- },
746
- }
747
- ```
748
-
749
- **Log levels**: `debug` (all), `info`, `warn`, `error`, `none` (default).
750
-
751
- Debug mode logs:
752
-
753
- - Event processing details
754
- - API request payload and destination count
755
- - API response status and request ID
756
- - Validation errors with full context
757
-
758
- ## Deduplication with gtag
759
-
760
- Prevent double-counting between client-side gtag and server-side Data Manager:
761
-
762
- ### Transaction ID Matching
763
-
764
- Use the same transaction ID across both platforms:
765
-
766
- ```javascript
767
- // Client-side gtag
768
- gtag('event', 'conversion', {
769
- transaction_id: 'ORDER-123',
770
- send_to: 'AW-CONVERSION/xxx',
771
- });
772
- ```
773
-
774
- ```typescript
775
- // Server-side walkerOS
776
- await elb('order complete', {
777
- id: 'ORDER-123', // Must map to transactionId via mapping config
778
- });
779
- ```
780
-
781
- Google deduplicates using `transactionId` within 14 days. You must explicitly
782
- map the transaction ID in your configuration.
783
-
784
- ### GCLID Attribution
785
-
786
- Map GCLID from your event structure:
787
-
788
- ```typescript
789
- {
790
- mapping: {
791
- order: {
792
- complete: {
793
- data: {
794
- map: {
795
- gclid: 'context.gclid', // From URL parameter
796
- transactionId: 'data.id',
797
- },
798
- },
799
- },
800
- },
801
- },
802
- }
803
- ```
804
-
805
- GCLID is captured by walkerOS browser source from URL parameters (`?gclid=xxx`)
806
- and stored in `context.gclid`.
807
-
808
- ## Rate Limits
809
-
810
- - **300 requests per minute** per project
811
- - **100,000 requests per day** per project
812
- - Error code: `RESOURCE_EXHAUSTED` (HTTP 429)
813
-
814
- ## Conversion Window
815
-
816
- **CRITICAL**: Events must occur within the last **14 days**. Older events will
817
- be rejected.
818
-
819
- ## API Reference
820
-
821
- ### Settings
822
-
823
- | Property | Type | Required | Description |
824
- | -------------------------- | -------------- | -------- | --------------------------------------------- |
825
- | `credentials` | object | \* | Service account (client_email + private_key) |
826
- | `keyFilename` | string | \* | Path to service account JSON file |
827
- | `scopes` | string[] | | OAuth scopes (default: datamanager scope) |
828
- | `destinations` | Destination[] | ✓ | Array of destination accounts (max 10) |
829
- | `eventSource` | EventSource | | Default event source (WEB, APP, etc.) |
830
- | `batchSize` | number | | Max events per batch (max 2000) |
831
- | `batchInterval` | number | | Batch flush interval in ms |
832
- | `validateOnly` | boolean | | Validate without ingestion |
833
- | `url` | string | | Override API endpoint |
834
- | `consent` | Consent | | Request-level consent |
835
- | `testEventCode` | string | | Test event code for debugging |
836
- | `userData` | object | | Guided helper: User data mapping |
837
- | `userId` | string | | Guided helper: First-party user ID |
838
- | `clientId` | string | | Guided helper: GA4 client ID (web stream) |
839
- | `appInstanceId` | string | | Guided helper: GA4 app instance ID (Firebase) |
840
- | `sessionAttributes` | string | | Guided helper: Privacy-safe attribution |
841
- | `consentAdUserData` | string/boolean | | Consent mapping: Field name or static value |
842
- | `consentAdPersonalization` | string/boolean | | Consent mapping: Field name or static value |
843
-
844
- **\* One of `credentials`, `keyFilename`, or ADC (automatic) required for
845
- authentication**
846
-
847
- ### Event Fields
848
-
849
- | Field | Type | Max Length | Description |
850
- | ----------------------- | ------ | ---------- | ------------------------------------------------ |
851
- | `transactionId` | string | 512 | Transaction ID for deduplication |
852
- | `clientId` | string | 255 | GA client ID (web stream) |
853
- | `appInstanceId` | string | | Firebase app instance ID (GA4 app stream) |
854
- | `userId` | string | 256 | First-party user ID |
855
- | `conversionValue` | number | | Conversion value |
856
- | `currency` | string | 3 | ISO 4217 currency code |
857
- | `eventName` | string | 40 | Event name (required for GA4) |
858
- | `eventSource` | string | | WEB, APP, IN_STORE, PHONE, OTHER |
859
- | `eventLocation.storeId` | string | | Physical store ID (required for IN_STORE events) |
860
- | `thirdPartyUserData` | object | | User identifiers from a data partner (typed) |
861
-
862
- ## Type Definitions
863
-
864
- See [src/types/](./src/types/) for TypeScript interfaces.
865
-
866
- ## Related
867
-
868
- - [Website Documentation](https://www.walkeros.io/docs/destinations/server/datamanager/)
869
- - [Destination Interface](../../../core/src/types/destination.ts)
870
-
871
- ## Resources
872
-
873
- - [Google Data Manager API Documentation](https://developers.google.com/data-manager/api)
874
- - [Data Formatting Guidelines](https://developers.google.com/data-manager/api/devguides/concepts/formatting)
875
- - [DMA Compliance](https://developers.google.com/data-manager/api/devguides/concepts/dma)
876
- - [walkerOS Documentation](https://www.walkeros.io/docs/)
50
+ Feel free to contribute by submitting an
51
+ [issue](https://github.com/elbwalker/walkerOS/issues), starting a
52
+ [discussion](https://github.com/elbwalker/walkerOS/discussions), or getting in
53
+ [contact](https://calendly.com/elb-alexander/30min).
877
54
 
878
55
  ## License
879
56
 
880
57
  MIT
881
-
882
- ## Support
883
-
884
- For issues and questions:
885
-
886
- - [GitHub Issues](https://github.com/elbwalker/walkerOS/issues)
887
- - [walkerOS Documentation](https://www.walkeros.io/docs/)
888
- - [Google Data Manager Support](https://developers.google.com/data-manager/api/support/contact)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/server-destination-datamanager",
4
- "version": "4.1.0-next-1778668930820",
4
+ "version": "4.1.0",
5
5
  "type": "destination",
6
6
  "platform": [
7
7
  "server"
@@ -40,7 +40,8 @@
40
40
  "client_email",
41
41
  "private_key"
42
42
  ],
43
- "additionalProperties": false
43
+ "additionalProperties": false,
44
+ "title": "credentials"
44
45
  },
45
46
  "keyFilename": {
46
47
  "description": "Path to service account JSON file. For local development or environments with filesystem access.",
@@ -154,7 +155,8 @@
154
155
  }
155
156
  },
156
157
  "additionalProperties": false,
157
- "description": "Request-level consent for all events"
158
+ "description": "Request-level consent for all events",
159
+ "title": "consent"
158
160
  },
159
161
  "testEventCode": {
160
162
  "type": "string",
@@ -215,8 +217,7 @@
215
217
  }
216
218
  },
217
219
  "required": [
218
- "destinations",
219
- "eventSource"
220
+ "destinations"
220
221
  ],
221
222
  "additionalProperties": false
222
223
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/server-destination-datamanager",
3
3
  "description": "Google Data Manager server destination for walkerOS",
4
- "version": "4.1.0-next-1778668930820",
4
+ "version": "4.1.0",
5
5
  "license": "MIT",
6
6
  "exports": {
7
7
  ".": {
@@ -22,7 +22,8 @@
22
22
  }
23
23
  },
24
24
  "files": [
25
- "dist/**"
25
+ "dist/**",
26
+ "CHANGELOG.md"
26
27
  ],
27
28
  "scripts": {
28
29
  "build": "tsup --silent",
@@ -34,12 +35,12 @@
34
35
  "update": "npx npm-check-updates -u && npm update"
35
36
  },
36
37
  "dependencies": {
37
- "@walkeros/core": "4.1.0-next-1778668930820",
38
- "@walkeros/server-core": "4.1.0-next-1778668930820",
38
+ "@walkeros/core": "4.1.0",
39
+ "@walkeros/server-core": "4.1.0",
39
40
  "google-auth-library": "^10.5.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@walkeros/collector": "4.1.0-next-1778668930820"
43
+ "@walkeros/collector": "4.1.0"
43
44
  },
44
45
  "repository": {
45
46
  "url": "git+https://github.com/elbwalker/walkerOS.git",