Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 207 additions & 7 deletions src/amplitude-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import base64Id from './base64Id';
import DEFAULT_OPTIONS from './options';
import getHost from './get-host';
import baseCookie from './base-cookie';
import { getEventLogApi } from './server-zone';
import { AmplitudeServerZone, getEventLogApi } from './server-zone';
import ConfigManager from './config-manager';

/**
Expand Down Expand Up @@ -858,15 +858,33 @@ AmplitudeClient.prototype.setDomain = function setDomain(domain) {
* Sets an identifier for the current user.
* @public
* @param {string} userId - identifier to set. Can be null.
* @param {boolean} startNewSession - (optional) if start a new session or not
* @example amplitudeClient.setUserId('[email protected]');
*/
AmplitudeClient.prototype.setUserId = function setUserId(userId) {
AmplitudeClient.prototype.setUserId = function setUserId(userId, startNewSession = false) {
if (!utils.validateInput(startNewSession, 'startNewSession', 'boolean')) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setUserId'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.userId = (userId !== undefined && userId !== null && '' + userId) || null;
if (startNewSession) {
if (this.options.unsetParamsReferrerOnNewSession) {
this._unsetUTMParams();
}
this._newSession = true;
this._sessionId = new Date().getTime();

// only capture UTM params and referrer if new session
if (this.options.saveParamsReferrerOncePerSession) {
this._trackParamsAndReferrer();
}
}

_saveCookieData(this);
} catch (e) {
utils.log.error(e);
Expand Down Expand Up @@ -1232,6 +1250,7 @@ AmplitudeClient.prototype._logEvent = function _logEvent(
timestamp,
callback,
errorCallback,
outOfSession,
) {
_loadCookieData(this); // reload cookie before each log event to sync event meta-data between windows and tabs

Expand All @@ -1257,7 +1276,13 @@ AmplitudeClient.prototype._logEvent = function _logEvent(
}
var sequenceNumber = this.nextSequenceNumber();
var eventTime = type(timestamp) === 'number' ? timestamp : new Date().getTime();
if (!this._sessionId || !this._lastEventTime || eventTime - this._lastEventTime > this.options.sessionTimeout) {
if (outOfSession) {
this._sessionId = -1;
} else if (
!this._sessionId ||
!this._lastEventTime ||
eventTime - this._lastEventTime > this.options.sessionTimeout
) {
this._sessionId = eventTime;
}
this._lastEventTime = eventTime;
Expand Down Expand Up @@ -1383,13 +1408,20 @@ AmplitudeClient.prototype._limitEventsQueued = function _limitEventsQueued(queue
* @param {Amplitude~eventCallback} opt_error_callback - (optional) a callback function to run after the event logging
* fails. The failure can be from the request being malformed or from a network failure
* Note: the server response code and response body from the event upload are passed to the callback function.
* @param {boolean} outOfSession - (optional) if this event is out of session or not
* @example amplitudeClient.logEvent('Clicked Homepage Button', {'finished_flow': false, 'clicks': 15});
*/
AmplitudeClient.prototype.logEvent = function logEvent(eventType, eventProperties, opt_callback, opt_error_callback) {
AmplitudeClient.prototype.logEvent = function logEvent(
eventType,
eventProperties,
opt_callback,
opt_error_callback,
outOfSession = false,
) {
if (this._shouldDeferCall()) {
return this._q.push(['logEvent'].concat(Array.prototype.slice.call(arguments, 0)));
}
return this.logEventWithTimestamp(eventType, eventProperties, null, opt_callback, opt_error_callback);
return this.logEventWithTimestamp(eventType, eventProperties, null, opt_callback, opt_error_callback, outOfSession);
};

/**
Expand All @@ -1403,6 +1435,7 @@ AmplitudeClient.prototype.logEvent = function logEvent(eventType, eventPropertie
* @param {Amplitude~eventCallback} opt_error_callback - (optional) a callback function to run after the event logging
* fails. The failure can be from the request being malformed or from a network failure
* Note: the server response code and response body from the event upload are passed to the callback function.
* @param {boolean} outOfSession - (optional) if out of the sessioin or not
* @example amplitudeClient.logEvent('Clicked Homepage Button', {'finished_flow': false, 'clicks': 15});
*/
AmplitudeClient.prototype.logEventWithTimestamp = function logEvent(
Expand All @@ -1411,6 +1444,7 @@ AmplitudeClient.prototype.logEventWithTimestamp = function logEvent(
timestamp,
opt_callback,
opt_error_callback,
outOfSession = false,
) {
if (this._shouldDeferCall()) {
return this._q.push(['logEventWithTimestamp'].concat(Array.prototype.slice.call(arguments, 0)));
Expand All @@ -1435,6 +1469,13 @@ AmplitudeClient.prototype.logEventWithTimestamp = function logEvent(
});
return -1;
}

if (!utils.validateInput(outOfSession, 'outOfSession', 'boolean')) {
_logErrorsWithCallbacks(opt_callback, opt_error_callback, 0, 'No request sent', {
reason: 'Invalid outOfSession value',
});
}

return this._logEvent(
eventType,
eventProperties,
Expand All @@ -1445,6 +1486,7 @@ AmplitudeClient.prototype.logEventWithTimestamp = function logEvent(
timestamp,
opt_callback,
opt_error_callback,
outOfSession,
);
};

Expand Down Expand Up @@ -1473,6 +1515,7 @@ AmplitudeClient.prototype.logEventWithGroups = function (
groups,
opt_callback,
opt_error_callback,
outOfSession = false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this one in group also used in flutter? Or used in other SDK?

Copy link
Contributor Author

@yuhao900914 yuhao900914 Nov 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flutter doesn't have the logEventWithGroups method. But I think those functions are exposed to Amplitude-Javascript user, so it's better to keep them consistent. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuhao900914 For other SDKs we have, do we have similaroutOfSession support on logEventWithGroups?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Andorid and iOS are similar, the logEvent function is able to pass groups info and outOfSession together.
- (void)logEvent:(NSString *)eventType withEventProperties:(NSDictionary *)eventProperties withApiProperties:(NSDictionary *)apiProperties withUserProperties:(NSDictionary *)userProperties withGroups:(NSDictionary *)groups withGroupProperties:(NSDictionary *)groupProperties withTimestamp:(NSNumber *)timestamp outOfSession:(BOOL)outOfSession {xxx}

) {
if (this._shouldDeferCall()) {
return this._q.push(['logEventWithGroups'].concat(Array.prototype.slice.call(arguments, 0)));
Expand All @@ -1490,7 +1533,25 @@ AmplitudeClient.prototype.logEventWithGroups = function (
});
return -1;
}
return this._logEvent(eventType, eventProperties, null, null, groups, null, null, opt_callback, opt_error_callback);

if (!utils.validateInput(outOfSession, 'outOfSession', 'boolean')) {
_logErrorsWithCallbacks(event.callback, event.errorCallback, 0, 'No request sent', {
reason: 'Invalid outOfSession value',
});
}

return this._logEvent(
eventType,
eventProperties,
null,
null,
groups,
null,
null,
opt_callback,
opt_error_callback,
outOfSession,
);
};

/**
Expand Down Expand Up @@ -1847,7 +1908,10 @@ AmplitudeClient.prototype.__VERSION__ = function getVersion() {
* @param {string} name - Custom library name
* @param {string} version - Custom library version
*/
AmplitudeClient.prototype.setLibrary = function setLibrary(name, version) {
AmplitudeClient.prototype.setLibrary = function setLibrary(
name = this.options.libraryName,
version = this.options.libraryVersion,
) {
this.options.library = { name: name, version: version };
};

Expand Down Expand Up @@ -1897,4 +1961,140 @@ AmplitudeClient.prototype._refreshDynamicConfig = function _refreshDynamicConfig
}
};

/**
* Returns the deviceId value.
* @public
* @return {string} Id of current device.
*/
AmplitudeClient.prototype.getDeviceId = function getDeviceId() {
return this.options.deviceId;
};

/**
* Returns the userId.
* @public
* @return {string} Id of current user.
*/
AmplitudeClient.prototype.getUserId = function getUserId() {
return this.options.userId;
};

/**
* Set a custom session expiration time.
* @public
* @param {number} timeInMillis - session expireation time in milliseconds.
*/
AmplitudeClient.prototype.setMinTimeBetweenSessionsMillis = function setMinTimeBetweenSessionsMillis(timeInMillis) {
if (!utils.validateInput(timeInMillis, 'timeInMillis', 'number')) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setMinTimeBetweenSessionsMillis'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.sessionTimeout = timeInMillis;
} catch (e) {
utils.log.error(e);
}
};

/**
* Sets minimum number of events to batch together per request if batchEvents is true.
* @public
* @param {number} eventUploadThreshold - The number of the event upload threshold. Default value is 30.
* @example amplitudeClient.setEventUploadThreshold(10);
*/
AmplitudeClient.prototype.setEventUploadThreshold = function setEventUploadThreshold(eventUploadThreshold) {
if (!utils.validateInput(eventUploadThreshold, 'eventUploadThreshold', 'number')) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setEventUploadThreshold'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.eventUploadThreshold = eventUploadThreshold;
} catch (e) {
utils.log.error(e);
}
};

/**
* Dynamically adjust server URL
* @public
* @param {bool} useDynamicConfig - if enable dynamic config or not.
* @example amplitudeClient.setUseDynamicConfig(true);
*/
AmplitudeClient.prototype.setUseDynamicConfig = function setUseDynamicConfig(useDynamicConfig) {
if (!utils.validateInput(useDynamicConfig, 'useDynamicConfig', 'boolean')) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setUseDynamicConfig'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.useDynamicConfig = useDynamicConfig;
this._refreshDynamicConfig();
} catch (e) {
utils.log.error(e);
}
};

/**
* Sets the server zone, used for server api endpoint and dynamic configuration.
* @public
* @param {string} serverZone - the server zone value. AmplitudeServerZone.US or AmplitudeServerZone.EU.
* @param {bool} serverZoneBasedApi - (optional) update api endpoint with serverZone change or not. For data residency, recommend to enable it unless using own proxy server.
* @example amplitudeClient.setServerZone('[email protected]', true);
*/
AmplitudeClient.prototype.setServerZone = function setServerZone(serverZone, serverZoneBasedApi = true) {
if (
(serverZone !== AmplitudeServerZone.EU && serverZone !== AmplitudeServerZone.US) ||
!utils.validateInput(serverZoneBasedApi, 'serverZoneBasedApi', 'boolean')
) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setServerZone'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.serverZone = serverZone;
this.options.serverZoneBasedApi = serverZoneBasedApi;
if (serverZoneBasedApi) {
this.options.apiEndpoint = getEventLogApi(this.options.serverZone);
}
} catch (e) {
utils.log.error(e);
}
};

/**
* Sets the server URL for the request.
* @public
* @param {string} serverUrl - The value of the server URL.
* @example amplitudeClient.setServerUrl('api.amplitude.com');
*/
AmplitudeClient.prototype.setServerUrl = function setServerUrl(serverUrl) {
if (!utils.validateInput(serverUrl, 'serverUrl', 'string')) {
return;
}

if (this._shouldDeferCall()) {
return this._q.push(['setServerUrl'].concat(Array.prototype.slice.call(arguments, 0)));
}

try {
this.options.apiEndpoint = serverUrl;
} catch (e) {
utils.log.error(e);
}
};

export default AmplitudeClient;
8 changes: 8 additions & 0 deletions src/amplitude-snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@
'logEventWithGroups',
'setSessionId',
'resetSessionId',
'getDeviceId',
'getUserId',
'setMinTimeBetweenSessionsMillis',
'setEventUploadThreshold',
'setUseDynamicConfig',
'setServerZone',
'setServerUrl',
'sendEvents',
'setLibrary',
];
function setUpProxy(instance) {
Expand Down
Loading