Skip to content

Commit a4c1024

Browse files
oakbanimikeproeng37
authored andcommitted
New Event Builder Payload With Numeric Event Support (#59)
1 parent ef63e2a commit a4c1024

File tree

6 files changed

+909
-402
lines changed

6 files changed

+909
-402
lines changed

src/Optimizely/Event/Builder/EventBuilder.php

Lines changed: 117 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Optimizely\Event\LogEvent;
2323
use Optimizely\ProjectConfig;
2424
use Optimizely\Utils\EventTagUtils;
25+
use Optimizely\Utils\GeneratorUtils;
2526

2627
define("RESERVED_ATTRIBUTE_KEY_BUCKETING_ID_EVENT_PARAM_KEY", "optimizely_bucketing_id");
2728

@@ -38,14 +39,9 @@ class EventBuilder
3839
const SDK_VERSION = '1.2.0';
3940

4041
/**
41-
* @var string URL to send impression event to.
42+
* @var string URL to send event to.
4243
*/
43-
private static $IMPRESSION_ENDPOINT = 'https://logx.optimizely.com/log/decision';
44-
45-
/**
46-
* @var string URL to send conversion event to.
47-
*/
48-
private static $CONVERSION_ENDPOINT = 'https://logx.optimizely.com/log/event';
44+
private static $ENDPOINT = 'https://logx.optimizely.com/v1/events';
4945

5046
/**
5147
* @var string HTTP method to be used when making call to log endpoint.
@@ -60,147 +56,151 @@ class EventBuilder
6056
];
6157

6258
/**
63-
* @var array Associative array of parameters to be sent for the event.
64-
*/
65-
private $_eventParams;
66-
67-
/**
68-
* Helper function to reset event params.
69-
*/
70-
private function resetParams()
71-
{
72-
$this->_eventParams = [];
73-
}
74-
75-
/**
76-
* @return array Params for the event.
77-
*/
78-
private function getParams()
79-
{
80-
return $this->_eventParams;
81-
}
82-
83-
/**
84-
* Helper function to set parameters common to impression and conversion event.
59+
* Helper function to get parameters common to impression and conversion events.
8560
*
8661
* @param $config ProjectConfig Configuration for the project.
8762
* @param $userId string ID of user.
8863
* @param $attributes array Attributes of the user.
8964
*/
90-
private function setCommonParams($config, $userId, $attributes)
65+
private function getCommonParams($config, $userId, $attributes)
9166
{
92-
$this->_eventParams[PROJECT_ID] = $config->getProjectId();
93-
$this->_eventParams[ACCOUNT_ID] = $config->getAccountId();
94-
$this->_eventParams[REVISION] = $config->getRevision();
95-
$this->_eventParams[VISITOR_ID] = $userId;
96-
$this->_eventParams[CLIENT_ENGINE] = self::SDK_TYPE;
97-
$this->_eventParams[CLIENT_VERSION] = self::SDK_VERSION;
98-
$this->_eventParams[USER_FEATURES] = [];
99-
$this->_eventParams[IS_GLOBAL_HOLDBACK] = false;
100-
$this->_eventParams[TIME] = time()*1000;
101-
if (!isset($attributes)) {
102-
$attributes = [];
103-
}
67+
$visitor = [
68+
SNAPSHOTS=> [],
69+
VISITOR_ID => $userId,
70+
ATTRIBUTES => []
71+
];
10472

105-
forEach ($attributes as $attributeKey => $attributeValue) {
106-
if ($attributeValue) {
73+
$commonParams = [
74+
ACCOUNT_ID => $config->getAccountId(),
75+
PROJECT_ID => $config->getProjectId(),
76+
VISITORS => [$visitor],
77+
REVISION => $config->getRevision(),
78+
CLIENT_ENGINE => self::SDK_TYPE,
79+
CLIENT_VERSION => self::SDK_VERSION
80+
];
81+
82+
if(is_null($attributes))
83+
return $commonParams;
84+
85+
foreach($attributes as $attributeKey => $attributeValue) {
86+
$feature = [];
87+
// Do not discard attribute if value is zero or false
88+
if (!is_null($attributeValue)) {
10789
// check for reserved attributes
10890
if (strcmp($attributeKey , RESERVED_ATTRIBUTE_KEY_BUCKETING_ID) == 0) {
10991
// TODO (Alda): the type for bucketing ID attribute may change so that custom
11092
// attributes are not overloaded
111-
array_push($this->_eventParams[USER_FEATURES], [
112-
'name' => RESERVED_ATTRIBUTE_KEY_BUCKETING_ID_EVENT_PARAM_KEY,
113-
'type' => 'custom',
114-
'value' => $attributeValue,
115-
'shouldIndex' => true
116-
]);
93+
$feature = [
94+
ENTITY_ID => RESERVED_ATTRIBUTE_KEY_BUCKETING_ID,
95+
KEY => RESERVED_ATTRIBUTE_KEY_BUCKETING_ID_EVENT_PARAM_KEY,
96+
TYPE => CUSTOM_ATTRIBUTE_FEATURE_TYPE,
97+
VALUE => $attributeValue
98+
];
99+
117100
} else {
118101
$attributeEntity = $config->getAttribute($attributeKey);
119102
if (!is_null($attributeEntity->getKey())) {
120-
array_push($this->_eventParams[USER_FEATURES], [
121-
'id' => $attributeEntity->getId(),
122-
'name' => $attributeKey,
123-
'type' => 'custom',
124-
'value' => $attributeValue,
125-
'shouldIndex' => true
126-
]);
103+
$feature = [
104+
ENTITY_ID => $attributeEntity->getId(),
105+
KEY => $attributeKey,
106+
TYPE => CUSTOM_ATTRIBUTE_FEATURE_TYPE,
107+
VALUE => $attributeValue,
108+
];
127109
}
128110
}
129111
}
112+
113+
if(!empty($feature))
114+
$commonParams[VISITORS][0][ATTRIBUTES][] = $feature;
130115
}
116+
117+
return $commonParams;
131118
}
132119

133120
/**
134-
* Helper function to set parameters specific to impression event.
121+
* Helper function to get parameters specific to impression event.
135122
*
136123
* @param $experiment Experiment Experiment being activated.
137124
* @param $variationId string
138125
*/
139-
private function setImpressionParams(Experiment $experiment, $variationId)
126+
private function getImpressionParams(Experiment $experiment, $variationId)
140127
{
141-
$this->_eventParams[LAYER_ID] = $experiment->getLayerId();
142-
$this->_eventParams[DECISION] = [
143-
EXPERIMENT_ID => $experiment->getId(),
144-
VARIATION_ID => $variationId,
145-
IS_LAYER_HOLDBACK => false
128+
$impressionParams = [
129+
DECISIONS => [
130+
[
131+
CAMPAIGN_ID => $experiment->getLayerId(),
132+
EXPERIMENT_ID => $experiment->getId(),
133+
VARIATION_ID => $variationId
134+
]
135+
],
136+
137+
EVENTS => [
138+
[
139+
ENTITY_ID => $experiment->getLayerId(),
140+
TIMESTAMP => time()*1000,
141+
KEY => ACTIVATE_EVENT_KEY,
142+
UUID => GeneratorUtils::getRandomUuid()
143+
]
144+
]
145+
146146
];
147+
148+
return $impressionParams;
147149
}
148150

149151
/**
150-
* Helper function to set parameters specific to conversion event.
152+
* Helper function to get parameters specific to conversion event.
151153
*
152154
* @param $config ProjectConfig Configuration for the project.
153155
* @param $eventKey string Key representing the event.
154156
* @param $experimentVariationMap array Map of experiment ID to the ID of the variation that the user is bucketed into.
155157
* @param $userId string ID of user.
156158
* @param $eventTags array Hash representing metadata associated with the event.
157159
*/
158-
private function setConversionParams($config, $eventKey, $experimentVariationMap, $userId, $eventTags)
160+
private function getConversionParams($config, $eventKey, $experimentVariationMap, $userId, $eventTags)
159161
{
160-
$this->_eventParams[EVENT_FEATURES] = [];
161-
$this->_eventParams[EVENT_METRICS] = [];
162-
163-
if (!is_null($eventTags)) {
164-
forEach ($eventTags as $eventTagId => $eventTagValue) {
165-
if (is_null($eventTagValue)) {
166-
continue;
167-
}
168-
$eventFeature = array(
169-
'name' => $eventTagId,
170-
'type' => 'custom',
171-
'value' => $eventTagValue,
172-
'shouldIndex' => false,
173-
);
174-
array_push($this->_eventParams[EVENT_FEATURES], $eventFeature);
175-
}
176-
$eventValue = EventTagUtils::getRevenueValue($eventTags);
177-
if ($eventValue) {
178-
$eventMetric = array(
179-
'name' => EventTagUtils::REVENUE_EVENT_METRIC_NAME,
180-
'value' => $eventValue,
181-
);
182-
array_push($this->_eventParams[EVENT_METRICS], $eventMetric);
183-
}
184-
}
185162

186-
$eventEntity = $config->getEvent($eventKey);
187-
$this->_eventParams[EVENT_ID] = $eventEntity->getId();
188-
$this->_eventParams[EVENT_NAME] = $eventKey;
189-
190-
$this->_eventParams[LAYER_STATES] = [];
191-
forEach ($experimentVariationMap as $experimentId => $variationId) {
163+
$conversionParams = [];
164+
foreach($experimentVariationMap as $experimentId => $variationId){
165+
$singleSnapshot = [];
192166
$experiment = $config->getExperimentFromId($experimentId);
193-
array_push($this->_eventParams[LAYER_STATES], [
194-
LAYER_ID => $experiment->getLayerId(),
195-
ACTION_TRIGGERED => true,
196-
REVISION => $config->getRevision(),
197-
DECISION => [
167+
$eventEntity = $config->getEvent($eventKey);
168+
169+
$singleSnapshot[DECISIONS] = [
170+
[
171+
CAMPAIGN_ID => $experiment->getLayerId(),
198172
EXPERIMENT_ID => $experimentId,
199-
VARIATION_ID => $variationId,
200-
IS_LAYER_HOLDBACK => false
173+
VARIATION_ID => $variationId
174+
]
175+
];
176+
177+
$singleSnapshot[EVENTS] = [
178+
[
179+
ENTITY_ID => $eventEntity->getId(),
180+
TIMESTAMP => time()*1000,
181+
UUID => GeneratorUtils::getRandomUuid(),
182+
KEY => $eventKey
201183
]
202-
]);
184+
];
185+
186+
if(!is_null($eventTags)){
187+
$revenue = EventTagUtils::getRevenueValue($eventTags);
188+
if(!is_null($revenue)){
189+
$singleSnapshot[EVENTS][0][EventTagUtils::REVENUE_EVENT_METRIC_NAME] = $revenue;
190+
}
191+
192+
$eventValue = EventTagUtils::getNumericValue($eventTags);
193+
if(!is_null($eventValue)){
194+
$singleSnapshot[EVENTS][0][EventTagUtils::NUMERIC_EVENT_METRIC_NAME] = $eventValue;
195+
}
196+
197+
$singleSnapshot[EVENTS][0]['tags'] = $eventTags;
198+
}
199+
200+
$conversionParams [] = $singleSnapshot;
203201
}
202+
203+
return $conversionParams;
204204
}
205205

206206
/**
@@ -216,14 +216,15 @@ private function setConversionParams($config, $eventKey, $experimentVariationMap
216216
*/
217217
public function createImpressionEvent($config, $experimentKey, $variationKey, $userId, $attributes)
218218
{
219-
$this->resetParams();
220-
$this->setCommonParams($config, $userId, $attributes);
219+
$eventParams = $this->getCommonParams($config, $userId, $attributes);
221220

222221
$experiment = $config->getExperimentFromKey($experimentKey);
223222
$variation = $config->getVariationFromKey($experimentKey, $variationKey);
224-
$this->setImpressionParams($experiment, $variation->getId());
223+
$impressionParams = $this->getImpressionParams($experiment, $variation->getId());
224+
225+
$eventParams[VISITORS][0][SNAPSHOTS][] = $impressionParams;
225226

226-
return new LogEvent(self::$IMPRESSION_ENDPOINT, $this->getParams(), self::$HTTP_VERB, self::$HTTP_HEADERS);
227+
return new LogEvent(self::$ENDPOINT, $eventParams, self::$HTTP_VERB, self::$HTTP_HEADERS);
227228
}
228229

229230
/**
@@ -240,10 +241,13 @@ public function createImpressionEvent($config, $experimentKey, $variationKey, $u
240241
*/
241242
public function createConversionEvent($config, $eventKey, $experimentVariationMap, $userId, $attributes, $eventTags)
242243
{
243-
$this->resetParams();
244-
$this->setCommonParams($config, $userId, $attributes);
245-
$this->setConversionParams($config, $eventKey, $experimentVariationMap, $userId, $eventTags);
246244

247-
return new LogEvent(self::$CONVERSION_ENDPOINT, $this->getParams(), self::$HTTP_VERB, self::$HTTP_HEADERS);
245+
$eventParams = $this->getCommonParams($config, $userId, $attributes);
246+
$conversionParams = $this->getConversionParams($config, $eventKey, $experimentVariationMap, $userId, $eventTags);
247+
248+
$eventParams[VISITORS][0][SNAPSHOTS] = $conversionParams;
249+
return new LogEvent(self::$ENDPOINT, $eventParams, self::$HTTP_VERB, self::$HTTP_HEADERS);
248250
}
249251
}
252+
253+
Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -15,23 +15,25 @@
1515
* limitations under the License.
1616
*/
1717

18-
define('ACCOUNT_ID', 'accountId');
19-
define('PROJECT_ID', 'projectId');
18+
define('ACCOUNT_ID', 'account_id');
19+
define('PROJECT_ID', 'project_id');
20+
define('ENTITY_ID', 'entity_id');
21+
define('TIMESTAMP', 'timestamp');
22+
define('VISITORS', 'visitors');
2023
define('REVISION', 'revision');
21-
define('LAYER_ID', 'layerId');
22-
define('EXPERIMENT_ID', 'experimentId');
23-
define('VARIATION_ID', 'variationId');
24-
define('VISITOR_ID', 'visitorId');
25-
define('EVENT_ID', 'eventEntityId');
26-
define('EVENT_NAME', 'eventName');
27-
define('EVENT_METRICS', 'eventMetrics');
28-
define('EVENT_FEATURES', 'eventFeatures');
29-
define('USER_FEATURES', 'userFeatures');
30-
define('DECISION', 'decision');
31-
define('LAYER_STATES', 'layerStates');
32-
define('TIME', 'timestamp');
33-
define('CLIENT_ENGINE', 'clientEngine');
34-
define('CLIENT_VERSION', 'clientVersion');
35-
define('ACTION_TRIGGERED', 'actionTriggered');
36-
define('IS_GLOBAL_HOLDBACK', 'isGlobalHoldback');
37-
define('IS_LAYER_HOLDBACK', 'isLayerHoldback');
24+
define('EXPERIMENT_ID', 'experiment_id');
25+
define('VARIATION_ID', 'variation_id');
26+
define('CAMPAIGN_ID','campaign_id');
27+
define('VISITOR_ID', 'visitor_id');
28+
define('DECISIONS', 'decisions');
29+
define('EVENTS', 'events');;
30+
define('CLIENT_ENGINE', 'client_name');
31+
define('CLIENT_VERSION', 'client_version');
32+
define('CUSTOM_ATTRIBUTE_FEATURE_TYPE','custom');
33+
define('ACTIVATE_EVENT_KEY','campaign_activated');
34+
define('SNAPSHOTS','snapshots');
35+
define('ATTRIBUTES', 'attributes');
36+
define('KEY', 'key');
37+
define('TYPE', 'type');
38+
define('VALUE', 'value');
39+
define('UUID', 'uuid');

0 commit comments

Comments
 (0)