Skip to content

Commit b64b8b0

Browse files
feat: accept custom session id paramter in config (#485)
1 parent 4c9cf0f commit b64b8b0

File tree

5 files changed

+64
-2
lines changed

5 files changed

+64
-2
lines changed

src/amplitude-client.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,19 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
174174

175175
var now = new Date().getTime();
176176
const startNewSession =
177-
!this._sessionId || !this._lastEventTime || now - this._lastEventTime > this.options.sessionTimeout;
177+
!this._sessionId ||
178+
!this._lastEventTime ||
179+
now - this._lastEventTime > this.options.sessionTimeout ||
180+
this.options.sessionId;
178181
if (startNewSession) {
179182
if (this.options.unsetParamsReferrerOnNewSession) {
180183
this._unsetUTMParams();
181184
}
182185
this._newSession = true;
183-
this._sessionId = now;
186+
this._sessionId = this.options.sessionId || now;
187+
// reset this.options.sessionId to avoid re-usage
188+
// use instance.getSessionId() to get session id
189+
this.options.sessionId = undefined;
184190

185191
// only capture UTM params and referrer if new session
186192
if (this.options.saveParamsReferrerOncePerSession) {
@@ -387,6 +393,9 @@ var _parseConfig = function _parseConfig(options, config) {
387393
var expectedType = type(options[key]);
388394
if (key === 'transport' && !utils.validateTransport(inputValue)) {
389395
return;
396+
} else if (key === 'sessionId' && inputValue !== null) {
397+
options[key] = utils.validateSessionId(inputValue) ? inputValue : null;
398+
return;
390399
} else if (!utils.validateInput(inputValue, key + ' option', expectedType)) {
391400
return;
392401
}

src/options.js

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { version as libraryVersion } from '../package.json';
5252
* @property {string} [serverZone] - For server zone related configuration, used for server api endpoint and dynamic configuration.
5353
* @property {boolean} [useDynamicConfig] - Enable dynamic configuration to find best server url for user.
5454
* @property {boolean} [serverZoneBasedApi] - To update api endpoint with serverZone change or not. For data residency, recommend to enable it unless using own proxy server.
55+
* @property {number} [sessionId=`null`] - The custom Session ID for the current session. *Note: This is not recommended unless you know what you are doing because the Session ID of a session is utilized for all session metrics in Amplitude.
5556
*/
5657
export default {
5758
apiEndpoint: Constants.EVENT_LOG_URL,
@@ -121,4 +122,5 @@ export default {
121122
serverZone: AmplitudeServerZone.US,
122123
useDynamicConfig: false,
123124
serverZoneBasedApi: false,
125+
sessionId: null,
124126
};

src/utils.js

+10
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,15 @@ const isWebWorkerEnvironment = () => {
278278
return typeof WorkerGlobalScope !== 'undefined';
279279
};
280280

281+
const validateSessionId = (sessionId) => {
282+
if (validateInput(sessionId, 'sessionId', 'number') && new Date(sessionId).getTime() > 0) {
283+
return true;
284+
}
285+
286+
log.error(`sessionId value must in milliseconds since epoch (Unix Timestamp)`);
287+
return false;
288+
};
289+
281290
export default {
282291
setLogLevel,
283292
getLogLevel,
@@ -293,4 +302,5 @@ export default {
293302
validateProperties,
294303
validateDeviceId,
295304
validateTransport,
305+
validateSessionId,
296306
};

test/amplitude-client.js

+21
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,27 @@ describe('AmplitudeClient', function () {
905905

906906
assert.deepEqual(amplitude.options.plan, plan);
907907
});
908+
909+
it('should set sessionId from config', () => {
910+
const amplitude = new AmplitudeClient();
911+
amplitude.init(apiKey, null, { sessionId: 123 });
912+
assert.equal(amplitude.getSessionId(), 123);
913+
assert.isUndefined(amplitude.options.sessionId);
914+
});
915+
916+
it('should set default sessionId', () => {
917+
const amplitude = new AmplitudeClient();
918+
amplitude.init(apiKey, null);
919+
assert.isTrue(amplitude.getSessionId() > 0);
920+
assert.isUndefined(amplitude.options.sessionId);
921+
});
922+
923+
it('should not set invalid sessionId', () => {
924+
const amplitude = new AmplitudeClient();
925+
amplitude.init(apiKey, null, { sessionId: 'asdf' });
926+
assert.isTrue(amplitude.getSessionId() > 0);
927+
assert.isUndefined(amplitude.options.sessionId);
928+
});
908929
});
909930

910931
describe('runQueuedFunctions', function () {

test/utils.js

+20
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,24 @@ describe('utils', function () {
260260
assert.isFalse(utils.isWebWorkerEnvironment());
261261
});
262262
});
263+
264+
describe('validateSessionId', function () {
265+
it('should return true', function () {
266+
assert.isTrue(utils.validateSessionId(Date.now()));
267+
});
268+
269+
it('should return false', function () {
270+
assert.isFalse(utils.validateSessionId('asdf'));
271+
assert.isFalse(utils.validateSessionId(0));
272+
assert.isFalse(utils.validateSessionId(NaN));
273+
assert.isFalse(utils.validateSessionId(null));
274+
assert.isFalse(utils.validateSessionId(undefined));
275+
assert.isFalse(utils.validateSessionId({}));
276+
assert.isFalse(utils.validateSessionId([]));
277+
assert.isFalse(utils.validateSessionId(new Map()));
278+
assert.isFalse(utils.validateSessionId(new Set()));
279+
assert.isFalse(utils.validateSessionId(true));
280+
assert.isFalse(utils.validateSessionId(false));
281+
});
282+
});
263283
});

0 commit comments

Comments
 (0)