Skip to content

Commit acf596a

Browse files
feat: add support for on new session start callback (#455)
1 parent ebbdf88 commit acf596a

File tree

3 files changed

+71
-8
lines changed

3 files changed

+71
-8
lines changed

src/amplitude-client.js

+32-7
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ var AmplitudeClient = function AmplitudeClient(instanceName) {
4242
this._q = []; // queue for proxied functions before script load
4343
this._sending = false;
4444
this._updateScheduled = false;
45-
this._onInit = [];
45+
this._onInitCallbacks = [];
46+
this._onNewSessionStartCallbacks = [];
4647

4748
// event meta data
4849
this._eventId = 0;
@@ -167,7 +168,9 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
167168
null;
168169

169170
var now = new Date().getTime();
170-
if (!this._sessionId || !this._lastEventTime || now - this._lastEventTime > this.options.sessionTimeout) {
171+
const startNewSession =
172+
!this._sessionId || !this._lastEventTime || now - this._lastEventTime > this.options.sessionTimeout;
173+
if (startNewSession) {
171174
if (this.options.unsetParamsReferrerOnNewSession) {
172175
this._unsetUTMParams();
173176
}
@@ -197,11 +200,15 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
197200

198201
this._sendEventsIfReady(); // try sending unsent events
199202

200-
for (let i = 0; i < this._onInit.length; i++) {
201-
this._onInit[i](this);
203+
for (let i = 0; i < this._onInitCallbacks.length; i++) {
204+
this._onInitCallbacks[i](this);
202205
}
203-
this._onInit = [];
206+
this._onInitCallbacks = [];
204207
this._isInitialized = true;
208+
209+
if (startNewSession) {
210+
this._runNewSessionStartCallbacks();
211+
}
205212
};
206213

207214
if (this.options.saveEvents) {
@@ -212,6 +219,9 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
212219
.map((event) => ({ event }))
213220
.concat(this._unsentIdentifys);
214221
}
222+
if (opt_config && opt_config.onNewSessionStart) {
223+
this.onNewSessionStart(this.options.onNewSessionStart);
224+
}
215225
initFromStorage();
216226
this.runQueuedFunctions();
217227
if (type(opt_callback) === 'function') {
@@ -250,6 +260,12 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
250260
}
251261
};
252262

263+
AmplitudeClient.prototype._runNewSessionStartCallbacks = function () {
264+
for (let i = 0; i < this._onNewSessionStartCallbacks.length; i++) {
265+
this._onNewSessionStartCallbacks[i](this);
266+
}
267+
};
268+
253269
AmplitudeClient.prototype.deleteLowerLevelDomainCookies = function () {
254270
const host = getHost();
255271

@@ -470,14 +486,22 @@ AmplitudeClient.prototype.isNewSession = function isNewSession() {
470486
* Add callbacks to call after init. Useful for users who load Amplitude through a snippet.
471487
* @public
472488
*/
473-
AmplitudeClient.prototype.onInit = function (callback) {
489+
AmplitudeClient.prototype.onInit = function onInit(callback) {
474490
if (this._isInitialized) {
475491
callback(this);
476492
} else {
477-
this._onInit.push(callback);
493+
this._onInitCallbacks.push(callback);
478494
}
479495
};
480496

497+
/**
498+
* Add callbacks to call after new session start.
499+
* @public
500+
*/
501+
AmplitudeClient.prototype.onNewSessionStart = function onNewSessionStart(callback) {
502+
this._onNewSessionStartCallbacks.push(callback);
503+
};
504+
481505
/**
482506
* Returns the id of the current session.
483507
* @public
@@ -878,6 +902,7 @@ AmplitudeClient.prototype.setUserId = function setUserId(userId, startNewSession
878902
}
879903
this._newSession = true;
880904
this._sessionId = new Date().getTime();
905+
this._runNewSessionStartCallbacks();
881906

882907
// only capture UTM params and referrer if new session
883908
if (this.options.saveParamsReferrerOncePerSession) {

src/options.js

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default {
8181
optOut: false,
8282
onError: () => {},
8383
onExitPage: () => {},
84+
onNewSessionStart: () => {},
8485
plan: {
8586
branch: '',
8687
source: '',

test/amplitude-client.js

+38-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,44 @@ describe('AmplitudeClient', function () {
125125
});
126126

127127
amplitude.init(apiKey);
128-
assert.lengthOf(amplitude._onInit, 0);
128+
assert.lengthOf(amplitude._onInitCallbacks, 0);
129+
});
130+
131+
it('should invoke onNewSessionStart callbacks on new session passed through init()', function () {
132+
const callback = sinon.spy();
133+
const amplitude2 = new AmplitudeClient();
134+
amplitude2.init(apiKey, undefined, {
135+
onNewSessionStart: callback,
136+
});
137+
assert.lengthOf(amplitude2._onNewSessionStartCallbacks, 1);
138+
assert.ok(callback.calledOnce);
139+
});
140+
141+
it('should invoke onNewSessionStart callbacks on new session pased through onNewSessionStart()', function () {
142+
const callback = sinon.spy();
143+
const amplitude2 = new AmplitudeClient();
144+
amplitude2.onNewSessionStart(callback);
145+
amplitude2.init(apiKey);
146+
assert.lengthOf(amplitude2._onNewSessionStartCallbacks, 1);
147+
assert.ok(callback.calledOnce);
148+
});
149+
150+
it('should pass the amplitude instance to onNewSessionStart callbacks', () => {
151+
const callback = sinon.spy();
152+
const amplitude2 = new AmplitudeClient();
153+
amplitude2.onNewSessionStart(callback);
154+
amplitude2.init(apiKey);
155+
assert.isTrue(callback.calledWith(amplitude2));
156+
});
157+
158+
it('should include a session id on onNewSessionStart callback', () => {
159+
let sessionId = null;
160+
const amplitude2 = new AmplitudeClient();
161+
amplitude2.onNewSessionStart((a) => {
162+
sessionId = a.getSessionId();
163+
});
164+
amplitude2.init(apiKey);
165+
assert.isNumber(sessionId);
129166
});
130167

131168
it('fails on invalid apiKeys', function () {

0 commit comments

Comments
 (0)