diff --git a/README.md b/README.md index 5073e934d..8a578f942 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,10 @@ GoogleAnalytics.trackPurchaseEvent({ }, 'Ecommerce', 'Purchase'); ``` +### trackMultiProductsPurchaseEvent(products, transaction, eventCategory, eventAction) + +same as trackPurchaseEvent but instead of one product you can provide an Array of products + ### trackException(error, fatal) * **error:** String, a description of the exception (up to 100 characters), accepts nil diff --git a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java index e1ac3d2b9..563488943 100644 --- a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java +++ b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java @@ -4,6 +4,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMapKeySetIterator; import com.google.android.gms.analytics.GoogleAnalytics; @@ -116,34 +117,66 @@ public void trackPurchaseEvent(String trackerId, ReadableMap product, ReadableMa Tracker tracker = getTracker(trackerId); if (tracker != null) { - Product ecommerceProduct = new Product() - .setId(product.getString("id")) - .setName(product.getString("name")) - .setCategory(product.getString("category")) - .setBrand(product.getString("brand")) - .setVariant(product.getString("variant")) - .setPrice(product.getDouble("price")) - .setCouponCode(product.getString("couponCode")) - .setQuantity(product.getInt("quantity")); - - ProductAction productAction = new ProductAction(ProductAction.ACTION_PURCHASE) - .setTransactionId(transaction.getString("id")) - .setTransactionAffiliation(transaction.getString("affiliation")) - .setTransactionRevenue(transaction.getDouble("revenue")) - .setTransactionTax(transaction.getDouble("tax")) - .setTransactionShipping(transaction.getDouble("shipping")) - .setTransactionCouponCode(transaction.getString("couponCode")); HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() - .addProduct(ecommerceProduct) - .setProductAction(productAction) - .setCategory(eventCategory) - .setAction(eventAction); + .addProduct(this.getPurchaseProduct(product)) + .setProductAction(this.getPurchaseTransaction(transaction)) + .setCategory(eventCategory) + .setAction(eventAction); tracker.send(hit.build()); } } + @ReactMethod + public void trackMultiProductsPurchaseEvent(String trackerId, ReadableArray products, ReadableMap transaction, String eventCategory, String eventAction) { + Tracker tracker = getTracker(trackerId); + + if (tracker != null) { + + HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() + .setProductAction(this.getPurchaseTransaction(transaction)) + .setCategory(eventCategory) + .setAction(eventAction); + + for (int i = 0; i < products.size(); i++) { + ReadableMap product = products.getMap(i); + hit.addProduct(this.getPurchaseProduct(product)); + } + + tracker.send(hit.build()); + } + } + + private ProductAction getPurchaseTransaction(ReadableMap transaction) { + ProductAction productAction = new ProductAction(ProductAction.ACTION_PURCHASE) + .setTransactionId(transaction.getString("id")) + .setTransactionTax(transaction.getDouble("tax")) + .setTransactionRevenue(transaction.getDouble("revenue")) + .setTransactionShipping(transaction.getDouble("shipping")) + .setTransactionCouponCode(transaction.getString("couponCode")) + .setTransactionAffiliation(transaction.getString("affiliation")); + + return productAction; + } + + private Product getPurchaseProduct(ReadableMap product) { + Product ecommerceProduct = new Product() + .setId(product.getString("id")) + .setName(product.getString("name")) + .setBrand(product.getString("brand")) + .setPrice(product.getDouble("price")) + .setQuantity(product.getInt("quantity")) + .setVariant(product.getString("variant")) + .setCategory(product.getString("category")); + + if(product.hasKey("couponCode")) { + ecommerceProduct.setCouponCode(product.getString("couponCode")); + } + + return ecommerceProduct; + } + @ReactMethod public void trackException(String trackerId, String error, Boolean fatal) { diff --git a/example/index.android.js b/example/index.android.js index cbde368c5..66d161d6d 100644 --- a/example/index.android.js +++ b/example/index.android.js @@ -67,6 +67,35 @@ class example extends Component { } ); + GoogleAnalytics.trackMultiProductsPurchaseEvent( + [ + { + id: '2224711', + name: 'Top Ilem', + category: 'Women/Kleidung/Tops/Spitzentops', + brand: 'THE label', + variant: 'rot', + price: 39.90, + quantity: 1 + }, + { + id: '2224706', + name: 'Shorts Isto', + category: 'Women/Kleidung/Hosen/Shirts', + brand: 'THE label', + variant: 'grau', + price: 59.90, + quantity: 1 + } + ], { + id: 'T12345', + affiliation: 'THE label Shop', + revenue: 83.87, + tax: 15.93, + shipping: 0.00, + couponCode: 'SUMMER2016' + }); + GoogleAnalytics.trackException("This is an error message", false); GoogleAnalytics.trackSocialInteraction('Twitter', 'Post'); diff --git a/example/index.ios.js b/example/index.ios.js index 87ea69603..1598ff419 100644 --- a/example/index.ios.js +++ b/example/index.ios.js @@ -68,6 +68,35 @@ class example extends Component { } ); + GoogleAnalytics.trackMultiProductsPurchaseEvent( + [ + { + id: '2224711', + name: 'Top Ilem', + category: 'Women/Kleidung/Tops/Spitzentops', + brand: 'THE label', + variant: 'rot', + price: 39.90, + quantity: 1 + }, + { + id: '2224706', + name: 'Shorts Isto', + category: 'Women/Kleidung/Hosen/Shirts', + brand: 'THE label', + variant: 'grau', + price: 59.90, + quantity: 1 + } + ], { + id: 'T12345', + affiliation: 'THE label Shop', + revenue: 83.87, + tax: 15.93, + shipping: 0.00, + couponCode: 'SUMMER2016' + }); + GoogleAnalytics.trackException("This is an error message", false); GoogleAnalytics.trackSocialInteraction('Twitter', 'Post'); diff --git a/index.js b/index.js index 8d75df6e1..7adcfec72 100644 --- a/index.js +++ b/index.js @@ -72,6 +72,17 @@ class GoogleAnalytics { GoogleAnalyticsBridge.trackPurchaseEvent(getTrackerId(), product, transaction, eventCategory, eventAction); } + /** + * Track a purchase event. This uses the Enhanced Ecommerce GA feature. + * @param {Array} products An array with products + * @param {Object} transaction An object with transaction values + * @param {String} eventCategory The event category, defaults to Ecommerce + * @param {String} eventAction The event action, defaults to Purchase + */ + static trackMultiProductsPurchaseEvent(products = [], transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase") { + GoogleAnalyticsBridge.trackMultiProductsPurchaseEvent(getTrackerId(), products, transaction, eventCategory, eventAction); + } + /** * Track an exception * @param {String} error The description of the error diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m index 77d18672c..bd7947d67 100644 --- a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m @@ -140,6 +140,53 @@ - (NSDictionary *)constantsToExport [tracker send:[builder build]]; } +RCT_EXPORT_METHOD(trackMultiProductsPurchaseEvent:(NSString *)trackerId products:(NSArray *)products transaction:(NSDictionary *)transaction eventCategory:(NSString *)eventCategory eventAction:(NSString *)eventAction) { + + id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; + NSString *transactionId = [RCTConvert NSString:transaction[@"id"]]; + NSString *transactionAffiliation = [RCTConvert NSString:transaction[@"affiliation"]]; + NSNumber *transactionRevenue = [RCTConvert NSNumber:transaction[@"revenue"]]; + NSNumber *transactionTax = [RCTConvert NSNumber:transaction[@"tax"]]; + NSNumber *transactionShipping = [RCTConvert NSNumber:transaction[@"shipping"]]; + NSString *transactionCouponCode = [RCTConvert NSString:transaction[@"couponCode"]]; + GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createEventWithCategory:eventCategory + action:eventAction + label:nil + value:nil]; + GAIEcommerceProductAction *action = [[GAIEcommerceProductAction alloc] init]; + [action setAction:kGAIPAPurchase]; + [action setTransactionId:transactionId]; + [action setAffiliation:transactionAffiliation]; + [action setRevenue:transactionRevenue]; + [action setTax:transactionTax]; + [action setShipping:transactionShipping]; + [action setCouponCode:transactionCouponCode]; + [builder setProductAction:action]; + for (id product in products) { + NSString *productId = [RCTConvert NSString:product[@"id"]]; + NSString *productName = [RCTConvert NSString:product[@"name"]]; + NSString *productBrand = [RCTConvert NSString:product[@"brand"]]; + NSNumber *productPrice = [RCTConvert NSNumber:product[@"price"]]; + NSString *productVariant = [RCTConvert NSString:product[@"variant"]]; + NSString *productCategory = [RCTConvert NSString:product[@"category"]]; + NSNumber *productQuantity = [RCTConvert NSNumber:product[@"quantity"]]; + GAIEcommerceProduct *ecommerceProduct = [[GAIEcommerceProduct alloc] init]; + [ecommerceProduct setId:productId]; + [ecommerceProduct setName:productName]; + [ecommerceProduct setCategory:productCategory]; + [ecommerceProduct setBrand:productBrand]; + [ecommerceProduct setVariant:productVariant]; + [ecommerceProduct setPrice:productPrice]; + [ecommerceProduct setQuantity:productQuantity]; + if ([product objectForKey:@"couponCode"]) { + NSString *productCouponCode = [RCTConvert NSString:product[@"couponCode"]]; + [ecommerceProduct setCouponCode:productCouponCode]; + } + [builder addProduct:ecommerceProduct]; + } + [tracker send:[builder build]]; +} + RCT_EXPORT_METHOD(trackException:(NSString *)trackerId error:(NSString *)error fatal:(BOOL)fatal) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId];