|
13 | 13 | // See the License for the specific language governing permissions and |
14 | 14 | // limitations under the License. |
15 | 15 |
|
| 16 | +// ** Glossary of terms |
| 17 | +// Mixpanel Terms: |
| 18 | +// user_id: A unique identifier used by the Mixpanel.identify method to identify a unique user. This will map to what an mParticle customer selects in the UI, which translates to the forwarderSettings.userIdentificationType. |
| 19 | +// device_id: A unique identifier used by Mixpanel to identify an anonymous user, usually a guid. mParticle and Mixpnael generate their own device ids. |
| 20 | +// distinct_id: A unique identifier that Mixpanel uses to bridge a user and a device. Usually the |
| 21 | +// distinct_id has a prefix of $device:guid<device_id> to denote an anonymouse user |
| 22 | +// and this will be replaced by the user_id once the user has been identified by |
| 23 | +// a request to Mixpanel.identify |
| 24 | + |
16 | 25 | // eslint-disable-next-line no-redeclare |
17 | 26 | var name = 'MixpanelEventForwarder', |
18 | 27 | moduleId = 10, |
@@ -137,11 +146,89 @@ var constructor = function () { |
137 | 146 | } |
138 | 147 | } |
139 | 148 |
|
140 | | - function onUserIdentified(user) { |
141 | | - var idForMixpanel; |
142 | | - var userIdentities = user.getUserIdentities() |
| 149 | + function getUserIdentities(user) { |
| 150 | + return user.getUserIdentities() |
143 | 151 | ? user.getUserIdentities().userIdentities |
144 | 152 | : {}; |
| 153 | + } |
| 154 | + |
| 155 | + function onLoginComplete(user) { |
| 156 | + var userIdentities = getUserIdentities(user); |
| 157 | + |
| 158 | + // When mParticle identifies a user, the user might |
| 159 | + // actually be anonymous. We only want to send an |
| 160 | + // identify request to Mixpanel if the user is |
| 161 | + // actually known. Only known (logged in) users |
| 162 | + // will have userIdentities. |
| 163 | + if (!isEmpty(userIdentities)) { |
| 164 | + sendIdentifyRequest(user, userIdentities); |
| 165 | + } else { |
| 166 | + return 'Logged in user does not have user identities and will not be sent to Mixpanel to Identify'; |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + function onLogoutComplete() { |
| 171 | + // For all Identity Requests, we run mixpanel.identify(<user_id>) |
| 172 | + // as per Mixpanel's documentation https://docs.mixpanel.com/docs/tracking-methods/identifying-users |
| 173 | + // except when a user logs out, where we run mixpanel.reset() to |
| 174 | + // detach the Mixpanel distinct_id from the Mixpanel device_id |
| 175 | + |
| 176 | + if (!isInitialized) { |
| 177 | + return ( |
| 178 | + 'Cannot call logout on forwarder: ' + name + ', not initialized' |
| 179 | + ); |
| 180 | + } |
| 181 | + |
| 182 | + try { |
| 183 | + mixpanel.mparticle.reset(); |
| 184 | + |
| 185 | + return 'Successfully called reset on forwarder: ' + name; |
| 186 | + } catch (e) { |
| 187 | + return 'Cannot call reset on forwarder: ' + name + ': ' + e; |
| 188 | + } |
| 189 | + } |
| 190 | + |
| 191 | + function onIdentifyComplete(user) { |
| 192 | + // Mixpanel considers any user with an identity to be a known user. |
| 193 | + // In mParticle, a user will always have an MPID even if they are anonymous. |
| 194 | + // When mParticle identifies a user, because the user might |
| 195 | + // actually be anonymous, we only want to send an |
| 196 | + // identify request to Mixpanel if the user is |
| 197 | + // actually known. If a user has any user identities, they are |
| 198 | + // considered to be "known" users. |
| 199 | + var userIdentities = getUserIdentities(user); |
| 200 | + |
| 201 | + if (!isEmpty(userIdentities)) { |
| 202 | + sendIdentifyRequest(user, userIdentities); |
| 203 | + } else { |
| 204 | + return 'Identified user does not have user identities and will not be sent to Mixpanel to Identify'; |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + function onModifyComplete(user) { |
| 209 | + // Mixpanel does not have the concept of modifying a |
| 210 | + // user's identity. For the time being, we will rely on |
| 211 | + // doing a simple Mixpanel.identify request for backwards compatibility. However |
| 212 | + // this method may be deprecated in a future release |
| 213 | + var userIdentities = getUserIdentities(user); |
| 214 | + |
| 215 | + if (!isEmpty(userIdentities)) { |
| 216 | + sendIdentifyRequest(user, userIdentities); |
| 217 | + } else { |
| 218 | + return 'Modified user does not have user identities and will not be sent to Mixpanel to Identify'; |
| 219 | + } |
| 220 | + } |
| 221 | + |
| 222 | + function sendIdentifyRequest(user, userIdentities) { |
| 223 | + // We should only make Mixpanel.identify requests |
| 224 | + // when a user has userIdentities and is therefore |
| 225 | + // a known mParticle user and not anonymous |
| 226 | + if (isEmpty(userIdentities)) { |
| 227 | + return; |
| 228 | + } |
| 229 | + |
| 230 | + var idForMixpanel; |
| 231 | + |
145 | 232 | switch (forwarderSettings.userIdentificationType) { |
146 | 233 | case 'CustomerId': |
147 | 234 | idForMixpanel = userIdentities.customerid; |
@@ -245,8 +332,12 @@ var constructor = function () { |
245 | 332 | this.process = processEvent; |
246 | 333 | this.setUserAttribute = setUserAttribute; |
247 | 334 | this.setUserIdentity = setUserIdentity; |
248 | | - this.onUserIdentified = onUserIdentified; |
249 | 335 | this.removeUserAttribute = removeUserAttribute; |
| 336 | + |
| 337 | + this.onIdentifyComplete = onIdentifyComplete; |
| 338 | + this.onLoginComplete = onLoginComplete; |
| 339 | + this.onLogoutComplete = onLogoutComplete; |
| 340 | + this.onModifyComplete = onModifyComplete; |
250 | 341 | }; |
251 | 342 |
|
252 | 343 | function getId() { |
@@ -283,6 +374,10 @@ function register(config) { |
283 | 374 | ); |
284 | 375 | } |
285 | 376 |
|
| 377 | +function isEmpty(value) { |
| 378 | + return value == null || !(Object.keys(value) || value).length; |
| 379 | +} |
| 380 | + |
286 | 381 | function isObject(val) { |
287 | 382 | return ( |
288 | 383 | val != null && typeof val === 'object' && Array.isArray(val) === false |
|
0 commit comments