Skill v1.0.1
currentAutomated scan100/1003 files
version: "1.0.1" name: walkeros-mapping-configuration description: Use when configuring walkerOS event mappings for specific use cases. Provides recipes for GA4, Meta, custom APIs, and common transformation patterns.
Mapping Configuration Recipes
Prerequisites
Read understanding-mapping first for core concepts.
Quick Reference
| I want to... | Use this pattern | |
|---|---|---|
| Rename event | { name: 'new_name' } | |
| Extract nested value | 'data.nested.value' | |
| Set static value | { value: 'USD' } | |
| Transform value | { fn: (e) => transform(e) } | |
| Build object | { map: { key: 'source' } } | |
| Process array | { loop: ['source', { map: {...} }] } | |
| Gate by consent | { key: 'data.email', consent: { marketing: true } } | |
| First defined value (fallback) | [{ key: 'data.sku' }, { key: 'data.id' }] | |
| Add a field to a default rule | { extend: { data: { map: { x: 'path' } } } } | |
| Drop a field from output | { remove: ['field.path'] } |
Common Recipes
GA4 / gtag
Product view → view_item:
product: {view: {name: 'view_item',data: {map: {currency: { value: 'USD' },value: 'data.price',items: {loop: ['nested',{map: {item_id: 'data.id',item_name: 'data.name',item_category: 'data.category',price: 'data.price',quantity: { value: 1 },},},],},},},},}
Order complete → purchase:
order: {complete: {name: 'purchase',data: {map: {transaction_id: 'data.orderId',value: 'data.total',currency: 'data.currency',items: {loop: ['nested',{map: {item_id: 'data.id',item_name: 'data.name',price: 'data.price',quantity: 'data.quantity',},},],},},},},}
Meta Pixel
Product view → ViewContent:
product: {view: {name: 'ViewContent',data: {map: {content_ids: { fn: (e) => [e.data.id] },content_type: { value: 'product' },content_name: 'data.name',value: 'data.price',currency: { value: 'USD' },},},},}
Order complete → Purchase:
order: {complete: {name: 'Purchase',data: {map: {content_ids: { fn: (e) => e.nested?.map((n) => n.data.id) ?? [] },content_type: { value: 'product' },value: 'data.total',currency: 'data.currency',num_items: { fn: (e) => e.nested?.length ?? 0 },},},},}
Custom API Destination
Transform to REST API format:
'*': {'*': {name: { fn: (e) => `${e.entity}_${e.action}` }, // page_viewdata: {map: {eventName: 'name',eventData: 'data',userId: 'user.id',sessionId: 'user.session',timestamp: 'timestamp',metadata: {map: {consent: 'consent',globals: 'globals',},},},},},}
Conditional Mapping
Different mapping based on event data:
order: {complete: [// High-value orders get extra tracking{condition: (e) => (e.data?.total ?? 0) > 500,name: 'high_value_purchase',data: {map: {value: 'data.total',priority: { value: 'high' },notify: { value: true },},},},// Standard orders{name: 'purchase',data: { map: { value: 'data.total' } },},],}
Patching Package-Shipped Rules (extend / remove)
Some packages (such as @walkeros/transformer-ga4) ship default mapping rules. Normally a user rule at the same key replaces the default in full. Use extend or remove to patch instead.
Two layers, two keywords:
- `extend` runs at init (config layer): deep-merges a partial rule onto the
shipped default. A null value clears an inherited field.
- `remove` runs after evaluation (output layer): strips dotted paths from
the final data payload. Applied last, always wins.
A rule with neither keyword keeps the existing replace behavior.
{"purchase": {"extend": {"data": { "map": { "affiliation": "params.ep.affiliation" } }},"remove": ["currency"]}}
This keeps all fields the package ships for purchase, adds affiliation, and strips currency from the output.
For the full reference and the two-layer model, see Mapping.Rule docs.
Value[] Fallback Chains
At any value position, an array of values is a fallback chain: the first entry that resolves to a defined value wins.
{"item_id": [{ "key": "data.sku" },{ "key": "data.id" },{ "value": "unknown" }]}
Use this to try multiple source fields before falling back to a constant.
Consent-Gated Fields
Only include PII if consent granted:
user: {login: {name: 'login',data: {map: {method: 'data.method',// Only include email if marketing consentemail: {key: 'user.email',consent: { marketing: true },},// Only include user ID if functional consentuserId: {key: 'user.id',consent: { functional: true },},},},},}
Wildcard Patterns
Catch-all for unmatched events:
// Any product actionproduct: {'*': {name: { fn: (e) => `product_${e.action}` },data: 'data',},}// Any click on any entity'*': {click: {name: 'element_click',data: {map: {element_type: 'entity',element_id: 'data.id',},},},}
Source-Side Mapping
Transform HTTP input to walkerOS event:
// In source config{mapping: {// Map incoming field names to walkerOS structurename: { fn: (input) => `${input.entity} ${input.action}` },data: 'payload',user: {map: {id: 'userId',session: 'sessionId',},},},}
Debugging Tips
- Event not mapping? Check entity/action match exactly (case-sensitive)
- Data missing? Verify source path exists:
'data.nested.field' - Function errors? Add null checks:
e.data?.price ?? 0 - Array empty? Confirm
nestedarray exists and has items
Related Skills
Core mapping concepts
Reference:
Implementation
- apps/quickstart/src/ - Validated examples