UNPKG

17.1 kBJavaScriptView Raw
1"use strict";
2/*
3 * Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
6 * the License. A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0/
9 *
10 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
12 * and limitations under the License.
13 */
14var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16 return new (P || (P = Promise))(function (resolve, reject) {
17 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20 step((generator = generator.apply(thisArg, _arguments || [])).next());
21 });
22};
23var __generator = (this && this.__generator) || function (thisArg, body) {
24 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
25 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
26 function verb(n) { return function (v) { return step([n, v]); }; }
27 function step(op) {
28 if (f) throw new TypeError("Generator is already executing.");
29 while (_) try {
30 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
31 if (y = 0, t) op = [op[0] & 2, t.value];
32 switch (op[0]) {
33 case 0: case 1: t = op; break;
34 case 4: _.label++; return { value: op[1], done: false };
35 case 5: _.label++; y = op[1]; op = [0]; continue;
36 case 7: op = _.ops.pop(); _.trys.pop(); continue;
37 default:
38 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
39 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
40 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
41 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
42 if (t[2]) _.ops.pop();
43 _.trys.pop(); continue;
44 }
45 op = body.call(thisArg, _);
46 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
47 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
48 }
49};
50var __importDefault = (this && this.__importDefault) || function (mod) {
51 return (mod && mod.__esModule) ? mod : { "default": mod };
52};
53Object.defineProperty(exports, "__esModule", { value: true });
54var core_1 = require("@aws-amplify/core");
55var client_personalize_events_1 = require("@aws-sdk/client-personalize-events");
56var AmazonPersonalizeHelper_1 = require("./AmazonPersonalizeHelper");
57var get_1 = __importDefault(require("lodash/get"));
58var isEmpty_1 = __importDefault(require("lodash/isEmpty"));
59var isEqual_1 = __importDefault(require("lodash/isEqual"));
60var logger = new core_1.ConsoleLogger('AmazonPersonalizeProvider');
61// events buffer
62var FLUSH_SIZE = 5;
63var FLUSH_SIZE_THRESHHOLD = 10;
64var FLUSH_INTERVAL = 5 * 1000; // 5s
65var IDENTIFY_EVENT = 'Identify';
66var AmazonPersonalizeProvider = /** @class */ (function () {
67 function AmazonPersonalizeProvider(config) {
68 this._buffer = [];
69 this._config = config ? config : {};
70 this._config.flushSize =
71 this._config.flushSize > 0 &&
72 this._config.flushSize <= FLUSH_SIZE_THRESHHOLD
73 ? this._config.flushSize
74 : FLUSH_SIZE;
75 this._config.flushInterval = this._config.flushInterval || FLUSH_INTERVAL;
76 this._sessionManager = new AmazonPersonalizeHelper_1.SessionInfoManager();
77 if (!isEmpty_1.default(this._config.trackingId)) {
78 this._sessionInfo = this._sessionManager.retrieveSessionInfo(this._config.trackingId);
79 }
80 this._isBrowser = core_1.JS.browserOrNode().isBrowser;
81 // flush event buffer
82 this._setupTimer();
83 }
84 AmazonPersonalizeProvider.prototype._setupTimer = function () {
85 if (this._timer) {
86 clearInterval(this._timer);
87 }
88 var flushInterval = this._config.flushInterval;
89 var that = this;
90 this._timer = setInterval(function () {
91 that._sendFromBuffer();
92 }, flushInterval);
93 };
94 /**
95 * Record event
96 * @param eventType - type of the event action. e.g. "Click"
97 * @param properties - properties of the event
98 * @return Promise
99 */
100 AmazonPersonalizeProvider.prototype.record = function (params) {
101 return __awaiter(this, void 0, void 0, function () {
102 var credentials, _a, eventType, properties, requestParams, isLoaded;
103 return __generator(this, function (_b) {
104 switch (_b.label) {
105 case 0: return [4 /*yield*/, this._getCredentials()];
106 case 1:
107 credentials = _b.sent();
108 if (!credentials)
109 return [2 /*return*/, Promise.resolve(false)];
110 Object.assign(params, {
111 config: this._config,
112 credentials: credentials,
113 sentAt: new Date(),
114 });
115 _a = params.event, eventType = _a.eventType, properties = _a.properties;
116 if (eventType === IDENTIFY_EVENT) {
117 this._sessionManager.updateSessionInfo(properties && properties.userId ? properties.userId : '', this._sessionInfo);
118 return [2 /*return*/];
119 }
120 else if (!isEmpty_1.default(params.event.userId)) {
121 this._sessionManager.updateSessionInfo(params.event.userId, this._sessionInfo);
122 }
123 requestParams = this.generateRequestParams(params, this._sessionInfo);
124 if (!(eventType === 'MediaAutoTrack')) return [3 /*break*/, 7];
125 if (!this._isBrowser) return [3 /*break*/, 5];
126 if (!!isEmpty_1.default(get_1.default(requestParams, 'eventData.properties.domElementId', null))) return [3 /*break*/, 3];
127 return [4 /*yield*/, this.isElementFullyLoaded(this.loadElement, requestParams.eventData.properties['domElementId'], 500, 5)];
128 case 2:
129 isLoaded = _b.sent();
130 if (isLoaded) {
131 new AmazonPersonalizeHelper_1.MediaAutoTrack(requestParams, this);
132 }
133 else {
134 logger.debug('Cannot find the media element.');
135 }
136 return [3 /*break*/, 4];
137 case 3:
138 logger.debug("Missing domElementId field in 'properties' for MediaAutoTrack event type.");
139 _b.label = 4;
140 case 4: return [3 /*break*/, 6];
141 case 5:
142 logger.debug('MediaAutoTrack only for browser');
143 _b.label = 6;
144 case 6: return [2 /*return*/];
145 case 7: return [2 /*return*/, this.putToBuffer(requestParams)];
146 }
147 });
148 });
149 };
150 AmazonPersonalizeProvider.prototype.loadElement = function (domId) {
151 return new Promise(function (resolve, reject) {
152 if (document.getElementById(domId) &&
153 document.getElementById(domId).clientHeight) {
154 return resolve(true);
155 }
156 else {
157 return reject(true);
158 }
159 });
160 };
161 AmazonPersonalizeProvider.prototype.isElementFullyLoaded = function (operation, params, delay, times) {
162 var _this = this;
163 var wait = function (ms) { return new Promise(function (r) { return setTimeout(r, ms); }); };
164 return new Promise(function (resolve, reject) {
165 return operation(params)
166 .then(resolve)
167 .catch(function (reason) {
168 if (times - 1 > 0) {
169 return wait(delay)
170 .then(_this.isElementFullyLoaded.bind(null, operation, params, delay, times - 1))
171 .then(resolve)
172 .catch(reject);
173 }
174 return reject(reason);
175 });
176 });
177 };
178 /**
179 * get the category of the plugin
180 */
181 AmazonPersonalizeProvider.prototype.getCategory = function () {
182 return 'Analytics';
183 };
184 /**
185 * get provider name of the plugin
186 */
187 AmazonPersonalizeProvider.prototype.getProviderName = function () {
188 return 'AmazonPersonalize';
189 };
190 /**
191 * configure the plugin
192 * @param {Object} config - configuration
193 */
194 AmazonPersonalizeProvider.prototype.configure = function (config) {
195 logger.debug('configure Analytics', config);
196 var conf = config ? config : {};
197 this._config = Object.assign({}, this._config, conf);
198 if (!isEmpty_1.default(this._config.trackingId)) {
199 this._sessionInfo = this._sessionManager.retrieveSessionInfo(this._config.trackingId);
200 }
201 this._setupTimer();
202 return this._config;
203 };
204 /**
205 * Generate the requestParams from customer input params and sessionInfo
206 * @private
207 * @param eventData - customer input for event data
208 * @param api - api name
209 * @return RequestParams - wrapper object with all information required for make request
210 */
211 AmazonPersonalizeProvider.prototype.generateRequestParams = function (params, sessionInfo) {
212 var requestParams = {};
213 var _a = params.event, eventType = _a.eventType, properties = _a.properties;
214 requestParams.eventData = { eventType: eventType, properties: properties };
215 requestParams.sessionInfo = sessionInfo;
216 requestParams.sentAt = params.sentAt;
217 requestParams.credentials = params.credentials;
218 requestParams.config = params.config;
219 return requestParams;
220 };
221 /**
222 * record an event
223 * @param {Object} params - the params of an event
224 */
225 AmazonPersonalizeProvider.prototype._sendEvents = function (group) {
226 var groupLen = group.length;
227 if (groupLen === 0) {
228 logger.debug('events array is empty, directly return');
229 return;
230 }
231 var _a = group[0], config = _a.config, credentials = _a.credentials, sessionInfo = _a.sessionInfo;
232 var initClients = this._init(config, credentials);
233 if (!initClients)
234 return false;
235 if (groupLen > 0) {
236 var events = [];
237 for (var i = 0; i < groupLen; i += 1) {
238 var params = group.shift();
239 var eventPayload = this._generateSingleRecordPayload(params, sessionInfo);
240 events.push(eventPayload);
241 }
242 var payload_1 = {};
243 payload_1.trackingId = sessionInfo.trackingId;
244 payload_1.sessionId = sessionInfo.sessionId;
245 payload_1.userId = sessionInfo.userId;
246 payload_1.eventList = [];
247 events.forEach(function (event) {
248 // @ts-ignore
249 payload_1.eventList.push(event);
250 });
251 var command = new client_personalize_events_1.PutEventsCommand(payload_1);
252 this._personalize.send(command, function (err) {
253 if (err)
254 logger.debug('Failed to call putEvents in Personalize', err);
255 else
256 logger.debug('Put events');
257 });
258 }
259 };
260 /**
261 * Put event into buffer
262 * @private
263 * @param params - params for the event recording
264 */
265 AmazonPersonalizeProvider.prototype.putToBuffer = function (params) {
266 if (this._buffer.length < this._config.flushSize) {
267 this._buffer.push(params);
268 }
269 else {
270 this._buffer.push(params);
271 this._sendFromBuffer();
272 }
273 return Promise.resolve(true);
274 };
275 /**
276 * flush the buffer and batch sending the request
277 * @private
278 * @param eventsParams - the buffer for cache the payload
279 */
280 AmazonPersonalizeProvider.prototype._sendFromBuffer = function () {
281 var _this = this;
282 var size = this._buffer.length;
283 if (size <= 0)
284 return;
285 var eventsGroups = [];
286 var preCred = null;
287 var group = [];
288 for (var i = 0; i < size; i += 1) {
289 var currRequestParams = this._buffer.shift();
290 var cred = currRequestParams.credentials;
291 var sessionInfo = currRequestParams.sessionInfo;
292 if (i === 0) {
293 group.push(currRequestParams);
294 preCred = cred;
295 }
296 else {
297 if (isEqual_1.default(sessionInfo, this._sessionInfo) &&
298 cred.sessionToken === preCred.sessionToken &&
299 cred.identityId === preCred.identityId) {
300 logger.debug('no change for cred, put event in the same group');
301 group.push(currRequestParams);
302 }
303 else {
304 eventsGroups.push(group);
305 group = [];
306 group.push(currRequestParams);
307 preCred = cred;
308 this._sessionInfo = sessionInfo;
309 }
310 }
311 }
312 eventsGroups.push(group);
313 eventsGroups.map(function (group) {
314 _this._sendEvents(group);
315 });
316 };
317 /**
318 * Generate the record payload for single event
319 * @private
320 * @param params - RequestParams
321 */
322 AmazonPersonalizeProvider.prototype._generateSingleRecordPayload = function (params, sessionInfo) {
323 var eventData = params.eventData, sentAt = params.sentAt;
324 var trackPayload = {};
325 trackPayload.sentAt = sentAt;
326 trackPayload.properties =
327 eventData.properties && JSON.stringify(eventData.properties);
328 trackPayload.eventId =
329 this._sessionManager.getTimerKey() + sessionInfo.sessionId;
330 trackPayload.eventType = eventData.eventType;
331 return trackPayload;
332 };
333 /**
334 * Initialize the personalize client
335 * @private
336 * @param params - RequestParams
337 */
338 AmazonPersonalizeProvider.prototype._init = function (config, credentials) {
339 logger.debug('init clients');
340 if (this._personalize &&
341 this._config.credentials &&
342 this._config.credentials.sessionToken === credentials.sessionToken &&
343 this._config.credentials.identityId === credentials.identityId) {
344 logger.debug('no change for analytics config, directly return from init');
345 return true;
346 }
347 this._config.credentials = credentials;
348 var region = config.region;
349 logger.debug('initialize personalize with credentials', credentials);
350 this._personalize = new client_personalize_events_1.PersonalizeEventsClient({
351 region: region,
352 credentials: credentials,
353 customUserAgent: core_1.getAmplifyUserAgent(),
354 });
355 return true;
356 };
357 /**
358 * check if current credentials exists
359 * @private
360 */
361 AmazonPersonalizeProvider.prototype._getCredentials = function () {
362 var that = this;
363 return core_1.Credentials.get()
364 .then(function (credentials) {
365 if (!credentials)
366 return null;
367 logger.debug('set credentials for analytics', that._config.credentials);
368 return core_1.Credentials.shear(credentials);
369 })
370 .catch(function (err) {
371 logger.debug('ensure credentials error', err);
372 return null;
373 });
374 };
375 return AmazonPersonalizeProvider;
376}());
377exports.AmazonPersonalizeProvider = AmazonPersonalizeProvider;
378/**
379 * @deprecated use named import
380 */
381exports.default = AmazonPersonalizeProvider;
382//# sourceMappingURL=AmazonPersonalizeProvider.js.map
\No newline at end of file