@@ -1364,50 +1364,51 @@ public void execute(@NonNull String viewName,
13641364 }
13651365 MParticle instance = MParticle .getInstance ();
13661366 MParticleUser user = instance .Identity ().getCurrentUser ();
1367- String email = attributes .get ("email" );
1367+ String email = getValueIgnoreCase (attributes , "email" );
1368+ String hashedEmail = getValueIgnoreCase (attributes , "emailsha256" );
13681369 Map <String , String > finalAttributes = attributes ;
1369- confirmEmail (email ,user ,instance .Identity (), () -> {
1370- JSONArray jsonArray = new JSONArray ();
1371-
1372- KitConfiguration kitConfig = provider .getConfiguration ();
1373- if (kitConfig != null ) {
1374- try {
1375- jsonArray = kitConfig .getPlacementAttributesMapping ();
1376- } catch (JSONException e ) {
1377- Logger .warning ("Invalid placementAttributes for kit: " + provider .getName () + " JSON: " + e .getMessage ());
1370+ confirmEmail (email , hashedEmail , user , instance .Identity (), () -> {
1371+ JSONArray jsonArray = new JSONArray ();
1372+
1373+ KitConfiguration kitConfig = provider .getConfiguration ();
1374+ if (kitConfig != null ) {
1375+ try {
1376+ jsonArray = kitConfig .getPlacementAttributesMapping ();
1377+ } catch (JSONException e ) {
1378+ Logger .warning ("Invalid placementAttributes for kit: " + provider .getName () + " JSON: " + e .getMessage ());
1379+ }
13781380 }
1379- }
1380- for ( int i = 0 ; i < jsonArray .length (); i ++) {
1381- JSONObject obj = jsonArray . optJSONObject ( i ) ;
1382- if ( obj == null ) continue ;
1383- String mapFrom = obj .optString ("map " );
1384- String mapTo = obj . optString ( "value" );
1385- if ( finalAttributes .containsKey (mapFrom )) {
1386- String value = finalAttributes .remove ( mapFrom );
1387- finalAttributes . put ( mapTo , value );
1381+ for ( int i = 0 ; i < jsonArray . length (); i ++) {
1382+ JSONObject obj = jsonArray .optJSONObject ( i );
1383+ if ( obj == null ) continue ;
1384+ String mapFrom = obj . optString ( "map" ) ;
1385+ String mapTo = obj .optString ("value " );
1386+ if ( finalAttributes . containsKey ( mapFrom )) {
1387+ String value = finalAttributes .remove (mapFrom );
1388+ finalAttributes .put ( mapTo , value );
1389+ }
13881390 }
1389- }
1390- Map <String , Object > objectAttributes = new HashMap <>();
1391- for (Map .Entry <String , String > entry : finalAttributes .entrySet ()) {
1392- if (!entry .getKey ().equals (Constants .MessageKey .SANDBOX_MODE_ROKT )) {
1393- objectAttributes .put (entry .getKey (), entry .getValue ());
1391+ Map <String , Object > objectAttributes = new HashMap <>();
1392+ for (Map .Entry <String , String > entry : finalAttributes .entrySet ()) {
1393+ if (!entry .getKey ().equals (Constants .MessageKey .SANDBOX_MODE_ROKT )) {
1394+ objectAttributes .put (entry .getKey (), entry .getValue ());
1395+ }
1396+ }
1397+ if (user != null ) {
1398+ user .setUserAttributes (objectAttributes );
13941399 }
1395- }
1396- if (user != null ) {
1397- user .setUserAttributes (objectAttributes );
1398- }
13991400
1400- if (!finalAttributes .containsKey (Constants .MessageKey .SANDBOX_MODE_ROKT )) {
1401- finalAttributes .put (Constants .MessageKey .SANDBOX_MODE_ROKT , String . valueOf ( Objects .toString (MPUtility .isDevEnv (), "false" ) )); // Default value is "false" if null
1402- }
1401+ if (!finalAttributes .containsKey (Constants .MessageKey .SANDBOX_MODE_ROKT )) {
1402+ finalAttributes .put (Constants .MessageKey .SANDBOX_MODE_ROKT , Objects .toString (MPUtility .isDevEnv (), "false" )); // Default value is "false" if null
1403+ }
14031404
1404- ((KitIntegration .RoktListener ) provider ).execute (viewName ,
1405- finalAttributes ,
1406- mpRoktEventCallback ,
1407- placeHolders ,
1408- fontTypefaces ,
1409- FilteredMParticleUser .getInstance (user .getId (), provider ),
1410- config );
1405+ ((KitIntegration .RoktListener ) provider ).execute (viewName ,
1406+ finalAttributes ,
1407+ mpRoktEventCallback ,
1408+ placeHolders ,
1409+ fontTypefaces ,
1410+ FilteredMParticleUser .getInstance (user .getId (), provider ),
1411+ config );
14111412 });
14121413 }
14131414 } catch (Exception e ) {
@@ -1416,6 +1417,15 @@ public void execute(@NonNull String viewName,
14161417 }
14171418 }
14181419
1420+ private String getValueIgnoreCase (Map <String , String > map , String searchKey ) {
1421+ for (Map .Entry <String , String > entry : map .entrySet ()) {
1422+ if (entry .getKey ().equalsIgnoreCase (searchKey )) {
1423+ return entry .getValue ();
1424+ }
1425+ }
1426+ return null ;
1427+ }
1428+
14191429 @ Override
14201430 public Flow <RoktEvent > events (@ NonNull String identifier ) {
14211431 for (KitIntegration provider : providers .values ()) {
@@ -1473,43 +1483,63 @@ public void close() {
14731483
14741484 private void confirmEmail (
14751485 @ Nullable String email ,
1486+ @ Nullable String hashedEmail ,
14761487 @ Nullable MParticleUser user ,
14771488 IdentityApi identityApi ,
14781489 Runnable runnable
14791490 ) {
1480- if (email != null && user != null ) {
1491+ boolean hasEmail = email != null && !email .isEmpty ();
1492+ boolean hasHashedEmail = hashedEmail != null && !hashedEmail .isEmpty ();
1493+
1494+ if ((hasEmail || hasHashedEmail ) && user != null ) {
14811495 String existingEmail = user .getUserIdentities ().get (MParticle .IdentityType .Email );
1496+ String existingHashedEmail = user .getUserIdentities ().get (MParticle .IdentityType .Other );
1497+
1498+ boolean emailMismatch = hasEmail && !email .equalsIgnoreCase (existingEmail );
1499+ boolean hashedEmailMismatch = hasHashedEmail && !hashedEmail .equalsIgnoreCase (existingHashedEmail );
14821500
1483- if (! email . equals ( existingEmail ) ) {
1501+ if (emailMismatch || hashedEmailMismatch ) {
14841502 // If there's an existing email but it doesn't match the passed-in email, log a warning
1485- if (existingEmail != null ) {
1486- Logger .warning ( String .format (
1503+ if (emailMismatch && existingEmail != null ) {
1504+ Logger .warning (String .format (
14871505 "The existing email on the user (%s) does not match the email passed to selectPlacements (%s). " +
14881506 "Please make sure to sync the email identity to mParticle as soon as it's available. " +
14891507 "Identifying user with the provided email before continuing to selectPlacements." ,
14901508 existingEmail , email
14911509 ));
14921510 }
1511+ // If there's an existing other but it doesn't match the passed-in hashed email, log a warning
1512+ else if (hashedEmailMismatch && existingHashedEmail != null ) {
1513+ Logger .warning (String .format (
1514+ "The existing hashed email on the user (%s) does not match the hashed email passed to selectPlacements (%s). " +
1515+ "Please make sure to sync the hashed email identity to mParticle as soon as it's available. " +
1516+ "Identifying user with the provided hashed email before continuing to selectPlacements." ,
1517+ existingHashedEmail , hashedEmail
1518+ ));
1519+ }
14931520
1494- IdentityApiRequest identityRequest = IdentityApiRequest .withUser (user )
1495- .email (email )
1496- .build ();
1521+ IdentityApiRequest .Builder identityBuilder = IdentityApiRequest .withUser (user );
1522+ if (emailMismatch ) {
1523+ identityBuilder .email (email );
1524+ }
1525+ if (hashedEmailMismatch ) {
1526+ identityBuilder .userIdentity (MParticle .IdentityType .Other , hashedEmail );
1527+ }
1528+
1529+ IdentityApiRequest identityRequest = identityBuilder .build ();
14971530 MParticleTask <IdentityApiResult > task = identityApi .identify (identityRequest );
1498- task .addFailureListener (new TaskFailureListener () {
1499- @ Override
1500- public void onFailure (IdentityHttpResponse result ) {
1501- Logger .error ( "Failed to sync email from selectPlacement to user: " + result .getErrors ().toString ());
15021531
1503- runnable .run ();
1504- }
1532+ task .addFailureListener (result -> {
1533+ Logger .error ("Failed to sync email from selectPlacement to user: " + result .getErrors ());
1534+ runnable .run ();
15051535 });
1506- task .addSuccessListener (new TaskSuccessListener () {
1507- @ Override
1508- public void onSuccess (IdentityApiResult result ) {
1509- Logger .debug ("Updated email identity based on selectPlacement's attributes: " + result .getUser ().getUserIdentities ().get (MParticle .IdentityType .Email ));
1510- runnable .run ();
1511- }
1536+
1537+ task .addSuccessListener (result -> {
1538+ Logger .debug ("Updated email identity based on selectPlacement's attributes: " +
1539+ result .getUser ().getUserIdentities ().get (MParticle .IdentityType .Email ));
1540+ runnable .run ();
15121541 });
1542+
15131543 } else {
15141544 runnable .run ();
15151545 }
0 commit comments