@@ -157,13 +157,16 @@ Amplitude.prototype._eventId = 0;
157157Amplitude . prototype . _sending = false ;
158158Amplitude . prototype . _lastEventTime = null ;
159159Amplitude . prototype . _sessionId = null ;
160+ Amplitude . prototype . _newSession = false ;
160161
161162/**
162163 * Initializes Amplitude.
163164 * apiKey The API Key for your app
164165 * opt_userId An identifier for this user
165166 * opt_config Configuration options
166167 * - saveEvents (boolean) Whether to save events to local storage. Defaults to true.
168+ * - utmParams (string) Optional utm data in query string format.
169+ * Pulled from location.search otherwise.
167170 */
168171Amplitude . prototype . init = function ( apiKey , opt_userId , opt_config ) {
169172 try {
@@ -211,11 +214,16 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config) {
211214 this . sendEvents ( ) ;
212215 }
213216
217+ // Parse the utm properties out of cookies and query for adding to user properties.
218+ var utmParams = opt_config && opt_config . utmParams || location . search ;
219+ this . _utmProperties = Amplitude . _getUtmData ( Cookie . get ( '__utmz' ) , utmParams ) ;
220+
214221 this . _lastEventTime = parseInt ( localStorage . getItem ( LocalStorageKeys . LAST_EVENT_TIME ) ) || null ;
215222 this . _sessionId = parseInt ( localStorage . getItem ( LocalStorageKeys . SESSION_ID ) ) || null ;
216223 this . _eventId = localStorage . getItem ( LocalStorageKeys . LAST_EVENT_ID ) || 0 ;
217224 var now = new Date ( ) . getTime ( ) ;
218225 if ( ! this . _sessionId || ! this . _lastEventTime || now - this . _lastEventTime > this . options . sessionTimeout ) {
226+ this . _newSession = true ;
219227 this . _sessionId = now ;
220228 localStorage . setItem ( LocalStorageKeys . SESSION_ID , this . _sessionId ) ;
221229 }
@@ -226,6 +234,10 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config) {
226234 }
227235} ;
228236
237+ Amplitude . prototype . isNewSession = function ( ) {
238+ return this . _newSession ;
239+ } ;
240+
229241Amplitude . prototype . nextEventId = function ( ) {
230242 this . _eventId ++ ;
231243 return this . _eventId ;
@@ -254,6 +266,31 @@ var _saveCookieData = function(scope) {
254266 } ) ;
255267} ;
256268
269+ Amplitude . _getUtmParam = function ( name , query ) {
270+ name = name . replace ( / [ \[ ] / , "\\[" ) . replace ( / [ \] ] / , "\\]" ) ;
271+ var regex = new RegExp ( "[\\?&]" + name + "=([^&#]*)" ) ;
272+ var results = regex . exec ( query ) ;
273+ return results === null ? undefined : decodeURIComponent ( results [ 1 ] . replace ( / \+ / g, " " ) ) ;
274+ } ;
275+
276+ Amplitude . _getUtmData = function ( rawCookie , query ) {
277+ // Translate the utmz cookie format into url query string format.
278+ var cookie = rawCookie ? '?' + rawCookie . split ( '.' ) . slice ( - 1 ) [ 0 ] . replace ( / \| / g, '&' ) : '' ;
279+
280+ var fetchParam = function ( queryName , query , cookieName , cookie ) {
281+ return Amplitude . _getUtmParam ( queryName , query ) ||
282+ Amplitude . _getUtmParam ( cookieName , cookie ) ;
283+ } ;
284+
285+ return {
286+ utm_source : fetchParam ( 'utm_source' , query , 'utmcsr' , cookie ) ,
287+ utm_medium : fetchParam ( 'utm_medium' , query , 'utmcmd' , cookie ) ,
288+ utm_campaign : fetchParam ( 'utm_campaign' , query , 'utmccn' , cookie ) ,
289+ utm_term : fetchParam ( 'utm_term' , query , 'utmctr' , cookie ) ,
290+ utm_content : fetchParam ( 'utm_content' , query , 'utmcct' , cookie ) ,
291+ } ;
292+ } ;
293+
257294Amplitude . prototype . saveEvents = function ( ) {
258295 try {
259296 localStorage . setItem ( this . options . unsentKey , JSON . stringify ( this . _unsentEvents ) ) ;
@@ -336,6 +373,11 @@ Amplitude.prototype.logEvent = function(eventType, eventProperties) {
336373 localStorage . setItem ( LocalStorageKeys . LAST_EVENT_TIME , this . _lastEventTime ) ;
337374 localStorage . setItem ( LocalStorageKeys . LAST_EVENT_ID , eventId ) ;
338375
376+ // Add the utm properties, if any, onto the user properties.
377+ var userProperties = { } ;
378+ object . merge ( userProperties , this . options . userProperties || { } , this . _utmProperties ) ;
379+ object . merge ( userProperties , this . _utmProperties ) ;
380+
339381 eventProperties = eventProperties || { } ;
340382 var event = {
341383 device_id : this . options . deviceId ,
@@ -351,7 +393,7 @@ Amplitude.prototype.logEvent = function(eventType, eventProperties) {
351393 device_model : ua . os . family ,
352394 language : this . options . language ,
353395 event_properties : eventProperties ,
354- user_properties : this . options . userProperties || { } ,
396+ user_properties : userProperties ,
355397 uuid : UUID ( ) ,
356398 library : {
357399 name : 'amplitude-js' ,
0 commit comments