diff --git a/README.md b/README.md index daf0976d..cbc77131 100755 --- a/README.md +++ b/README.md @@ -568,6 +568,10 @@ ConstructorIo.trackRecommendationResultClick("Best_Sellers", "User Featured", "7 // Track when recommendation results are loaded into view (podId, numResultsViewed, resultPage, resultCount, resultId, sectionName) ConstructorIo.trackRecommendationResultsView("Best_Sellers", 4, 1, 4, "179b8a0e-3799-4a31-be87-127b06871de2", "Products") + +// v2.34.0+ only +// Track when recommendation results are loaded into view (podId, itemIds, numResultsViewed, resultPage, resultCount, resultId, sectionName) +ConstructorIo.trackRecommendationResultsView("Best_Sellers", arrayOf("1234", "2345"), 4, 1, 4, "179b8a0e-3799-4a31-be87-127b06871de2", "Products") ``` ### Quiz Events diff --git a/library/src/main/java/io/constructor/core/ConstructorIo.kt b/library/src/main/java/io/constructor/core/ConstructorIo.kt index 0d5400e2..045a4f30 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -2048,7 +2048,30 @@ object ConstructorIo { * * Example: * ``` - * ConstructorIo.trackRecommendationResultsView("Best_Sellers", "User Featured", 4, 1, 4, "179b8a0e-3799-4a31-be87-127b06871de2", "Products") + * ConstructorIo.trackRecommendationResultsView("Best_Sellers", arrayOf("123", "234"), 4, 1, 4, "179b8a0e-3799-4a31-be87-127b06871de2", "Products") + * ``` + * @param podId The pod id + * @param itemIds the item ids of the dislayed items + * @param numResultsViewed The count of recommendation results being viewed + * @param resultPage The current page that recommendation result is on + * @param resultCount The total number of recommendation results + * @param resultId The result ID of the recommendation response that the selection came from + * @param sectionName The section that the results came from, i.e. "Products" + * @param analyticsTags Additional analytics tags to pass + */ + fun trackRecommendationResultsView(podId: String, itemIds: Array, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map? = null) { + var completable = trackRecommendationResultsViewInternal(podId, itemIds, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags) + disposable.add(completable.subscribeOn(Schedulers.io()).subscribe({}, { + t -> e("Recommendation Results View error: ${t.message}") + })) + } + + /** + * Tracks recommendation result view events. + * + * Example: + * ``` + * ConstructorIo.trackRecommendationResultsView("Best_Sellers", 4, 1, 4, "179b8a0e-3799-4a31-be87-127b06871de2", "Products") * ``` * @param podId The pod id * @param numResultsViewed The count of recommendation results being viewed @@ -2059,16 +2082,18 @@ object ConstructorIo { * @param analyticsTags Additional analytics tags to pass */ fun trackRecommendationResultsView(podId: String, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map? = null) { - var completable = trackRecommendationResultsViewInternal(podId, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags) + var completable = trackRecommendationResultsViewInternal(podId, null, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags) disposable.add(completable.subscribeOn(Schedulers.io()).subscribe({}, { t -> e("Recommendation Results View error: ${t.message}") })) } - internal fun trackRecommendationResultsViewInternal(podId: String, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map? = null): Completable { + internal fun trackRecommendationResultsViewInternal(podId: String, itemIds: Array? = null, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map? = null): Completable { preferenceHelper.getSessionId(sessionIncrementHandler) val section = sectionName ?: preferenceHelper.defaultItemSection + val items = itemIds?.map{ item -> TrackingItem(item, null)} val recommendationResultViewRequestBody = RecommendationResultViewRequestBody( podId, + items, numResultsViewed, resultPage, resultCount, diff --git a/library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultViewRequestBody.kt b/library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultViewRequestBody.kt index f6e36a13..4cb7ceea 100644 --- a/library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultViewRequestBody.kt +++ b/library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultViewRequestBody.kt @@ -8,6 +8,7 @@ import java.io.Serializable @JsonClass(generateAdapter = true) data class RecommendationResultViewRequestBody( @Json(name = "pod_id") val podId: String, + @Json(name = "items") val items: List?, @Json(name = "num_results_viewed") val numResultsViewed: Int, @Json(name = "result_page") val resultPage: Int?, @Json(name = "result_count") val resultCount: Int?, diff --git a/library/src/test/java/io/constructor/core/ConstructorIoIntegrationTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoIntegrationTest.kt index c91ec0a3..a5e6c379 100644 --- a/library/src/test/java/io/constructor/core/ConstructorIoIntegrationTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoIntegrationTest.kt @@ -1149,7 +1149,7 @@ class ConstructorIoIntegrationTest { @Test fun trackRecommendationResultsViewAgainstRealResponse() { - val observer = constructorIo.trackRecommendationResultsViewInternal("home_page_1", 4).test() + val observer = constructorIo.trackRecommendationResultsViewInternal("home_page_1", arrayOf("123", "234"), 4).test() observer.assertComplete() Thread.sleep(timeBetweenTests) } diff --git a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt index 8e0a232e..872fe9a9 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt @@ -1097,7 +1097,7 @@ class ConstructorIoTrackingTest { fun trackRecommendationResultsView() { val mockResponse = MockResponse().setResponseCode(204) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null, 4).test() observer.assertComplete() val request = mockServer.takeRequest() val requestBody = getRequestBody(request) @@ -1112,7 +1112,7 @@ class ConstructorIoTrackingTest { fun trackRecommendationResultsViewWithAnalyticsTags() { val mockResponse = MockResponse().setResponseCode(204) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4, analyticsTags = mapOf("test" to "test1", "appVersion" to "150")).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null,4, analyticsTags = mapOf("test" to "test1", "appVersion" to "150")).test() observer.assertComplete() val request = mockServer.takeRequest() val requestBody = getRequestBody(request) @@ -1124,11 +1124,29 @@ class ConstructorIoTrackingTest { assert(request.path!!.startsWith(path)) } + @Test + fun trackRecommendationResultsViewWithItems() { + val mockResponse = MockResponse().setResponseCode(204) + mockServer.enqueue(mockResponse) + val items = arrayOf("123", "234") + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", items,4, analyticsTags = mapOf("test" to "test1", "appVersion" to "150")).test() + observer.assertComplete() + val request = mockServer.takeRequest() + val requestBody = getRequestBody(request) + val path = "/v2/behavioral_action/recommendation_result_view?section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.33.0&_dt=" + assertEquals("pdp5", requestBody["pod_id"]) + assertEquals("[{item_id:123},{item_id:234}]", requestBody["items"]) + assertEquals("4", requestBody["num_results_viewed"]) + assertEquals("{appVersion:150,appPlatform:Android,test:test1}", requestBody["analytics_tags"]) + assertEquals("POST", request.method) + assert(request.path!!.startsWith(path)) + } + @Test fun trackRecommendationResultsViewWithSectionAndResultID() { val mockResponse = MockResponse().setResponseCode(204) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4, 1, 4, "3467632", "Search Suggestions").test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null, 4, 1, 4, "3467632", "Search Suggestions").test() observer.assertComplete() val request = mockServer.takeRequest() val requestBody = getRequestBody(request) @@ -1146,7 +1164,7 @@ class ConstructorIoTrackingTest { fun trackRecommendationResultsView500() { val mockResponse = MockResponse().setResponseCode(500).setBody("Internal server error") mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null, 4).test() observer.assertError { true } val request = mockServer.takeRequest() val requestBody = getRequestBody(request) @@ -1162,7 +1180,7 @@ class ConstructorIoTrackingTest { val mockResponse = MockResponse().setResponseCode(500).setBody("Internal server error") mockResponse.throttleBody(0, 5, TimeUnit.SECONDS) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null, 4).test() observer.assertError(SocketTimeoutException::class.java) val request = mockServer.takeRequest(10, TimeUnit.SECONDS) assertEquals(null, request) diff --git a/library/src/test/java/io/constructor/core/ConstructorioSegmentsTest.kt b/library/src/test/java/io/constructor/core/ConstructorioSegmentsTest.kt index 5d0b3841..5e259dfc 100644 --- a/library/src/test/java/io/constructor/core/ConstructorioSegmentsTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorioSegmentsTest.kt @@ -173,7 +173,7 @@ class ConstructorioSegmentsTest { fun trackRecommendationResultsView() { val mockResponse = MockResponse().setResponseCode(204) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null,4).test() observer.assertComplete() val request = mockServer.takeRequest() val path = "/v2/behavioral_action/recommendation_result_view?section=Products&key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&us=mobile&us=COUNTRY_US&c=cioand-2.33.0&_dt=" diff --git a/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt b/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt index 7e6a3514..e523c11d 100644 --- a/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt @@ -174,7 +174,7 @@ class ConstructorioTestCellTest { fun trackRecommendationResultsView() { val mockResponse = MockResponse().setResponseCode(204) mockServer.enqueue(mockResponse) - val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", 4).test() + val observer = ConstructorIo.trackRecommendationResultsViewInternal("pdp5", null, 4).test() observer.assertComplete() val request = mockServer.takeRequest() val path = "/v2/behavioral_action/recommendation_result_view?section=Products&key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&ef-cellone=vanilla&ef-celltwo=whipped-cream&c=cioand-2.33.0&_dt="