Skip to content

Commit 653a3ea

Browse files
committed
update readme and validate groups
1 parent 356d038 commit 653a3ea

File tree

11 files changed

+207
-72
lines changed

11 files changed

+207
-72
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,15 @@ This SDK automatically grabs useful data about the browser, including browser ty
251251

252252
### Setting Groups ###
253253

254-
Amplitude supports assigning users to groups, and performing queries such as count by distinct on those groups. An example would be if you want to group your users based on what organization they are in (based on something like an orgId). For example you can designate user Joe to be in orgId 10, while Sue is in orgId 15. When performing an event segmentation query, you can then select Count By: orgId, to query the number of different orgIds that have performed a specific event. As long as at least one member of that group has performed the specific event, that group will be included in the count. See our help article on [Count By Distinct]() for more information.
254+
Amplitude supports assigning users to groups, and performing queries such as Count by Distinct on those groups. An example would be if you want to group your users based on what organization they are in by using an orgId. You can designate Joe to be in orgId 10, while Sue is in orgId 15. When performing an event segmentation query, you can then select Count by Distinct orgIds to query the number of different orgIds that have performed a specific event. As long as at least one member of that group has performed the specific event, that group will be included in the count. See our help article on [Count By Distinct]() for more information.
255255

256-
In the above example, 'orgId' is a `groupType`, and the value 10 or 15 is the `groupName`. Another example of a `groupType` could a sport that the user participates in, and possible `groupNames` within that type would be tennis, baseball, etc.
256+
When setting groups you need to define a `groupType` and `groupName`(s). In the above example, 'orgId' is a `groupType`, and the value 10 or 15 is the `groupName`. Another example of a `groupType` could be 'sport' with `groupNames` like 'tennis', 'baseball', etc.
257257

258-
You can use `setGroup(groupType, groupName)` to designate which groups a user belongs to. Few things to note: this will also set the `groupType: groupName` as a user property. **This will overwrite any existing groupName value set for that user's groupType, as well as the corresponding user property value.** For example if Joe was in orgId 10, and you call `setGroup('orgId', 20)`, 20 would replace 10. You can also call `setGroup` multiple times with different groupTypes to add a user to different groups. For example Sue can be in orgId: 15, and she also plays sport: soccer. Now when querying, you can Count By both orgId and sport (although as separate queries). **You are allowed to set up to 5 different groupTypes per user.** Any more than that will be ignored from the Count By Distinct query UI, although they will still appear as user properties for that user.
258+
You can use `setGroup(groupType, groupName)` to designate which groups a user belongs to. Note: this will also set the `groupType`: `groupName` as a user property. **This will overwrite any existing groupName value set for that user's groupType, as well as the corresponding user property value.** `groupType` is a string, and `groupName` can be either a string or an array of strings to indicate a user being in multiple groups (for example Joe is in orgId 10 and 16, so the `groupName` would be [10, 16]).
259259

260260
```javascript
261-
amplitude.setGroup('orgId', 15);
262-
amplitude.setGroup('sport', 'tennis');
261+
amplitude.setGroup('orgId', '15');
262+
amplitude.setGroup('sport', ['soccer', 'tennis']);
263263
```
264264

265265
You can also use `logEventWithGroups` to set event-level groups, meaning the group designation only applies for the specific event being logged and does not persist on the user (unless you explicitly set it with `setGroup`).

amplitude.js

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ Amplitude.prototype.init = function init(apiKey, opt_userId, opt_config, opt_cal
199199
var eventProperties = this._unsentEvents[i].event_properties;
200200
var groups = this._unsentEvents[i].groups;
201201
this._unsentEvents[i].event_properties = utils.validateProperties(eventProperties);
202-
this._unsentEvents[i].groups = utils.validateProperties(groups);
202+
this._unsentEvents[i].groups = utils.validateGroups(groups);
203203
}
204204

205205
// validate user properties for unsent identifys
206206
for (var j = 0; j < this._unsentIdentifys.length; j++) {
207207
var userProperties = this._unsentIdentifys[j].user_properties;
208208
var identifyGroups = this._unsentIdentifys[j].groups;
209209
this._unsentIdentifys[j].user_properties = utils.validateProperties(userProperties);
210-
this._unsentIdentifys[j].groups = utils.validateProperties(identifyGroups);
210+
this._unsentIdentifys[j].groups = utils.validateGroups(identifyGroups);
211211
}
212212

