|
| 1 | +--- |
| 2 | +title: ABsmartly (Actions) Destination |
| 3 | +id: 64f703d1f6e9aa0a283ae3e2 |
| 4 | +beta: true |
| 5 | +private: true |
| 6 | +--- |
| 7 | + |
| 8 | +{% include content/plan-grid.md name="actions" %} |
| 9 | + |
| 10 | +[ABsmartly](https://absmartly.com/?utm_source=segmentio&utm_medium=docs&utm_campaign=partners){:target="_blank"} provides an on-premise, full-stack experimentation platform for engineering and product teams that do continuous experimentation embedded into their development process. ABsmartly's real-time analytics help engineering and product teams ensure that new features will improve the customer experience without breaking or degrading performance and/or business metrics. |
| 11 | + |
| 12 | +This destination is maintained by ABsmartly. For any issues with the destination, [contact ABsmartly's Support ](mailto:[email protected]). |
| 13 | + |
| 14 | +## Benefits of ABsmartly (Actions) vs ABsmartly Classic |
| 15 | + |
| 16 | +- **Easier Setup**: Actions-based destinations are easier to configure with clear default settings, letting you quickly get started. |
| 17 | +- **Control and clearer mapping**: Actions-based destinations enable you to define the mapping between the data Segment receives from your source and the data Segment sends to ABsmartly. |
| 18 | + |
| 19 | +## Getting started |
| 20 | + |
| 21 | +1. From the Segment web app, click **Catalog**. |
| 22 | +2. Search for "ABsmartly" in the Catalog, select **ABsmartly (Actions)**, and choose which of your sources to connect the destination to. |
| 23 | +3. Add the following Connection Settings: |
| 24 | + - **Collector Endpoint**: Your ABsmartly Collector REST Endpoint. Usually `https://<your-subdomain>.absmartly.io/v1` |
| 25 | + - **API Key**: An existing API Key. Created under Settings > API Keys in the ABsmartly Web Console. |
| 26 | + - **Environment**: The environment where the events are originated matching an existing environment in ABsmartly. Created under Settings > Environments in the ABsmartly Web Console. |
| 27 | +5. Enable the _Track Calls_ mapping to send events to ABsmartly. |
| 28 | + |
| 29 | +{% include components/actions-fields.html %} |
| 30 | + |
| 31 | +> info "" |
| 32 | +> If you need support setting things up, you can contact the ABsmartly support team on Slack or [via email](mailto:[email protected]). |
| 33 | +
|
| 34 | +# Sending exposures to Segment |
| 35 | + |
| 36 | +It can be useful to send experiment exposures to Segment for visibility from |
| 37 | +other destinations. The Segment Spec includes the [Experiment Viewed semantic event](/docs/connections/spec/ab-testing/) |
| 38 | +for this purpose. |
| 39 | + |
| 40 | +> info "" |
| 41 | +> By default, the _Track Calls_ mapping will filter and not send any events with the name `Experiment Viewed` to ABsmartly. |
| 42 | +
|
| 43 | +You can [install a custom event logger](https://docs.absmartly.com/docs/sdk%20documentation/getting-started/#using-a-custom-event-logger){:target="_blank"} in ABsmartly and send exposures directly to Segment. |
| 44 | + |
| 45 | +```javascript |
| 46 | +analytics.ready(function() { |
| 47 | + // initialize ABsmartly SDK |
| 48 | + const sdk = new absmartly.SDK({ |
| 49 | + endpoint: 'https://your-absmartly-endpoint.absmartly.io/v1', |
| 50 | + apiKey: '<YOUR-API-KEY>', |
| 51 | + environment: 'development', |
| 52 | + application: 'YOUR-APP', |
| 53 | + eventLogger: (context, eventName, data) => { |
| 54 | + if (eventName == "exposure") { |
| 55 | + // filter only relevant and interesting exposures |
| 56 | + // if the assigned flag is false, this exposure was a treatment call that did not result in an assignment |
| 57 | + // this can happen if, for example, the experiment is no longer running, but treatment() calls are still in the application code |
| 58 | + if (exposure.assigned) { |
| 59 | + analytics.track("Experiment Viewed", { |
| 60 | + experiment_id: exposure.id, |
| 61 | + experiment_name: exposure.name, |
| 62 | + variation_id: exposure.variant, |
| 63 | + variation_name: "ABCDEFG"[exposure.variant], |
| 64 | + }); |
| 65 | + } |
| 66 | + } |
| 67 | + }, |
| 68 | + }); |
| 69 | + |
| 70 | + const context = sdk.createContext(request); |
| 71 | + context.attribute("user_agent", navigator.userAgent); |
| 72 | + |
| 73 | + context.ready().then((response) => { |
| 74 | + console.log("ABSmartly Context ready!"); |
| 75 | + console.log(context.treatment("test-exp")); |
| 76 | + }).catch((error) => { |
| 77 | + console.log(error); |
| 78 | + }); |
| 79 | +}); |
| 80 | +``` |
| 81 | + |
| 82 | +### Publishing experiment exposures through Segment |
| 83 | + |
| 84 | +To publish experiment exposures through Segment, you must first configure |
| 85 | +and enable the _Exposures (Verbatim)_ mapping in your ABsmartly (Actions) destination. |
| 86 | + |
| 87 | +By enabling the _Exposures (Verbatim)_ mapping in Segment, you replace the direct flow of exposure events from the ABsmartly SDK to the ABsmartly collector and instead send them to Segment |
| 88 | +for processing by the destination function. |
| 89 | + |
| 90 | +This can be achieved by instantiating the ABsmartly SDK with a custom context publisher. |
| 91 | + |
| 92 | +The custom publisher will publish an `Experiment Viewed` Segment event with ABsmartly's exposure data in the `properties.exposure` field as well |
| 93 | +as the normal semantic data that Segment recommends for this event. |
| 94 | + |
| 95 | +Here is an example in Javascript. |
| 96 | + |
| 97 | +```javascript |
| 98 | +analytics.ready(function() { |
| 99 | + // initialize ABSmartly SDK |
| 100 | + const sdk = new absmartly.SDK({ |
| 101 | + endpoint: 'https://your-absmartly-endpoint.absmartly.io/v1', |
| 102 | + apiKey: '<YOUR-API-KEY>', |
| 103 | + environment: 'development', |
| 104 | + application: 'YOUR-APP', |
| 105 | + }); |
| 106 | + |
| 107 | + // ABSmartly publisher implementation that publishes ABSmartly exposures to Segment, |
| 108 | + // instead of directly to the ABSmartly Collector |
| 109 | + // these will then be pushed by the ABSmartly segment integration to the ABSmartly collector |
| 110 | + class SegmentContextPublisher extends absmartly.ContextPublisher { |
| 111 | + constructor(segment) { |
| 112 | + super(); |
| 113 | + |
| 114 | + this._segment = segment; |
| 115 | + } |
| 116 | + |
| 117 | + publish(request, sdk, context) { |
| 118 | + // NOTE: only exposures are expected to come via this route |
| 119 | + // other types of events should be tracked through the Segment API |
| 120 | + if (request.exposures) { |
| 121 | + for (const exposure of request.exposures) { |
| 122 | + this._segment.track(`Experiment Viewed`, { |
| 123 | + experiment_id: exposure.id, |
| 124 | + experiment_name: exposure.name, |
| 125 | + variation_id: exposure.variant, |
| 126 | + variation_name: "ABCDEFG"[exposure.variant], |
| 127 | + exposure: Object.assign({}, |
| 128 | + { |
| 129 | + exposures: [exposure], |
| 130 | + }, |
| 131 | + // add anything else in the a/b smartly payload that are not exposures or goals |
| 132 | + ...Object.entries(request) |
| 133 | + .filter(e => (e[0] !== 'exposures') && (e[0] !== 'goals')) |
| 134 | + .map(e => ({[e[0]]: e[1]})) |
| 135 | + ) |
| 136 | + }); |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + return Promise.resolve(); |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + // set this as the default publisher - all contexts created from now on will use it by default |
| 145 | + sdk.setContextPublisher(new SegmentContextPublisher(analytics)); |
| 146 | + |
| 147 | + const request = { |
| 148 | + units: { |
| 149 | + userId: analytics.user().id(), |
| 150 | + anonymousId: analytics.user().anonymousId(), |
| 151 | + }, |
| 152 | + }; |
| 153 | + |
| 154 | + window.context = sdk.createContext(request); |
| 155 | + context.attribute("user_agent", navigator.userAgent); |
| 156 | + |
| 157 | + context.ready().then((response) => { |
| 158 | + console.log("ABSmartly Context ready!"); |
| 159 | + console.log(context.treatment("test-exp")); |
| 160 | + }).catch((error) => { |
| 161 | + console.log(error); |
| 162 | + }); |
| 163 | +}); |
| 164 | +``` |
| 165 | + |
| 166 | + |
| 167 | +## Migration from the classic ABsmartly destination |
| 168 | + |
| 169 | +To migrate from the classic ABsmartly destination to ABsmartly (Actions), disconnect the classic ABsmartly destination before enabling the ABsmartly (Actions) destination to avoid duplicate experimentation events. |
| 170 | + |
| 171 | +--- |
| 172 | + |
0 commit comments