Skip to main content

Segment

Server Source code Package

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().

Where this fits

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
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',
      },
    },
  },
},
});

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

PropertyTypeDescriptionMore
writeKey*stringSegment source write key. Find it in your Segment workspace under Connections > Sources > Settings > API Keys.
userIdstringwalkerOS mapping value path to resolve userId from each event (like user.id).
anonymousIdstringwalkerOS mapping value path to resolve anonymousId from each event (like user.session).
hoststringBase URL of Segment API. Set to https://events.eu1.segmentapis.com for EU endpoint.
pathstringAPI path route (like /v1/batch).
flushAtintegerEvents to enqueue before flushing a batch. Default: 15.
flushIntervalintegerMax milliseconds before auto-flush. Default: 10000.
maxRetriesintegerRetry attempts for failed batches. Default: 3.
httpRequestTimeoutintegerHTTP request timeout in milliseconds. Default: 10000.
disablebooleanCompletely disable the SDK (no-ops all calls). Default: false.
identifyanyDestination-level identity mapping. Resolves to { traits } object. Fires identify() on the first push and re-fires when values change.
groupanyDestination-level group mapping. Resolves to { groupId, traits }. Fires group() on the first push and re-fires on change.
consentRecord<string, string>Mapping from walkerOS consent keys to Segment categoryPreferences keys. Example: { "marketing": "Advertising", "analytics": "Analytics" }.
integrationsRecord<string, any>Enable/disable downstream Segment destinations. Example: { "All": true, "Mixpanel": false }.
* Required fields

Mapping

Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.

PropertyTypeDescriptionMore
identifyanyPer-event identity mapping. Resolves to { userId?, traits? }. Use with rule-level silent: true on login/identify events.
groupanyPer-event group assignment. Resolves to { groupId, traits? }. Use with rule-level silent: true on company/team events.
pageanyPer-event page call. Resolves to { category?, name?, properties? } or true for minimal page(). Use with silent: true.
screenanyPer-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.

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": {
    "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"
  }
}
Out
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.

Event
{
  "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"
  }
}
Mapping
{
  "silent": true,
  "settings": {
    "group": {
      "map": {
        "groupId": "data.company_id",
        "traits": {
          "map": {
            "name": "data.company_name",
            "industry": "data.industry",
            "employees": "data.employees"
          }
        }
      }
    }
  }
}
Out
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.

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": {
    "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"
  }
}
Out
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.

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"
  }
}
Out
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.

Event
{
  "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"
  }
}
Out
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.

Event
{
  "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"
  }
}
Mapping
{
  "name": "Order Completed"
}
Out
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.

Event
{
  "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"
  }
}
Mapping
{
  "silent": true,
  "settings": {
    "page": {
      "map": {
        "category": "data.category",
        "name": "data.title",
        "properties": {
          "map": {
            "section": "data.section"
          }
        }
      }
    }
  }
}
Out
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.

Event
{
  "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"
  }
}
Mapping
{
  "silent": true,
  "settings": {
    "screen": {
      "map": {
        "name": "data.screen_name",
        "category": "data.section",
        "properties": {
          "map": {
            "build": "data.build"
          }
        }
      }
    }
  }
}
Out
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.

Event
{
  "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"
  }
}
Mapping
{
  "silent": true,
  "settings": {
    "identify": {
      "map": {
        "userId": "data.user_id",
        "traits": {
          "map": {
            "email": "data.email",
            "name": "data.name",
            "plan": "data.plan"
          }
        }
      }
    }
  }
}
Out
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.

💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)