Skip to content

Commit

Permalink
Merge 516b2aa into 001976d
Browse files Browse the repository at this point in the history
  • Loading branch information
najmsheikh committed Aug 12, 2020
2 parents 001976d + 516b2aa commit 2c5eb54
Show file tree
Hide file tree
Showing 19 changed files with 1,297 additions and 19 deletions.
@@ -0,0 +1,64 @@
/*
* ActivityReportingTask.java
*
* Copyright (c) 2020 Button, Inc. (https://usebutton.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

package com.usebutton.merchant;

import android.support.annotation.Nullable;

import com.usebutton.merchant.module.Features;

import java.util.List;

/**
* Asynchronous task used to report user activity to Button.
*/
public class ActivityReportingTask extends Task<Void> {

private final ButtonApi buttonApi;
private final DeviceManager deviceManager;
private final Features features;
private final String activityName;
private final List<ButtonProductCompatible> products;
private final String sourceToken;

public ActivityReportingTask(ButtonApi buttonApi, DeviceManager deviceManager,
Features features, String activityName, List<ButtonProductCompatible> products,
@Nullable String sourceToken, @Nullable Listener<Void> listener) {
super(listener);
this.buttonApi = buttonApi;
this.deviceManager = deviceManager;
this.features = features;
this.activityName = activityName;
this.products = products;
this.sourceToken = sourceToken;
}

@Nullable
@Override
Void execute() throws Exception {
String advertisingId = features.getIncludesIfa() ? deviceManager.getAdvertisingId() : null;
return buttonApi.postActivity(activityName, products, sourceToken, advertisingId);
}
}
Expand Up @@ -54,6 +54,12 @@ PostInstallLink getPendingLink(String applicationId, @Nullable String advertisin
Void postOrder(Order order, String applicationId, String sourceToken,
@Nullable String advertisingId) throws ButtonNetworkException;

@Nullable
@WorkerThread
Void postActivity(String activityName, List<ButtonProductCompatible> products,
@Nullable String sourceToken, @Nullable String advertisingId)
throws ButtonNetworkException;

@Nullable
@WorkerThread
Void postEvents(List<Event> events, @Nullable String advertisingId)
Expand Down
Expand Up @@ -202,6 +202,78 @@ public Void postOrder(Order order, String applicationId, String sourceToken,
return null;
}

@Nullable
@Override
public Void postActivity(String activityName, List<ButtonProductCompatible> products,
@Nullable String sourceToken, @Nullable String advertisingId)
throws ButtonNetworkException {

try {
JSONObject requestBody = new JSONObject();
JSONObject activityBody = new JSONObject();
requestBody.put("ifa", advertisingId);
requestBody.put("btn_ref", sourceToken);
activityBody.put("name", activityName);

if (!products.isEmpty()) {
JSONArray productsArray = new JSONArray();
for (int i = 0; i < products.size(); i++) {
ButtonProductCompatible product = products.get(i);
List<String> categories = product.getCategories();
Map<String, String> attributes = product.getAttributes();
JSONObject productJson = new JSONObject();

// Convert categories list to JSON array
JSONArray categoriesJson = new JSONArray();
if (categories != null) {
for (int j = 0; j < categories.size(); j++) {
categoriesJson.put(j, categories.get(j));
}
productJson.put("categories", categoriesJson);
}

// Convert custom attributes map to JSON object
JSONObject attributesJson = new JSONObject();
if (attributes != null) {
for (Map.Entry<String, String> entry : attributes.entrySet()) {
attributesJson.putOpt(entry.getKey(), entry.getValue());
}
productJson.put("attributes", attributesJson);
}

// Put product data into a JSON object
productJson.put("id", product.getId());
productJson.put("upc", product.getUpc());
productJson.put("name", product.getName());
productJson.put("currency", product.getCurrency());
productJson.put("value", product.getValue());
productJson.put("quantity", product.getQuantity());
productJson.put("url", product.getUrl());

// Add to JSON array of products
productsArray.put(i, productJson);
}

// Append products only if available
activityBody.put("products", productsArray);
}

// Append activity data to request body
requestBody.put("activity_data", activityBody);

ApiRequest apiRequest = new ApiRequest.Builder(ApiRequest.RequestMethod.POST,
"/v1/app/activity")
.setBody(requestBody)
.build();
connectionManager.executeRequest(apiRequest);
} catch (JSONException e) {
Log.e(TAG, "Error creating request body", e);
throw new ButtonNetworkException(e);
}

return null;
}

@Nullable
@Override
public Void postEvents(List<Event> events, @Nullable String advertisingId)
Expand Down
Expand Up @@ -31,6 +31,7 @@
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;

import com.usebutton.merchant.module.ButtonUserActivity;
import com.usebutton.merchant.module.Features;

import java.util.concurrent.Executor;
Expand All @@ -49,6 +50,8 @@ private ButtonMerchant() {
private static Executor executor = new MainThreadExecutor();
@VisibleForTesting
static ButtonInternal buttonInternal = new ButtonInternalImpl(executor);
@VisibleForTesting
static ButtonUserActivity activity = ButtonUserActivityImpl.getInstance();

private static ExecutorService executorService = Executors.newSingleThreadExecutor();
static final String BASE_URL = "https://mobileapi.usebutton.com";
Expand All @@ -63,6 +66,7 @@ private ButtonMerchant() {
*/
public static void configure(@NonNull Context context, @NonNull String applicationId) {
buttonInternal.configure(getButtonRepository(context), applicationId);
((ButtonUserActivityImpl) activity()).flushQueue(getButtonRepository(context));
}

/**
Expand Down Expand Up @@ -196,6 +200,15 @@ public static Features features() {
return FeaturesImpl.getInstance();
}

/**
* An interface through which user activities can be reported.
*
* @return Button user activity API
*/
public static ButtonUserActivity activity() {
return activity;
}

private static ButtonRepository getButtonRepository(Context context) {
PersistenceManager persistenceManager =
PersistenceManagerImpl.getInstance(context.getApplicationContext());
Expand All @@ -207,7 +220,8 @@ private static ButtonRepository getButtonRepository(Context context) {

ButtonApi buttonApi = ButtonApiImpl.getInstance(connectionManager);

return ButtonRepositoryImpl.getInstance(buttonApi, persistenceManager, executorService);
return ButtonRepositoryImpl.getInstance(buttonApi, deviceManager, features(),
persistenceManager, executorService);
}

private static DeviceManager getDeviceManager(Context context) {
Expand Down
@@ -0,0 +1,137 @@
/*
* ButtonProduct.java
*
* Copyright (c) 2020 Button, Inc. (https://usebutton.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

package com.usebutton.merchant;

import android.support.annotation.Nullable;

import java.util.List;
import java.util.Map;

/**
* A concrete implementation of the {@link ButtonProductCompatible} interface.
*/
public class ButtonProduct implements ButtonProductCompatible {

@Nullable private String id;
@Nullable private String upc;
@Nullable private List<String> categories;
@Nullable private String name;
@Nullable private String currency;
@Nullable private Integer value;
@Nullable private Integer quantity;
@Nullable private String url;
@Nullable private Map<String, String> attributes;

@Override
@Nullable
public String getId() {
return id;
}

@Override
@Nullable
public String getUpc() {
return upc;
}

@Override
@Nullable
public List<String> getCategories() {
return categories;
}

@Override
@Nullable
public String getName() {
return name;
}

@Override
@Nullable
public String getCurrency() {
return currency;
}

@Override
@Nullable
public Integer getValue() {
return value;
}

@Override
@Nullable
public Integer getQuantity() {
return quantity;
}

@Override
@Nullable
public String getUrl() {
return url;
}

@Override
@Nullable
public Map<String, String> getAttributes() {
return attributes;
}

public void setId(@Nullable String id) {
this.id = id;
}

public void setUpc(@Nullable String upc) {
this.upc = upc;
}

public void setCategories(@Nullable List<String> categories) {
this.categories = categories;
}

public void setName(@Nullable String name) {
this.name = name;
}

public void setCurrency(@Nullable String currency) {
this.currency = currency;
}

public void setValue(@Nullable Integer value) {
this.value = value;
}

public void setQuantity(@Nullable Integer quantity) {
this.quantity = quantity;
}

public void setUrl(@Nullable String url) {
this.url = url;
}

public void setAttributes(@Nullable Map<String, String> attributes) {
this.attributes = attributes;
}
}

0 comments on commit 2c5eb54

Please sign in to comment.