Skip to content

Commit 3d81d89

Browse files
authored
Merge pull request #595 from OneSignal/send_tags_handler
Add Update Handler for Send/Delete Tags
2 parents af55a25 + 7bcb166 commit 3d81d89

File tree

4 files changed

+209
-12
lines changed

4 files changed

+209
-12
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,24 @@ public interface GetTagsHandler {
143143
void tagsAvailable(JSONObject tags);
144144
}
145145

146+
public interface ChangeTagsUpdateHandler {
147+
void onSuccess(JSONObject tags);
148+
void onFailure(SendTagsError error);
149+
}
150+
151+
public static class SendTagsError {
152+
private String message;
153+
private int code;
154+
155+
SendTagsError(int errorCode, String errorMessage) {
156+
this.message = errorMessage;
157+
this.code = errorCode;
158+
}
159+
160+
public int getCode() { return code; }
161+
public String getMessage() { return message; }
162+
}
163+
146164

147165
public enum EmailErrorType {
148166
VALIDATION, REQUIRES_EMAIL_AUTH, INVALID_OPERATION, NETWORK
@@ -869,6 +887,13 @@ private static void fireCallbackForOpenedNotifications() {
869887

870888
unprocessedOpenedNotifis.clear();
871889
}
890+
/**
891+
* Please do not use this method for logging, it is meant solely to be
892+
* used by our wrapper SDK's.
893+
*/
894+
public static void onesignalLog(LOG_LEVEL level, String message) {
895+
OneSignal.Log(level, message);
896+
}
872897

873898
public static boolean userProvidedPrivacyConsent() {
874899
return getSavedUserConsentStatus();
@@ -1422,6 +1447,24 @@ public static void sendTags(String jsonString) {
14221447
*
14231448
*/
14241449
public static void sendTags(final JSONObject keyValues) {
1450+
sendTags(keyValues, null);
1451+
}
1452+
1453+
/**
1454+
* Tag a user based on an app event of your choosing so later you can create
1455+
* <a href="https://documentation.onesignal.com/docs/segmentation">OneSignal Segments</a>
1456+
* to target these users.
1457+
*
1458+
* NOTE: The ChangeTagsUpdateHandler will not be called under all circumstances. It can also take
1459+
* more than 5 seconds in some cases to be called, so please do not block any user action
1460+
* based on this callback.
1461+
* @param keyValues Key value pairs of your choosing to create or update. <b>Note:</b>
1462+
* Passing in a blank String as a value deletes a key.
1463+
* You can also call {@link #deleteTag(String)} or {@link #deleteTags(String)}.
1464+
*
1465+
*/
1466+
public static void sendTags(final JSONObject keyValues, ChangeTagsUpdateHandler handler) {
1467+
final ChangeTagsUpdateHandler tagsHandler = handler;
14251468

14261469
//if applicable, check if the user provided privacy consent
14271470
if (shouldLogUserPrivacyConsentErrorMessageForMethodName("sendTags()"))
@@ -1430,10 +1473,13 @@ public static void sendTags(final JSONObject keyValues) {
14301473
Runnable sendTagsRunnable = new Runnable() {
14311474
@Override
14321475
public void run() {
1433-
if (keyValues == null) return;
1476+
if (keyValues == null) {
1477+
if (tagsHandler != null)
1478+
tagsHandler.onFailure(new SendTagsError(-1, "Attempted to send null tags"));
1479+
return;
1480+
}
14341481

14351482
JSONObject existingKeys = OneSignalStateSynchronizer.getTags(false).result;
1436-
14371483
JSONObject toSend = new JSONObject();
14381484

14391485
Iterator<String> keys = keyValues.keys();
@@ -1456,15 +1502,21 @@ else if (keyValues.isNull(key) || "".equals(value)) {
14561502
catch (Throwable t) {}
14571503
}
14581504

1459-
if (!toSend.toString().equals("{}"))
1460-
OneSignalStateSynchronizer.sendTags(toSend);
1505+
if (!toSend.toString().equals("{}")) {
1506+
OneSignalStateSynchronizer.sendTags(toSend, tagsHandler);
1507+
} else {
1508+
tagsHandler.onSuccess(existingKeys);
1509+
}
14611510
}
14621511
};
14631512

14641513

14651514
if (appContext == null || shouldRunTaskThroughQueue()) {
14661515
Log(LOG_LEVEL.ERROR, "You must initialize OneSignal before modifying tags!" +
14671516
"Moving this operation to a pending task queue.");
1517+
if (tagsHandler != null)
1518+
tagsHandler.onFailure(new SendTagsError(-1, "You must initialize OneSignal before modifying tags!" +
1519+
"Moving this operation to a pending task queue."));
14681520
addTaskToQueue(new PendingTaskRunnable(sendTagsRunnable));
14691521
return;
14701522
}
@@ -1612,14 +1664,17 @@ public void run() {
16121664
* @param key Key to remove.
16131665
*/
16141666
public static void deleteTag(String key) {
1667+
deleteTag(key, null);
1668+
}
16151669

1670+
public static void deleteTag(String key, ChangeTagsUpdateHandler handler) {
16161671
//if applicable, check if the user provided privacy consent
16171672
if (shouldLogUserPrivacyConsentErrorMessageForMethodName("deleteTag()"))
16181673
return;
16191674

16201675
Collection<String> tempList = new ArrayList<>(1);
16211676
tempList.add(key);
1622-
deleteTags(tempList);
1677+
deleteTags(tempList, handler);
16231678
}
16241679

16251680
/**
@@ -1628,7 +1683,10 @@ public static void deleteTag(String key) {
16281683
* @param keys Keys to remove.
16291684
*/
16301685
public static void deleteTags(Collection<String> keys) {
1686+
deleteTags(keys, null);
1687+
}
16311688

1689+
public static void deleteTags(Collection<String> keys, ChangeTagsUpdateHandler handler) {
16321690
//if applicable, check if the user provided privacy consent
16331691
if (shouldLogUserPrivacyConsentErrorMessageForMethodName("deleteTags()"))
16341692
return;
@@ -1638,14 +1696,17 @@ public static void deleteTags(Collection<String> keys) {
16381696
for (String key : keys)
16391697
jsonTags.put(key, "");
16401698

1641-
sendTags(jsonTags);
1699+
sendTags(jsonTags, handler);
16421700
} catch (Throwable t) {
16431701
Log(LOG_LEVEL.ERROR, "Failed to generate JSON for deleteTags.", t);
16441702
}
16451703
}
16461704

16471705
public static void deleteTags(String jsonArrayString) {
1706+
deleteTags(jsonArrayString, null);
1707+
}
16481708

1709+
public static void deleteTags(String jsonArrayString, ChangeTagsUpdateHandler handler) {
16491710
//if applicable, check if the user provided privacy consent
16501711
if (shouldLogUserPrivacyConsentErrorMessageForMethodName("deleteTags()"))
16511712
return;
@@ -1657,7 +1718,7 @@ public static void deleteTags(String jsonArrayString) {
16571718
for (int i = 0; i < jsonArray.length(); i++)
16581719
jsonTags.put(jsonArray.getString(i), "");
16591720

1660-
sendTags(jsonTags);
1721+
sendTags(jsonTags, handler);
16611722
} catch (Throwable t) {
16621723
Log(LOG_LEVEL.ERROR, "Failed to generate JSON for deleteTags.", t);
16631724
}
@@ -2138,6 +2199,10 @@ public static void setInFocusDisplaying(int displayOption) {
21382199
setInFocusDisplaying(getInFocusDisplaying(displayOption));
21392200
}
21402201

2202+
public static OSInFocusDisplayOption currentInFocusDisplayOption() {
2203+
return getCurrentOrNewInitBuilder().mDisplayOption;
2204+
}
2205+
21412206
private static OSInFocusDisplayOption getInFocusDisplaying(int displayOption) {
21422207
switch(displayOption) {
21432208
case 0:

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalStateSynchronizer.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import org.json.JSONException;
3131
import org.json.JSONObject;
32+
import com.onesignal.OneSignal.ChangeTagsUpdateHandler;
3233

3334
class OneSignalStateSynchronizer {
3435

@@ -71,12 +72,13 @@ static void syncUserState(boolean fromSyncService) {
7172
getEmailStateSynchronizer().syncUserState(fromSyncService);
7273
}
7374

74-
static void sendTags(JSONObject newTags) {
75+
static void sendTags(JSONObject newTags, ChangeTagsUpdateHandler handler) {
7576
try {
7677
JSONObject jsonField = new JSONObject().put("tags", newTags);
77-
getPushStateSynchronizer().sendTags(jsonField);
78-
getEmailStateSynchronizer().sendTags(jsonField);
78+
getPushStateSynchronizer().sendTags(jsonField, handler);
79+
getEmailStateSynchronizer().sendTags(jsonField, handler);
7980
} catch (JSONException e) {
81+
handler.onFailure(new OneSignal.SendTagsError(-1, "Encountered an error attempting to serialize your tags into JSON: " + e.getMessage() + "\n" + e.getStackTrace()));
8082
e.printStackTrace();
8183
}
8284
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/UserStateSynchronizer.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import android.os.Handler;
44
import android.os.HandlerThread;
5+
import com.onesignal.OneSignal.ChangeTagsUpdateHandler;
6+
import com.onesignal.OneSignal.SendTagsError;
57

68
import org.json.JSONException;
79
import org.json.JSONObject;
810

11+
import java.util.ArrayList;
912
import java.util.HashMap;
1013
import java.util.Set;
1114
import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,6 +37,11 @@ String getRegistrationId() {
3437
abstract GetTagsResult getTags(boolean fromServer);
3538

3639
private AtomicBoolean runningSyncUserState = new AtomicBoolean();
40+
41+
// maintain an array of handlers so that if the user calls
42+
// sendTags() multiple times, it will call each callback
43+
private ArrayList<ChangeTagsUpdateHandler> sendTagsHandlers = new ArrayList<ChangeTagsUpdateHandler>();
44+
3745
class NetworkHandlerThread extends HandlerThread {
3846
protected static final int NETWORK_HANDLER_USERSTATE = 0;
3947

@@ -180,6 +188,15 @@ private void internalSyncUserState(boolean fromSyncService) {
180188

181189
if (jsonBody == null) {
182190
currentUserState.persistStateAfterSync(dependDiff, null);
191+
192+
for (ChangeTagsUpdateHandler handler : this.sendTagsHandlers) {
193+
if (handler != null) {
194+
handler.onSuccess(OneSignalStateSynchronizer.getTags(false).result);
195+
}
196+
}
197+
198+
this.sendTagsHandlers.clear();
199+
183200
return;
184201
}
185202
getToSyncUserState().persistState();
@@ -249,8 +266,21 @@ private void logoutEmailSyncSuccess() {
249266
}
250267

251268
private void doPutSync(String userId, final JSONObject jsonBody, final JSONObject dependDiff) {
252-
if (userId == null)
269+
if (userId == null) {
270+
for (ChangeTagsUpdateHandler handler : this.sendTagsHandlers) {
271+
if (handler != null) {
272+
handler.onFailure(new SendTagsError(-1, "Unable to update tags: the current user is not registered with OneSignal"));
273+
}
274+
}
275+
276+
this.sendTagsHandlers.clear();
277+
253278
return;
279+
}
280+
281+
final ArrayList<ChangeTagsUpdateHandler> tagsHandlers = (ArrayList<ChangeTagsUpdateHandler>) this.sendTagsHandlers.clone();
282+
283+
this.sendTagsHandlers.clear();
254284

255285
OneSignalRestClient.putSync("players/" + userId, jsonBody, new OneSignalRestClient.ResponseHandler() {
256286
@Override
@@ -261,12 +291,29 @@ void onFailure(int statusCode, String response, Throwable throwable) {
261291
handlePlayerDeletedFromServer();
262292
else
263293
handleNetworkFailure();
294+
295+
if (jsonBody.has("tags"))
296+
for (ChangeTagsUpdateHandler handler : tagsHandlers) {
297+
if (handler != null) {
298+
handler.onFailure(new SendTagsError(statusCode, response));
299+
}
300+
}
301+
264302
}
265303

266304
@Override
267305
void onSuccess(String response) {
268306
currentUserState.persistStateAfterSync(dependDiff, jsonBody);
269307
onSuccessfulSync(jsonBody);
308+
JSONObject tags = OneSignalStateSynchronizer.getTags(false).result;
309+
310+
if (jsonBody.has("tags") && tags != null)
311+
for (ChangeTagsUpdateHandler handler : tagsHandlers) {
312+
if (handler != null) {
313+
handler.onSuccess(tags);
314+
}
315+
}
316+
270317
}
271318
});
272319
}
@@ -385,7 +432,8 @@ void setSyncAsNewSession() {
385432
}
386433

387434

388-
void sendTags(JSONObject tags) {
435+
void sendTags(JSONObject tags, ChangeTagsUpdateHandler handler) {
436+
this.sendTagsHandlers.add(handler);
389437
JSONObject userStateTags = getUserStateForModification().syncValues;
390438
generateJsonDiff(userStateTags, tags, userStateTags, null);
391439
}

0 commit comments

Comments
 (0)