Segment
Server-side event delivery to Segment via the official @segment/analytics-node SDK. Implements the full Segment Spec surface (track, identify, group, page, and screen) with automatic identity deduplication and graceful shutdown via closeAndFlush().
Segment is a server destination in the walkerOS flow:
Receives events server-side from the collector, resolves identity and consent context, and forwards them to Segment for routing to 400+ downstream destinations.
Installation
npm install @walkeros/server-destination-segment- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { destinationSegment } from '@walkeros/server-destination-segment';
await startFlow({
destinations: {
segment: {
code: destinationSegment,
config: {
settings: {
writeKey: 'YOUR_SEGMENT_WRITE_KEY',
},
},
},
},
});Add to your flow.json destinations:
"destinations": {
"segment": {
"package": "@walkeros/server-destination-segment",
"config": {
"settings": {
"writeKey": "YOUR_SEGMENT_WRITE_KEY"
}
}
}
}Configuration
This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
writeKey | string | Segment source write key. Find it in your Segment workspace under Connections > Sources > Settings > API Keys. | |
userId | string | walkerOS mapping value path to resolve userId from each event (like user.id). | |
anonymousId | string | walkerOS mapping value path to resolve anonymousId from each event (like user.session). | |
host | string | Base URL of Segment API. Set to https://events.eu1.segmentapis.com for EU endpoint. | |
path | string | API path route (like /v1/batch). | |
flushAt | integer | Events to enqueue before flushing a batch. Default: 15. | |
flushInterval | integer | Max milliseconds before auto-flush. Default: 10000. | |
maxRetries | integer | Retry attempts for failed batches. Default: 3. | |
httpRequestTimeout | integer | HTTP request timeout in milliseconds. Default: 10000. | |
disable | boolean | Completely disable the SDK (no-ops all calls). Default: false. | |
identify | any | Destination-level identity mapping. Resolves to { traits } object. Fires identify() on the first push and re-fires when values change. | |
group | any | Destination-level group mapping. Resolves to { groupId, traits }. Fires group() on the first push and re-fires on change. | |
consent | Record<string, string> | Mapping from walkerOS consent keys to Segment categoryPreferences keys. Example: { "marketing": "Advertising", "analytics": "Analytics" }. | |
integrations | Record<string, any> | Enable/disable downstream Segment destinations. Example: { "All": true, "Mixpanel": false }. |
Mapping
Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
| Property | Type | Description | More |
|---|---|---|---|
identify | any | Per-event identity mapping. Resolves to { userId?, traits? }. Use with rule-level silent: true on login/identify events. | |
group | any | Per-event group assignment. Resolves to { groupId, traits? }. Use with rule-level silent: true on company/team events. | |
page | any | Per-event page call. Resolves to { category?, name?, properties? } or true for minimal page(). Use with silent: true. | |
screen | any | Per-event screen call (mobile backends). Resolves to { category?, name?, properties? } or true for minimal screen(). Use with silent: true. |
Examples
Anonymous only
When no userId is resolved Segment accepts a track call keyed solely by anonymousId.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "9f6bb791905ac38c",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000107,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {}
})Group company
A company update fires Segment analytics.group with groupId and group traits for account-level tracking.
{
"name": "company update",
"data": {
"company_id": "comp-456",
"company_name": "Acme",
"industry": "tech",
"employees": 50
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "0bec0432ab1f14a4",
"trigger": "test",
"entity": "company",
"action": "update",
"timestamp": 1700000104,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"group": {
"map": {
"groupId": "data.company_id",
"traits": {
"map": {
"name": "data.company_name",
"industry": "data.industry",
"employees": "data.employees"
}
}
}
}
}
}analytics.group({
"userId": "us3r",
"anonymousId": "s3ss10n",
"groupId": "comp-456",
"traits": {
"name": "Acme",
"industry": "tech",
"employees": 50
},
"timestamp": {}
})Consent forwarding
Walker consent keys are mapped to Segment categoryPreferences on the analytics context for downstream filtering.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"analytics": true,
"marketing": true
},
"id": "4ebcd79dd02ff62b",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000108,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {},
"context": {
"consent": {
"categoryPreferences": {
"Analytics": true,
"Advertising": true
}
}
}
})Default track
A walker event becomes a Segment analytics.track call with userId and anonymousId resolved from the event.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "3dea2dc6859dad63",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000100,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {}
})Destination identify
Destination-level identify fires Segment analytics.identify with traits on the first push only, then the track call follows.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n",
"email": "user@example.com"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "fa6bb2fc20d5e931",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000102,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.identify({
"userId": "us3r",
"anonymousId": "s3ss10n",
"traits": {
"email": "user@example.com"
},
"timestamp": {}
});
analytics.track({
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "page view",
"properties": {},
"timestamp": {}
})Renamed event
A mapping renames the event so the Segment track call uses Segment's canonical 'Order Completed' name.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "560aab471377af49",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000101,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "Order Completed"
}analytics.track({
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "Order Completed",
"properties": {},
"timestamp": {}
})Page view
A page view fires Segment analytics.page with category, name, and properties instead of a generic track.
{
"name": "page view",
"data": {
"category": "docs",
"title": "Getting Started",
"section": "tutorials"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "2f9a5e93cd84574d",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000105,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"page": {
"map": {
"category": "data.category",
"name": "data.title",
"properties": {
"map": {
"section": "data.section"
}
}
}
}
}
}analytics.page({
"userId": "us3r",
"anonymousId": "s3ss10n",
"category": "docs",
"name": "Getting Started",
"properties": {
"section": "tutorials"
},
"timestamp": {}
})Screen view
A screen view fires Segment analytics.screen with name, category, and properties for mobile app tracking.
{
"name": "screen view",
"data": {
"screen_name": "Welcome",
"section": "onboarding",
"build": "1.2.3"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "e613433c43fcb3fd",
"trigger": "test",
"entity": "screen",
"action": "view",
"timestamp": 1700000106,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"screen": {
"map": {
"name": "data.screen_name",
"category": "data.section",
"properties": {
"map": {
"build": "data.build"
}
}
}
}
}
}analytics.screen({
"userId": "us3r",
"anonymousId": "s3ss10n",
"name": "Welcome",
"category": "onboarding",
"properties": {
"build": "1.2.3"
},
"timestamp": {}
})User login identify
A user login fires only Segment analytics.identify with the userId and traits, skipping the track.
{
"name": "user login",
"data": {
"user_id": "new-user-123",
"email": "user@acme.com",
"name": "Jane Doe",
"plan": "premium"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "4528ec6ae0b1875e",
"trigger": "test",
"entity": "user",
"action": "login",
"timestamp": 1700000103,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"identify": {
"map": {
"userId": "data.user_id",
"traits": {
"map": {
"email": "data.email",
"name": "data.name",
"plan": "data.plan"
}
}
}
}
}
}analytics.identify({
"userId": "new-user-123",
"anonymousId": "s3ss10n",
"traits": {
"email": "user@acme.com",
"name": "Jane Doe",
"plan": "premium"
},
"timestamp": {}
})Identity is resolved automatically from each event: userId defaults to user.id and anonymousId defaults to user.session. At least one must be present for a call to be sent. Override these paths in settings to match your event structure.