@@ -4,6 +4,7 @@ import android.graphics.Typeface
44import com.mparticle.MParticle
55import com.mparticle.MpRoktEventCallback
66import com.mparticle.RoktEvent
7+ import com.mparticle.TypedUserAttributeListener
78import com.mparticle.identity.IdentityApi
89import com.mparticle.identity.IdentityApiRequest
910import com.mparticle.identity.MParticleUser
@@ -50,17 +51,20 @@ internal class RoktKitApiImpl(private val roktListener: KitIntegration.RoktListe
5051 val kitConfig = kitIntegration.configuration
5152
5253 confirmEmail(email, hashedEmail, user, instance.Identity (), kitConfig) {
53- val finalAttributes = prepareAttributes(mutableAttributes, user)
54- roktListener.selectPlacements(
55- viewName,
56- finalAttributes,
57- mpRoktEventCallback,
58- placeHolders,
59- fontTypefaces,
60- FilteredMParticleUser .getInstance(user?.id ? : 0L , kitIntegration),
61- config,
62- options,
63- )
54+ val finalAttributes = applyPlacementAttributeMapping(mutableAttributes)
55+ setRoktAttributesOnUser(finalAttributes, user) {
56+ ensureSandboxMode(finalAttributes)
57+ roktListener.selectPlacements(
58+ viewName,
59+ finalAttributes,
60+ mpRoktEventCallback,
61+ placeHolders,
62+ fontTypefaces,
63+ FilteredMParticleUser .getInstance(user?.id ? : 0L , kitIntegration),
64+ config,
65+ options,
66+ )
67+ }
6468 }
6569 } catch (e: Exception ) {
6670 Logger .warning(" Failed to call execute for Rokt Kit: ${e.message} " )
@@ -115,16 +119,19 @@ internal class RoktKitApiImpl(private val roktListener: KitIntegration.RoktListe
115119 return
116120 }
117121 val user = instance.Identity ().currentUser
118- val email = mutableAttributes[ " email" ]
122+ val email = getValueIgnoreCase( mutableAttributes, " email" )
119123 val hashedEmail = getValueIgnoreCase(mutableAttributes, " emailsha256" )
120124 val kitConfig = kitIntegration.configuration
121125
122126 confirmEmail(email, hashedEmail, user, instance.Identity (), kitConfig) {
123- val finalAttributes = prepareAttributes(mutableAttributes, user)
124- roktListener.enrichAttributes(
125- finalAttributes,
126- FilteredMParticleUser .getInstance(user?.id ? : 0L , kitIntegration),
127- )
127+ val finalAttributes = applyPlacementAttributeMapping(mutableAttributes)
128+ setRoktAttributesOnUser(finalAttributes, user) {
129+ ensureSandboxMode(finalAttributes)
130+ roktListener.enrichAttributes(
131+ finalAttributes,
132+ FilteredMParticleUser .getInstance(user?.id ? : 0L , kitIntegration),
133+ )
134+ }
128135 }
129136 } catch (e: Exception ) {
130137 Logger .warning(" Failed to call prepareAttributesAsync for Rokt Kit: ${e.message} " )
@@ -142,7 +149,7 @@ internal class RoktKitApiImpl(private val roktListener: KitIntegration.RoktListe
142149 return null
143150 }
144151
145- private fun prepareAttributes ( finalAttributes : MutableMap <String , String >, user : MParticleUser ? ): MutableMap <String , String > {
152+ private fun applyPlacementAttributeMapping ( attributes : MutableMap <String , String >): MutableMap <String , String > {
146153 val kitConfig = kitIntegration.configuration
147154 val jsonArray = try {
148155 kitConfig?.placementAttributesMapping ? : org.json.JSONArray ()
@@ -155,27 +162,49 @@ internal class RoktKitApiImpl(private val roktListener: KitIntegration.RoktListe
155162 val obj = jsonArray.optJSONObject(i) ? : continue
156163 val mapFrom = obj.optString(" map" )
157164 val mapTo = obj.optString(" value" )
158- if (finalAttributes .containsKey(mapFrom)) {
159- val value = finalAttributes .remove(mapFrom)
165+ if (attributes .containsKey(mapFrom)) {
166+ val value = attributes .remove(mapFrom)
160167 if (value != null ) {
161- finalAttributes [mapTo] = value
168+ attributes [mapTo] = value
162169 }
163170 }
164171 }
172+ return attributes
173+ }
165174
175+ private fun ensureSandboxMode (finalAttributes : MutableMap <String , String >) {
176+ if (! finalAttributes.containsKey(Constants .MessageKey .SANDBOX_MODE_ROKT )) {
177+ finalAttributes[Constants .MessageKey .SANDBOX_MODE_ROKT ] =
178+ Objects .toString(MPUtility .isDevEnv(), " false" )
179+ }
180+ }
181+
182+ /* *
183+ * Persists placement attributes on the mParticle user, then invokes [onReady] after the
184+ * attributes have been applied. This ensures the Rokt kit reads an up-to-date user profile
185+ * when merging attributes for the placement.
186+ */
187+ private fun setRoktAttributesOnUser (
188+ finalAttributes : Map <String , String >,
189+ user : MParticleUser ? ,
190+ onReady : Runnable ,
191+ ) {
166192 val objectAttributes = mutableMapOf<String , Any >()
167193 for ((key, value) in finalAttributes) {
168194 if (key != Constants .MessageKey .SANDBOX_MODE_ROKT ) {
169195 objectAttributes[key] = value
170196 }
171197 }
172- user?.setUserAttributes(objectAttributes)
173-
174- if (! finalAttributes.containsKey(Constants .MessageKey .SANDBOX_MODE_ROKT )) {
175- finalAttributes[Constants .MessageKey .SANDBOX_MODE_ROKT ] =
176- Objects .toString(MPUtility .isDevEnv(), " false" )
198+ if (user != null ) {
199+ user.setUserAttributes(objectAttributes)
200+ user.getUserAttributes(
201+ TypedUserAttributeListener { _, _, _ ->
202+ onReady.run ()
203+ },
204+ )
205+ } else {
206+ onReady.run ()
177207 }
178- return finalAttributes
179208 }
180209
181210 private fun confirmEmail (
0 commit comments