213213
this._sendEventsIfReady(); // try sending unsent events
@@ -661,16 +661,17 @@ Amplitude.prototype.setUserId = function setUserId(userId) {
661661
};
662662

663663
/**
664-
* Designate which groups a user belongs to. Note: this will also set groupType:
665-
* groupName as a user property. You can call setGroup multiple times with different groupTypes to
666-
* add a user to different groups. Note: each user is allowed to be in up to 5 groups. Any more
667-
* than that will be ignored from the Count by Distinct query UI, although they will still appear
668-
* in the the user properties for that user.
669-
* See the [SDK Readme]{@link https://github.com/amplitude/Amplitude-Javascript##setting-groups} for more information.
664+
* Add user to a group or groups. You need to specify a groupType and groupName(s).
665+
* For example you can group people by their organization.
666+
* In that case groupType is "orgId" and groupName would be the actual ID(s).
667+
* groupName can be a string or an array of strings to indicate a user in multiple gruups.
668+
* You can also call setGroup multiple times with different groupTypes to track multiple types of groups (up to 5 per app).
669+
* Note: this will also set groupType: groupName as a user property.
670+
* See the [SDK Readme]{@link https://github.com/amplitude/Amplitude-Javascript#setting-groups} for more information.
670671
* @public
671672
* @param {string} groupType - the group type (ex: orgId)
672-
* @param {string} groupName - the name of the group (ex: 15)
673-
* @example: amplitude.setGroup('orgId', 15); // this adds the current user to orgId 15.
673+
* @param {string|list} groupName - the name of the group (ex: 15), or a list of names of the groups
674+
* @example amplitude.setGroup('orgId', 15); // this adds the current user to orgId 15.
674675
*/
675676
Amplitude.prototype.setGroup = function(groupType, groupName) {
676677
if (!this._apiKeySet('setGroup()') || !utils.validateInput(groupType, 'groupType', 'string') ||
@@ -680,7 +681,6 @@ Amplitude.prototype.setGroup = function(groupType, groupName) {
680681

681682
var groups = {};
682683
groups[groupType] = groupName;
683-
684684
var identify = new Identify().set(groupType, groupName);
685685
this._logEvent(Constants.IDENTIFY_EVENT, null, null, identify.userPropertiesOperations, groups, null);
686686
};
@@ -814,7 +814,7 @@ Amplitude.prototype.identify = function(identify_obj, opt_callback) {
814814
/**
815815
* Set a versionName for your application.
816816
* @public
817-
* @param {string} versionName
817+
* @param {string} versionName - The version to set for your application.
818818
* @example amplitude.setVersionName('1.12.3');
819819
*/
820820
Amplitude.prototype.setVersionName = function setVersionName(versionName) {
@@ -878,7 +878,7 @@ Amplitude.prototype._logEvent = function _logEvent(eventType, eventProperties, a
878878
version: version
879879
},
880880
sequence_number: sequenceNumber, // for ordering events and identifys
881-
groups: utils.truncate(utils.validateProperties(groups))
881+
groups: utils.truncate(utils.validateGroups(groups))
882882
// country: null
883883
};
884884

@@ -946,15 +946,16 @@ Amplitude.prototype.logEvent = function logEvent(eventType, eventProperties, opt
946946
* Log an event with eventType, eventProperties, and groups. Use this to set event-level groups.
947947
* Note: the group(s) set only apply for the specific event type being logged and does not persist on the user
948948
* (unless you explicitly set it with setGroup).
949-
* See the [SDK Readme]{@link https://github.com/amplitude/Amplitude-Javascript##setting-groups} for more information
949+
* See the [SDK Readme]{@link https://github.com/amplitude/Amplitude-Javascript#setting-groups} for more information
950950
* about groups and Count by Distinct on the Amplitude platform.
951951
* @public
952952
* @param {string} eventType - name of event
953953
* @param {object} eventProperties - (optional) an object with string keys and values for the event properties.
954-
* @param (object) groups - (optional) an object with string groupType: groupName values for the event being logged.
954+
* @param {object} groups - (optional) an object with string groupType: groupName values for the event being logged.
955+
* groupName can be a string or an array of strings.
955956
* @param {Amplitude~eventCallback} opt_callback - (optional) a callback function to run after the event is logged.
956957
* Note: the server response code and response body from the event upload are passed to the callback function.
957-
* @example amplitude.logEvent('Clicked Homepage Button', {'finished_flow': false, 'clicks': 15});
958+
* @example amplitude.logEventWithGroups('Clicked Button', null, {'orgId': 24});
958959
*/
959960
Amplitude.prototype.logEventWithGroups = function(eventType, eventProperties, groups, opt_callback) {
960961
if (!this._apiKeySet('logEventWithGroup()') ||
@@ -2294,8 +2295,8 @@ var validateProperties = function validateProperties(properties) {
22942295
var key = property;
22952296
var keyType = type(key);
22962297
if (keyType !== 'string') {
2297-
log('WARNING: Non-string property key, received type ' + keyType + ', coercing to string "' + key + '"');
22982298
key = String(key);
2299+
log('WARNING: Non-string property key, received type ' + keyType + ', coercing to string "' + key + '"');
22992300
}
23002301

23012302
// validate value
@@ -2339,11 +2340,76 @@ var validatePropertyValue = function validatePropertyValue(key, value) {
23392340
return value;
23402341
};
23412342

2343+
var validateGroups = function validateGroups(groups) {
2344+
var groupsType = type(groups);
2345+
if (groupsType !== 'object') {
2346+
log('Error: invalid groups format. Expecting Javascript object, received ' + groupsType + ', ignoring');
2347+
return {};
2348+
}
2349+
2350+
var copy = {}; // create a copy with all of the valid properties
2351+
for (var group in groups) {
2352+
if (!groups.hasOwnProperty(group)) {
2353+
continue;
2354+
}
2355+
2356+
// validate key
2357+
var key = group;
2358+
var keyType = type(key);
2359+
if (keyType !== 'string') {
2360+
key = String(key);
2361+
log('WARNING: Non-string groupType, received type ' + keyType + ', coercing to string "' + key + '"');
2362+
}
2363+
2364+
// validate value
2365+
var value = validateGroupName(key, groups[group]);
2366+
if (value === null) {
2367+
continue;
2368+
}
2369+
copy[key] = value;
2370+
}
2371+
return copy;
2372+
};
2373+
2374+
var validateGroupName = function validateGroupName(key, groupName) {
2375+
var groupNameType = type(groupName);
2376+
if (groupNameType === 'string') {
2377+
return groupName;
2378+
}
2379+
if (groupNameType === 'date' || groupNameType === 'number' || groupNameType === 'boolean') {
2380+
groupName = String(groupName);
2381+
log('WARNING: Non-string groupName, received type ' + groupNameType + ', coercing to string "' + groupName + '"');
2382+
return groupName;
2383+
}
2384+
if (groupNameType === 'array') {
2385+
// check for nested arrays or objects
2386+
var arrayCopy = [];
2387+
for (var i = 0; i < groupName.length; i++) {
2388+
var element = groupName[i];
2389+
var elemType = type(element);
2390+
if (elemType === 'array' || elemType === 'object') {
2391+
log('WARNING: Skipping nested ' + elemType + ' in array groupName');
2392+
continue;
2393+
} else if (elemType === 'string') {
2394+
arrayCopy.push(element);
2395+
} else if (elemType === 'date' || elemType === 'number' || elemType === 'boolean') {
2396+
element = String(element);
2397+
log('WARNING: Non-string groupName, received type ' + elemType + ', coercing to string "' + element + '"');
2398+
arrayCopy.push(element);
2399+
}
2400+
}
2401+
return arrayCopy;
2402+
}
2403+
log('WARNING: Non-string groupName, received type ' + groupNameType +
2404+
'. Please use strings or array of strings for groupName');
2405+
};
2406+
23422407
module.exports = {
23432408
log: log,
23442409
isEmptyString: isEmptyString,
23452410
sessionStorageEnabled: sessionStorageEnabled,
23462411
truncate: truncate,
2412+
validateGroups: validateGroups,
23472413
validateInput: validateInput,
23482414
validateProperties: validateProperties
23492415
};

amplitude.min.js

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

documentation/Amplitude.html

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ <h4 class="name" id="__VERSION__"><span class="type-signature"></span>__VERSION_
184184

185185
<dt class="tag-source">Source:</dt>
186186
<dd class="tag-source"><ul class="dummy"><li>
187-
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line1068">line 1068</a>
187+
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line1069">line 1069</a>
188188
</li></ul></dd>
189189

190190

@@ -1173,7 +1173,8 @@ <h5>Parameters:</h5>
11731173

11741174

11751175

1176-
<td class="description last">(optional) an object with string groupType: groupName values for the event being logged.</td>
1176+
<td class="description last">(optional) an object with string groupType: groupName values for the event being logged.
1177+
groupName can be a string or an array of strings.</td>
11771178
</tr>
11781179

11791180

@@ -1238,7 +1239,7 @@ <h5>Parameters:</h5>
12381239

12391240
<dt class="tag-source">Source:</dt>
12401241
<dd class="tag-source"><ul class="dummy"><li>
1241-
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line853">line 853</a>
1242+
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line854">line 854</a>
12421243
</li></ul></dd>
12431244

12441245

@@ -1420,7 +1421,7 @@ <h5>Parameters:</h5>
14201421

14211422
<dt class="tag-source">Source:</dt>
14221423
<dd class="tag-source"><ul class="dummy"><li>
1423-
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line880">line 880</a>
1424+
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line881">line 881</a>
14241425
</li></ul></dd>
14251426

14261427

@@ -1783,7 +1784,7 @@ <h4 class="name" id="setGlobalUserProperties"><span class="type-signature"></spa
17831784

17841785
<dt class="tag-source">Source:</dt>
17851786
<dd class="tag-source"><ul class="dummy"><li>
1786-
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line1058">line 1058</a>
1787+
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line1059">line 1059</a>
17871788
</li></ul></dd>
17881789

17891790

@@ -1821,11 +1822,12 @@ <h4 class="name" id="setGroup"><span class="type-signature"></span>setGroup<span
18211822

18221823

18231824
<div class="description">
1824-
Designate which groups a user belongs to. Note: this will also set groupType:
1825-
groupName as a user property. You can call setGroup multiple times with different groupTypes to
1826-
add a user to different groups. Note: each user is allowed to be in up to 5 groups. Any more
1827-
than that will be ignored from the Count by Distinct query UI, although they will still appear
1828-
in the the user properties for that user.
1825+
Add user to a group or groups. You need to specify a groupType and groupName(s).
1826+
For example you can group people by their organization.
1827+
In that case groupType is "orgId" and groupName would be the actual ID(s).
1828+
groupName can be a string or an array of strings to indicate a user in multiple gruups.
1829+
You can also call setGroup multiple times with different groupTypes to track multiple types of groups (up to 5 per app).
1830+
Note: this will also set groupType: groupName as a user property.
18291831
See the <a href="https://github.com/amplitude/Amplitude-Javascript#setting-groups">SDK Readme</a> for more information.
18301832
</div>
18311833

@@ -1891,16 +1893,10 @@ <h5>Parameters:</h5>
18911893
<td class="type">
18921894

18931895

1894-
<span class="param-type">number</span>
1895-
|
1896-
18971896
<span class="param-type">string</span>
18981897
|
18991898

19001899
<span class="param-type">list</span>
1901-
|
1902-
1903-
<span class="param-type">object</span>
19041900

19051901

19061902

@@ -1910,7 +1906,7 @@ <h5>Parameters:</h5>
19101906

19111907

19121908

1913-
<td class="description last">the name of the group (ex: 15)</td>
1909+
<td class="description last">the name of the group (ex: 15), or a list of names of the groups</td>
19141910
</tr>
19151911

19161912

@@ -1951,7 +1947,7 @@ <h5>Parameters:</h5>
19511947

19521948
<dt class="tag-source">Source:</dt>
19531949
<dd class="tag-source"><ul class="dummy"><li>
1954-
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line569">line 569</a>
1950+
<a href="amplitude.js.html">amplitude.js</a>, <a href="amplitude.js.html#line570">line 570</a>
19551951
</li></ul></dd>
19561952

19571953

@@ -2726,7 +2722,7 @@ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Amplitude
27262722
<br class="clear">
27272723

27282724
<footer>
2729-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Wed Apr 06 2016 01:23:04 GMT-0700 (PDT)
2725+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Thu Apr 07 2016 00:36:52 GMT-0700 (PDT)
27302726
</footer>
27312727

27322728
<script> prettyPrint(); </script>

documentation/Identify.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Amplitude
12951295
<br class="clear">
12961296

12971297
<footer>
1298-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Wed Apr 06 2016 01:23:04 GMT-0700 (PDT)
1298+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Thu Apr 07 2016 00:36:52 GMT-0700 (PDT)
12991299
</footer>
13001300

13011301
<script> prettyPrint(); </script>

0 commit comments

Comments
 (0)