Segment Integration
This is a Lambda function that runs on Segment for ABsmartly Integration.
It extracts the relevant data from Segment events and sends it, correctly formatted, to the ABsmartly Collector endpoint.
It can also be added directly as a destination function on a Segment workspace.
Configuring a Workspace Destination Function
If you are configuring a destination function on your workspace, these are the necessary settings:
Collector Endpoint
- Type: String
- Required: ✅
- Javascript:
settings.collectorEndpoint
Your dedicated ABsmartly Collector Endpoint. Example: https://demo.absmartly.io/v1
API Key
- Type: String
- Required: ✅
- Javascript:
settings.apiKey
API Key to use when sending events to the ABsmartly Collector. API Keys are created in the ABsmartly Web Console's Settings section.
Environment
- Type: String
- Required: ✅
- Javascript:
settings.environment
The environment name where the events are originating (case sensitive). Environments are created in the ABsmartly Web Console's Settings section.
Unit Mapping
- Type: Mapping
- Required: ✅
- Javascript:
settings.unitMapping
Mapping of Segment identity to ABsmartly Unit. Mapping of Segment identity
to ABsmartly Unit. Example anonymousId
-> anonymous_uuid
, userId
->
user_id
. Units are created in the ABsmartly Web Console's Settings section.
This mapping is required, even if the names are exactly the same.
EnableExposureTracking
- Type: Boolean
- Required: ❌
- Javascript:
settings.enableExposureTracking
Enable sending ABsmartly exposures to the ABsmartly Collector.
Enable this only if you instantiate the ABsmartly SDK with a custom publisher and are sending ABsmartly exposures through Segment.
EnablePageViewTracking
- Type: Boolean
- Required: ❌
- Javascript:
settings.enablePageViewTracking
Enable sending Segment's Page events as goals to the ABsmartly Collector.
These events tend to happen very frequently and may increase storage cost.
The goal generated will have the name Page: <Page Name>
for example
Page: Home
and needs to have been previously created in
the ABsmartly Web Console's Settings section.
EnableAppScreenViewTracking
- Type: Boolean
- Required: ❌
- Javascript:
settings.enableAppScreenViewTracking
Enable sending Segment's Screen events as goals to the ABsmartly Collector.
These events tend to happen very frequently and may increase storage cost.
The goal generated will have the name Screen: <Screen Name>
for example
Screen: Login
and needs to have been previously created in the ABsmartly
Web Console's Settings section.
Goal Mapping
- Type: Mapping
- Required: ❌
- Javascript:
settings.goalMapping
Mapping of Segment event names to ABsmartly goal names. If a mapping exists, it will be used, otherwise the original event name will be used as the goal name.
Advanced Usage
Sending experiment exposures to Segment
It can be useful to send experiment exposures to Segment for visibility from
other destinations. The Segment spec includes the Experiment Viewed
semantic event
for this purpose.
In the ABsmartly context, we can install a custom event logger and send exposures directly to Segment.
analytics.ready(function () {
// initialize ABSmartly SDK
const sdk = new absmartly.SDK({
endpoint: "https://your-absmartly-endpoint.absmartly.io/v1",
apiKey: "<YOUR-API-KEY>",
environment: "development",
application: "YOUR-APP",
eventLogger: (context, eventName, data) => {
if (eventName == "exposure") {
// filter only relevant and interesting exposures
// if the assigned flag is false, this exposure was a treatment call that did not result in an assignment
// this can happen if, for example, the experiment is no longer running, but treatment() calls are still in the application code
if (exposure.assigned) {
analytics.track("Experiment Viewed", {
experiment_id: exposure.id,
experiment_name: exposure.name,
variation_id: exposure.variant,
variation_name: "ABCDEFG"[exposure.variant],
});
}
}
},
});
const context = sdk.createContext(request);
context.attribute("user_agent", navigator.userAgent);
context
.ready()
.then((response) => {
console.log("ABSmartly Context ready!");
console.log(context.treatment("test-exp"));
})
.catch((error) => {
console.log(error);
});
});
Mapping Segment Identities to ABsmartly Units
For simple mappings, you can map Segment's identities/properties to ABsmartly's units in your ABsmartly integration settings in Segment.
If you want to programmatically make this mapping, you can install a
middleware in your Segment SDK that will append the units to the
properties.absmartly.units
field before sending to Segment.
The destination function will extract and use that instead. This may be
useful if you are running ABsmartly experiment on units that are not
the typical Segment anonymousId
or userId
.
// example absmartly middle to enrich segment track, page and screen events with relevant
analytics.ready(function () {
// absmartly units - useful if you want to run experiments on units that are not your segment users
const absmartlyMiddleware = function ({ payload, next, integrations }) {
const type = payload.obj.type;
switch (type) {
case "track":
case "page":
case "screen":
const event = payload.obj;
const props = event.properties;
const units = [];
// always send the current user's units
const anonymousId =
"anonymousId" in event
? event["anonymousId"]
: analytics.user().anonymousId();
units.push({ type: "anonymousId", uid: anonymousId });
// additionally, if we have any other units, add them
if (event.userId) {
units.push({ type: "userId", uid: event.userId });
}
// add any additional product units from properties, for example, when running product experiments
// event will also be assigned to these units in absmartly
if (props.productId) {
units.push({ type: "productId", uid: props.productId });
}
if (props.products) {
for (const product of props.products) {
units.push({ type: "productId", uid: product.productId });
}
}
props["absmartly"] = { units };
break;
default:
break;
}
next(payload);
};
// add it as middleware
analytics.addSourceMiddleware(absmartlyMiddleware);
});
Publishing Experiment Exposures Through Segment
To publish experiment exposures, you must turn on EnableExposureTracking
in your destination settings in Segment.
We want to replace the direct flow of exposure events from the ABsmartly SDK to the ABsmartly collector, by instead sending them to Segment for processing by the destination function.
This can be achieved by instantiating the ABsmartly SDK with a custom context publisher.
The custom publisher will publish an Experiment Viewed
Segment event
with ABsmartly's exposure data in the properties.absmartly
field as well
as the normal semantic data that Segment recommends for this event.
Here is an example in Javascript.
analytics.ready(function () {
// initialize ABSmartly SDK
const sdk = new absmartly.SDK({
endpoint: "https://your-absmartly-endpoint.absmartly.io/v1",
apiKey: "<YOUR-API-KEY>",
environment: "development",
application: "YOUR-APP",
});
// ABSmartly publisher implementation that publishes ABSmartly exposures to Segment,
// instead of directly to the ABSmartly Collector
// these will then be pushed by the ABSmartly segment integration to the ABSmartly collector
class SegmentContextPublisher extends absmartly.ContextPublisher {
constructor(segment) {
super();
this._segment = segment;
}
publish(request, sdk, context) {
// NOTE: only exposures are expected to come via this route
// other types of events should be tracked through the Segment API
if (request.exposures) {
for (const exposure of request.exposures) {
this._segment.track(`Experiment Viewed`, {
experiment_id: exposure.id,
experiment_name: exposure.name,
variation_id: exposure.variant,
variation_name: "ABCDEFG"[exposure.variant],
absmartly: Object.assign(
{},
{
exposures: [exposure],
},
// add anything else in the ABsmartly payload that are not exposures or goals
...Object.entries(request)
.filter((e) => e[0] !== "exposures" && e[0] !== "goals")
.map((e) => ({ [e[0]]: e[1] }))
),
});
}
}
return Promise.resolve();
}
}
// set this as the default publisher - all contexts created from now on will use it by default
sdk.setContextPublisher(new SegmentContextPublisher(analytics));
const request = {
units: {
userId: analytics.user().id(),
anonymousId: analytics.user().anonymousId(),
},
};
window.context = sdk.createContext(request);
context.attribute("user_agent", navigator.userAgent);
context
.ready()
.then((response) => {
console.log("ABSmartly Context ready!");
console.log(context.treatment("test-exp"));
})
.catch((error) => {
console.log(error);
});
});
Finishing Up
You should now have your ABsmartly Segment integration fully set up!
If you are looking for more information, feel free to ask a question in your organization's dedicated ABsmartly Slack channel.