@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 +305 -0
- package/README.md +34 -865
- package/dist/walkerOS.json +6 -5
- package/package.json +6 -5
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
+
•
|
|
14
|
+
[NPM Package](https://www.npmjs.com/package/@walkeros/server-destination-datamanager)
|
|
15
|
+
•
|
|
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
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
711
|
-
|
|
712
|
-
|
|
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)
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-datamanager",
|
|
4
|
-
"version": "4.1.0
|
|
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
|
|
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
|
|
38
|
-
"@walkeros/server-core": "4.1.0
|
|
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
|
|
43
|
+
"@walkeros/collector": "4.1.0"
|
|
43
44
|
},
|
|
44
45
|
"repository": {
|
|
45
46
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|