Skip to content

Commit

Permalink
feat: accept custom session id paramter in config (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpagtakhan authored Jan 20, 2022
1 parent 4c9cf0f commit b64b8b0
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/amplitude-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,19 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o

var now = new Date().getTime();
const startNewSession =
!this._sessionId || !this._lastEventTime || now - this._lastEventTime > this.options.sessionTimeout;
!this._sessionId ||
!this._lastEventTime ||
now - this._lastEventTime > this.options.sessionTimeout ||
this.options.sessionId;
if (startNewSession) {
if (this.options.unsetParamsReferrerOnNewSession) {
this._unsetUTMParams();
}
this._newSession = true;
this._sessionId = now;
this._sessionId = this.options.sessionId || now;
// reset this.options.sessionId to avoid re-usage
// use instance.getSessionId() to get session id
this.options.sessionId = undefined;

// only capture UTM params and referrer if new session
if (this.options.saveParamsReferrerOncePerSession) {
Expand Down Expand Up @@ -387,6 +393,9 @@ var _parseConfig = function _parseConfig(options, config) {
var expectedType = type(options[key]);
if (key === 'transport' && !utils.validateTransport(inputValue)) {
return;
} else if (key === 'sessionId' && inputValue !== null) {
options[key] = utils.validateSessionId(inputValue) ? inputValue : null;
return;
} else if (!utils.validateInput(inputValue, key + ' option', expectedType)) {
return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { version as libraryVersion } from '../package.json';
* @property {string} [serverZone] - For server zone related configuration, used for server api endpoint and dynamic configuration.
* @property {boolean} [useDynamicConfig] - Enable dynamic configuration to find best server url for user.
* @property {boolean} [serverZoneBasedApi] - To update api endpoint with serverZone change or not. For data residency, recommend to enable it unless using own proxy server.
* @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.
*/
export default {
apiEndpoint: Constants.EVENT_LOG_URL,
Expand Down Expand Up @@ -121,4 +122,5 @@ export default {
serverZone: AmplitudeServerZone.US,
useDynamicConfig: false,
serverZoneBasedApi: false,
sessionId: null,
};
10 changes: 10 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@ const isWebWorkerEnvironment = () => {
return typeof WorkerGlobalScope !== 'undefined';
};

const validateSessionId = (sessionId) => {
if (validateInput(sessionId, 'sessionId', 'number') && new Date(sessionId).getTime() > 0) {
return true;
}

log.error(`sessionId value must in milliseconds since epoch (Unix Timestamp)`);
return false;
};

export default {
setLogLevel,
getLogLevel,
Expand All @@ -293,4 +302,5 @@ export default {
validateProperties,
validateDeviceId,
validateTransport,
validateSessionId,
};
21 changes: 21 additions & 0 deletions test/amplitude-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,27 @@ describe('AmplitudeClient', function () {

assert.deepEqual(amplitude.options.plan, plan);
});

it('should set sessionId from config', () => {
const amplitude = new AmplitudeClient();
amplitude.init(apiKey, null, { sessionId: 123 });
assert.equal(amplitude.getSessionId(), 123);
assert.isUndefined(amplitude.options.sessionId);
});

it('should set default sessionId', () => {
const amplitude = new AmplitudeClient();
amplitude.init(apiKey, null);
assert.isTrue(amplitude.getSessionId() > 0);
assert.isUndefined(amplitude.options.sessionId);
});

it('should not set invalid sessionId', () => {
const amplitude = new AmplitudeClient();
amplitude.init(apiKey, null, { sessionId: 'asdf' });
assert.isTrue(amplitude.getSessionId() > 0);
assert.isUndefined(amplitude.options.sessionId);
});
});

describe('runQueuedFunctions', function () {
Expand Down
20 changes: 20 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,24 @@ describe('utils', function () {
assert.isFalse(utils.isWebWorkerEnvironment());
});
});

describe('validateSessionId', function () {
it('should return true', function () {
assert.isTrue(utils.validateSessionId(Date.now()));
});

it('should return false', function () {
assert.isFalse(utils.validateSessionId('asdf'));
assert.isFalse(utils.validateSessionId(0));
assert.isFalse(utils.validateSessionId(NaN));
assert.isFalse(utils.validateSessionId(null));
assert.isFalse(utils.validateSessionId(undefined));
assert.isFalse(utils.validateSessionId({}));
assert.isFalse(utils.validateSessionId([]));
assert.isFalse(utils.validateSessionId(new Map()));
assert.isFalse(utils.validateSessionId(new Set()));
assert.isFalse(utils.validateSessionId(true));
assert.isFalse(utils.validateSessionId(false));
});
});
});

0 comments on commit b64b8b0

Please sign in to comment.