diff --git a/package.json b/package.json index 7d6d3576..878ca787 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,12 @@ { - "version": "2.11.4", + "version": "3.0.0", "name": "onesignal-cordova-plugin", "cordova_name": "OneSignal Push Notifications", "description": "OneSignal is a high volume Push Notification service for mobile apps. In addition to basic notification delivery, OneSignal also provides tools to localize, target, schedule, and automate notifications that you send.", "license": "MIT", + "main": "www/OneSignalPlugin.js", + "typings": "types/index.d.ts", "keywords": [ "push", "notification", @@ -23,7 +25,6 @@ "platforms": [ "android", "ios", - "windows", "amazon-fireos" ], "engines": [ @@ -53,7 +54,6 @@ "platforms": [ "android", "ios", - "windows", "amazon-fireos" ] }, diff --git a/plugin.xml b/plugin.xml index 05cd5d78..da35f1bb 100644 --- a/plugin.xml +++ b/plugin.xml @@ -2,18 +2,18 @@ + version="3.0.0"> OneSignal Push Notifications Josh Kasten, Bradley Hesse, Rodrigo Gomez-Palacio OneSignal is a high volume Push Notification service for mobile apps. In addition to basic notification delivery, OneSignal also provides tools to localize, target, schedule, A/B test, and automate notifications that you send. - push,notification,push notification,push notifications,apns,gcm,adm,retention,messaging,ios,android,windows phone + push,notification,push notification,push notifications,apns,gcm,adm,retention,messaging,ios,android MIT - + @@ -25,43 +25,29 @@ + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + @@ -70,11 +56,9 @@ - + - - remote-notification @@ -88,28 +72,20 @@ production - + + + + + + + + + + - - - - - - - - - - - - - - - - - diff --git a/src/android/com/plugin/gcm/CallbackHelper.java b/src/android/com/onesignal/cordova/CallbackHelper.java similarity index 98% rename from src/android/com/plugin/gcm/CallbackHelper.java rename to src/android/com/onesignal/cordova/CallbackHelper.java index d1dd2b27..7e261dc7 100644 --- a/src/android/com/plugin/gcm/CallbackHelper.java +++ b/src/android/com/onesignal/cordova/CallbackHelper.java @@ -1,4 +1,4 @@ -package com.plugin.gcm; +package com.onesignal.cordova; import org.apache.cordova.CallbackContext; import org.json.JSONObject; diff --git a/src/android/com/plugin/gcm/OneSignalController.java b/src/android/com/onesignal/cordova/OneSignalController.java similarity index 62% rename from src/android/com/plugin/gcm/OneSignalController.java rename to src/android/com/onesignal/cordova/OneSignalController.java index 8755d81b..877400dd 100644 --- a/src/android/com/plugin/gcm/OneSignalController.java +++ b/src/android/com/onesignal/cordova/OneSignalController.java @@ -1,43 +1,70 @@ -package com.plugin.gcm; +package com.onesignal.cordova; + +import com.onesignal.OSDeviceState; +import com.onesignal.OneSignal; +import com.onesignal.OneSignal.PostNotificationResponseHandler; -import android.util.Log; import org.apache.cordova.CallbackContext; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; + import java.util.ArrayList; import java.util.Collection; +public class OneSignalController { -import com.onesignal.OneSignal; -import com.onesignal.OSNotification; -import com.onesignal.OSNotificationOpenResult; -import com.onesignal.OSInAppMessageAction; - -import com.onesignal.OneSignal.NotificationOpenedHandler; -import com.onesignal.OneSignal.NotificationReceivedHandler; -import com.onesignal.OneSignal.GetTagsHandler; -import com.onesignal.OneSignal.IdsAvailableHandler; -import com.onesignal.OneSignal.PostNotificationResponseHandler; + /** + * Subscriptions + */ + public static boolean getDeviceState(CallbackContext callbackContext) { + OSDeviceState deviceState = OneSignal.getDeviceState(); + if (deviceState != null) + CallbackHelper.callbackSuccess(callbackContext, deviceState.toJSONObject()); + return true; + } -public class OneSignalController { - private static CallbackContext notifReceivedCallbackContext; - private static CallbackContext notifOpenedCallbackContext; - private static CallbackContext inAppMessageClickedCallbackContext; + public static boolean disablePush(JSONArray data) { + try { + OneSignal.disablePush(data.getBoolean(0)); + return true; + } + catch (Throwable t) { + t.printStackTrace(); + return false; + } + } - private static final String TAG = "OneSignalPush"; + /** + * Misc + */ + public static void setLogLevel(JSONArray data) { + try { + int logLevel = data.getInt(0); + int visualLevel = data.getInt(1); + OneSignal.setLogLevel(logLevel, visualLevel); + } catch (Throwable t) { + t.printStackTrace(); + } + } + public static boolean setLanguage(JSONArray data) { + try { + OneSignal.setLanguage(data.getString(0)); + return true; + } + catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + /** * Tags */ public static boolean getTags(CallbackContext callbackContext) { final CallbackContext jsTagsAvailableCallBack = callbackContext; - OneSignal.getTags(new GetTagsHandler() { - @Override - public void tagsAvailable(JSONObject tags) { - CallbackHelper.callbackSuccess(jsTagsAvailableCallBack, tags); - } - }); + OneSignal.getTags(tags -> CallbackHelper.callbackSuccess(jsTagsAvailableCallBack, tags)); return true; } @@ -64,25 +91,6 @@ public static boolean deleteTags(JSONArray data) { } } - /** - * Subscriptions - */ - public static boolean getPermissionSubscriptionState(CallbackContext callbackContext) { - CallbackHelper.callbackSuccess(callbackContext, OneSignal.getPermissionSubscriptionState().toJSONObject()); - return true; - } - - public static boolean setSubscription(JSONArray data) { - try { - OneSignal.setSubscription(data.getBoolean(0)); - return true; - } - catch (Throwable t) { - t.printStackTrace(); - return false; - } - } - /** * Notifications */ @@ -122,103 +130,61 @@ public static boolean clearOneSignalNotifications() { } } - /** - * Location - */ - - public static void promptLocation() { - OneSignal.promptLocation(); - } - - public static void setLocationShared(JSONArray data) { + public static boolean removeNotification(JSONArray data) { try { - OneSignal.setLocationShared(data.getBoolean(0)); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - /** - * Misc - */ - public static boolean registerForPushNotifications() { - // doesn't apply to Android - return true; - } - - public static boolean getIds(CallbackContext callbackContext) { - final CallbackContext jsIdsAvailableCallBack = callbackContext; - OneSignal.idsAvailable(new IdsAvailableHandler() { - @Override - public void idsAvailable(String userId, String registrationId) { - JSONObject jsonIds = new JSONObject(); - try { - jsonIds.put("userId", userId); - if (registrationId != null) - jsonIds.put("pushToken", registrationId); - else - jsonIds.put("pushToken", ""); - - CallbackHelper.callbackSuccess(jsIdsAvailableCallBack, jsonIds); - } - catch (Throwable t) { - t.printStackTrace(); - } - } - }); - return true; - } - - public static boolean enableVibrate(JSONArray data) { - try { - OneSignal.enableVibrate(data.getBoolean(0)); + OneSignal.removeNotification(data.getInt(0)); return true; - } - catch (Throwable t) { + } catch (Throwable t) { t.printStackTrace(); return false; } } - public static boolean enableSound(JSONArray data) { + public static boolean removeGroupedNotifications(JSONArray data) { try { - OneSignal.enableSound(data.getBoolean(0)); + OneSignal.removeGroupedNotifications(data.getString(0)); return true; - } - catch (Throwable t) { + } catch (Throwable t) { t.printStackTrace(); return false; } } - public static boolean setInFocusDisplaying(JSONArray data) { - try { - OneSignal.setInFocusDisplaying(data.getInt(0)); - return true; - } - catch (JSONException e) { - Log.e(TAG, "execute: Got JSON Exception " + e.getMessage()); - return false; - } + public static boolean registerForProvisionalAuthorization() { + // doesn't apply to Android + return true; } - public static void setLogLevel(JSONArray data) { + public static boolean promptForPushNotificationsWithUserResponse() { + // doesn't apply to Android + return true; + } + + public static boolean unsubscribeWhenNotificationsAreDisabled(JSONArray data) { try { - JSONObject jo = data.getJSONObject(0); - OneSignal.setLogLevel(jo.optInt("logLevel", 0), jo.optInt("visualLevel", 0)); - } - catch(Throwable t) { - t.printStackTrace(); + OneSignal.unsubscribeWhenNotificationsAreDisabled(data.getBoolean(0)); + return true; + } catch (JSONException e) { + e.printStackTrace(); } + return false; } + /** + * Privacy consent + */ public static boolean userProvidedConsent(CallbackContext callbackContext) { boolean providedConsent = OneSignal.userProvidedPrivacyConsent(); - final CallbackContext jsUserProvidedConsentContext = callbackContext; CallbackHelper.callbackSuccessBoolean(callbackContext, providedConsent); return true; } + public static boolean requiresUserPrivacyConsent(CallbackContext callbackContext) { + boolean requiresUserPrivacyConsent = OneSignal.requiresUserPrivacyConsent(); + CallbackHelper.callbackSuccessBoolean(callbackContext, requiresUserPrivacyConsent); + return true; + } + public static boolean setRequiresConsent(CallbackContext callbackContext, JSONArray data) { try { OneSignal.setRequiresUserPrivacyConsent(data.getBoolean(0)); @@ -229,7 +195,7 @@ public static boolean setRequiresConsent(CallbackContext callbackContext, JSONAr } } - public static boolean grantConsent(JSONArray data) { + public static boolean provideUserConsent(JSONArray data) { try { OneSignal.provideUserConsent(data.getBoolean(0)); return true; @@ -239,6 +205,9 @@ public static boolean grantConsent(JSONArray data) { } } + /** + * External User Is + */ public static boolean setExternalUserId(final CallbackContext callback, JSONArray data) { try { String authHashToken = null; @@ -247,9 +216,14 @@ public static boolean setExternalUserId(final CallbackContext callback, JSONArra OneSignal.setExternalUserId(data.getString(0), authHashToken, new OneSignal.OSExternalUserIdUpdateCompletionHandler() { @Override - public void onComplete(JSONObject results) { + public void onSuccess(JSONObject results) { CallbackHelper.callbackSuccess(callback, results); } + + @Override + public void onFailure(OneSignal.ExternalIdError error) { + CallbackHelper.callbackError(callback, error.getMessage()); + } }); return true; } catch (JSONException e) { @@ -261,11 +235,36 @@ public void onComplete(JSONObject results) { public static boolean removeExternalUserId(final CallbackContext callback) { OneSignal.removeExternalUserId(new OneSignal.OSExternalUserIdUpdateCompletionHandler() { @Override - public void onComplete(JSONObject results) { + public void onSuccess(JSONObject results) { CallbackHelper.callbackSuccess(callback, results); } + + @Override + public void onFailure(OneSignal.ExternalIdError error) { + CallbackHelper.callbackError(callback, error.getMessage()); + } }); return true; } -} \ No newline at end of file + /** + * Location + */ + public static void promptLocation() { + OneSignal.promptLocation(); + } + + public static void setLocationShared(JSONArray data) { + try { + OneSignal.setLocationShared(data.getBoolean(0)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public static boolean isLocationShared(CallbackContext callbackContext) { + // Need to be implemented in Android + CallbackHelper.callbackSuccessBoolean(callbackContext, false); + return true; + } +} diff --git a/src/android/com/onesignal/cordova/OneSignalEmailController.java b/src/android/com/onesignal/cordova/OneSignalEmailController.java new file mode 100644 index 00000000..7a7e4e6f --- /dev/null +++ b/src/android/com/onesignal/cordova/OneSignalEmailController.java @@ -0,0 +1,88 @@ +package com.onesignal.cordova; + +import com.onesignal.OneSignal; +import com.onesignal.OneSignal.EmailUpdateError; +import com.onesignal.OneSignal.EmailUpdateHandler; + +import org.apache.cordova.CallbackContext; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class OneSignalEmailController { + public static boolean setEmail(CallbackContext callbackContext, JSONArray data) { + final CallbackContext jsSetEmailContext = callbackContext; + try { + OneSignal.setEmail(data.getString(0), data.getString(1), new EmailUpdateHandler() { + @Override + public void onSuccess() { + CallbackHelper.callbackSuccess(jsSetEmailContext, null); + } + + @Override + public void onFailure(EmailUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetEmailContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + + public static boolean setUnauthenticatedEmail(CallbackContext callbackContext, JSONArray data) { + final CallbackContext jsSetEmailContext = callbackContext; + try { + OneSignal.setEmail(data.getString(0), null, new EmailUpdateHandler() { + @Override + public void onSuccess() { + CallbackHelper.callbackSuccess(jsSetEmailContext, null); + } + + @Override + public void onFailure(EmailUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetEmailContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + + public static boolean logoutEmail(CallbackContext callbackContext) { + final CallbackContext jsSetEmailContext = callbackContext; + OneSignal.logoutEmail(new EmailUpdateHandler() { + @Override + public void onSuccess() { + CallbackHelper.callbackSuccess(jsSetEmailContext, null); + } + + @Override + public void onFailure(EmailUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetEmailContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } +} diff --git a/src/android/com/onesignal/cordova/OneSignalInAppMessagingController.java b/src/android/com/onesignal/cordova/OneSignalInAppMessagingController.java new file mode 100644 index 00000000..8645559f --- /dev/null +++ b/src/android/com/onesignal/cordova/OneSignalInAppMessagingController.java @@ -0,0 +1,99 @@ +package com.onesignal.cordova; + +import com.onesignal.OneSignal; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class OneSignalInAppMessagingController { + + // This is to prevent an issue where if two Javascript calls are made to OneSignal expecting a callback then only one would fire. + private static void callbackSuccess(CallbackContext callbackContext, JSONObject jsonObject) { + if (jsonObject == null) // in case there are no data + jsonObject = new JSONObject(); + + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, jsonObject); + pluginResult.setKeepCallback(true); + callbackContext.sendPluginResult(pluginResult); + } + + public static boolean addTriggers(JSONArray data) { + try { + JSONObject triggersObject = data.getJSONObject(0); + Map triggers = new HashMap<>(); + Iterator keys = triggersObject.keys(); + + while (keys.hasNext()) { + String key = keys.next(); + triggers.put(key, triggersObject.get(key)); + } + + OneSignal.addTriggers(triggers); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean removeTriggersForKeys(JSONArray data) { + try { + JSONArray triggerKeysArray = data.getJSONArray(0); + List triggerKeys = new ArrayList<>(); + + for (int i = 0; i < triggerKeysArray.length(); i++) { + triggerKeys.add(triggerKeysArray.getString(i)); + } + + OneSignal.removeTriggersForKeys(triggerKeys); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean getTriggerValueForKey(CallbackContext callbackContext, JSONArray data) { + try { + Object value = OneSignal.getTriggerValueForKey(data.getString(0)); + if (value == null) { + callbackSuccess(callbackContext, new JSONObject()); + } else { + callbackSuccess(callbackContext, new JSONObject( + "{value:" + + value.toString() + + "}")); + } + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean pauseInAppMessages(JSONArray data) { + try { + OneSignal.pauseInAppMessages(data.getBoolean(0)); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean isInAppMessagingPaused(CallbackContext callbackContext) { + boolean inAppMessagingPaused = OneSignal.isInAppMessagingPaused(); + CallbackHelper.callbackSuccessBoolean(callbackContext, inAppMessagingPaused); + return true; + } + +} diff --git a/src/android/com/plugin/gcm/OneSignalObserverController.java b/src/android/com/onesignal/cordova/OneSignalObserverController.java similarity index 78% rename from src/android/com/plugin/gcm/OneSignalObserverController.java rename to src/android/com/onesignal/cordova/OneSignalObserverController.java index 8c0df697..5c7ff02d 100644 --- a/src/android/com/plugin/gcm/OneSignalObserverController.java +++ b/src/android/com/onesignal/cordova/OneSignalObserverController.java @@ -1,4 +1,4 @@ -package com.plugin.gcm; +package com.onesignal.cordova; import org.apache.cordova.CallbackContext; @@ -10,19 +10,23 @@ import com.onesignal.OSPermissionObserver; import com.onesignal.OSEmailSubscriptionObserver; +import com.onesignal.OSSMSSubscriptionObserver; import com.onesignal.OSSubscriptionObserver; import com.onesignal.OSPermissionStateChanges; import com.onesignal.OSSubscriptionStateChanges; import com.onesignal.OSEmailSubscriptionStateChanges; +import com.onesignal.OSSMSSubscriptionStateChanges; public class OneSignalObserverController { private static CallbackContext jsPermissionObserverCallBack; private static CallbackContext jsSubscriptionObserverCallBack; private static CallbackContext jsEmailSubscriptionObserverCallBack; + private static CallbackContext jsSMSSubscriptionObserverCallBack; private static OSPermissionObserver permissionObserver; private static OSSubscriptionObserver subscriptionObserver; private static OSEmailSubscriptionObserver emailSubscriptionObserver; + private static OSSMSSubscriptionObserver smsSubscriptionObserver; // This is to prevent an issue where if two Javascript calls are made to OneSignal expecting a callback then only one would fire. private static void callbackSuccess(CallbackContext callbackContext, JSONObject jsonObject) { @@ -75,4 +79,18 @@ public void onOSEmailSubscriptionChanged(OSEmailSubscriptionStateChanges stateCh } return true; } -} \ No newline at end of file + + public static boolean addSMSSubscriptionObserver(CallbackContext callbackContext) { + jsSMSSubscriptionObserverCallBack = callbackContext; + if (smsSubscriptionObserver == null) { + smsSubscriptionObserver = new OSSMSSubscriptionObserver() { + @Override + public void onSMSSubscriptionChanged(OSSMSSubscriptionStateChanges stateChanges) { + callbackSuccess(jsSMSSubscriptionObserverCallBack, stateChanges.toJSONObject()); + } + }; + OneSignal.addSMSSubscriptionObserver(smsSubscriptionObserver); + } + return true; + } +} diff --git a/src/android/com/onesignal/cordova/OneSignalOutcomeController.java b/src/android/com/onesignal/cordova/OneSignalOutcomeController.java new file mode 100644 index 00000000..9d9f2129 --- /dev/null +++ b/src/android/com/onesignal/cordova/OneSignalOutcomeController.java @@ -0,0 +1,82 @@ +package com.onesignal.cordova; + +import android.util.Log; + +import com.onesignal.OneSignal; + +import org.apache.cordova.CallbackContext; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class OneSignalOutcomeController { + + private static final String TAG = "OneSignalOutcome"; + + public static boolean sendUniqueOutcome(CallbackContext callbackContext, JSONArray data) { + try { + final CallbackContext jsSendUniqueOutcomeCallback = callbackContext; + final String name = data.getString(0); + OneSignal.sendUniqueOutcome(name, outcomeEvent -> { + if (outcomeEvent == null) + CallbackHelper.callbackSuccess(jsSendUniqueOutcomeCallback, new JSONObject()); + else { + try { + CallbackHelper.callbackSuccess(jsSendUniqueOutcomeCallback, outcomeEvent.toJSONObject()); + } catch (JSONException e) { + Log.e(TAG, "sendUniqueOutcome with name: " + name + ", failed with message: " + e.getMessage()); + } + } + }); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean sendOutcome(CallbackContext callbackContext, JSONArray data) { + try { + final CallbackContext jsSendOutcomeCallback = callbackContext; + final String name = data.getString(0); + OneSignal.sendOutcome(name, outcomeEvent -> { + if (outcomeEvent == null) + CallbackHelper.callbackSuccess(jsSendOutcomeCallback, new JSONObject()); + else { + try { + CallbackHelper.callbackSuccess(jsSendOutcomeCallback, outcomeEvent.toJSONObject()); + } catch (JSONException e) { + Log.e(TAG, "sendOutcome with name: " + name + ", failed with message: " + e.getMessage()); + } + } + }); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean sendOutcomeWithValue(CallbackContext callbackContext, JSONArray data) { + try { + final CallbackContext jsSendOutcomeWithValueCallback = callbackContext; + final String name = data.getString(0); + final float value = Double.valueOf(data.optDouble(1)).floatValue(); + OneSignal.sendOutcomeWithValue(name, value, outcomeEvent -> { + if (outcomeEvent == null) + CallbackHelper.callbackSuccess(jsSendOutcomeWithValueCallback, new JSONObject()); + else { + try { + CallbackHelper.callbackSuccess(jsSendOutcomeWithValueCallback, outcomeEvent.toJSONObject()); + } catch (JSONException e) { + Log.e(TAG, "sendOutcomeWithValue with name: " + name + " and value: " + value + ", failed with message: " + e.getMessage()); + } + } + }); + return true; + } catch (JSONException e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/android/com/plugin/gcm/OneSignalPush.java b/src/android/com/onesignal/cordova/OneSignalPush.java similarity index 55% rename from src/android/com/plugin/gcm/OneSignalPush.java rename to src/android/com/onesignal/cordova/OneSignalPush.java index 76c35c6c..e82edd20 100644 --- a/src/android/com/plugin/gcm/OneSignalPush.java +++ b/src/android/com/onesignal/cordova/OneSignalPush.java @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2017 OneSignal + * Copyright 2021 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,69 +25,74 @@ * THE SOFTWARE. */ -package com.plugin.gcm; +package com.onesignal.cordova; import android.util.Log; + +import com.onesignal.OSInAppMessageAction; +import com.onesignal.OSNotification; +import com.onesignal.OSNotificationOpenedResult; +import com.onesignal.OSNotificationReceivedEvent; +import com.onesignal.OneSignal; + import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; -import com.onesignal.OneSignal; -import com.onesignal.OSNotification; -import com.onesignal.OSNotificationOpenResult; -import com.onesignal.OSInAppMessageAction; -import com.onesignal.OneSignal.NotificationOpenedHandler; -import com.onesignal.OneSignal.NotificationReceivedHandler; -import com.onesignal.OneSignal.InAppMessageClickHandler; - -import com.onesignal.OSPermissionObserver; -import com.onesignal.OSEmailSubscriptionObserver; -import com.onesignal.OSSubscriptionObserver; +import java.util.HashMap; public class OneSignalPush extends CordovaPlugin { private static final String TAG = "OneSignalPush"; - private static final String SET_NOTIFICATION_RECEIVED_HANDLER = "setNotificationReceivedHandler"; + private static final String SET_NOTIFICATION_WILL_SHOW_IN_FOREGROUND_HANDLER = "setNotificationWillShowInForegroundHandler"; private static final String SET_NOTIFICATION_OPENED_HANDLER = "setNotificationOpenedHandler"; private static final String SET_IN_APP_MESSAGE_CLICK_HANDLER = "setInAppMessageClickHandler"; + private static final String COMPLETE_NOTIFICATION = "completeNotification"; private static final String INIT = "init"; - private static final String SET_IN_FOCUS_DISPLAYING = "setInFocusDisplaying"; + private static final String GET_DEVICE_STATE = "getDeviceState"; - private static final String GET_PERMISSION_SUBCRIPTION_STATE = "getPermissionSubscriptionState"; - private static final String GET_IDS = "getIds"; + private static final String SET_LANGUAGE = "setLanguage"; private static final String ADD_PERMISSION_OBSERVER = "addPermissionObserver"; private static final String ADD_SUBSCRIPTION_OBSERVER = "addSubscriptionObserver"; + private static final String ADD_EMAIL_SUBSCRIPTION_OBSERVER = "addEmailSubscriptionObserver"; + private static final String ADD_SMS_SUBSCRIPTION_OBSERVER = "addSMSSubscriptionObserver"; private static final String GET_TAGS = "getTags"; private static final String DELETE_TAGS = "deleteTags"; private static final String SEND_TAGS = "sendTags"; - private static final String SYNC_HASHED_EMAIL = "syncHashedEmail"; - private static final String REGISTER_FOR_PUSH_NOTIFICATIONS = "registerForPushNotifications"; - private static final String ENABLE_VIBRATE = "enableVibrate"; - private static final String ENABLE_SOUND = "enableSound"; + private static final String REGISTER_FOR_PROVISIONAL_AUTHORIZATION = "registerForProvisionalAuthorization"; + private static final String PROMPT_FOR_PUSH_NOTIFICATIONS_WITH_USER_RESPONSE = "promptForPushNotificationsWithUserResponse"; + private static final String UNSUBSCRIBE_WHEN_NOTIFICATIONS_DISABLED = "unsubscribeWhenNotificationsAreDisabled"; - private static final String SET_SUBSCRIPTION = "setSubscription"; - private static final String POST_NOTIFICATION = "postNotification"; - private static final String PROMPT_LOCATION = "promptLocation"; private static final String CLEAR_ONESIGNAL_NOTIFICATIONS = "clearOneSignalNotifications"; + private static final String REMOVE_NOTIFICATION = "removeNotification"; + private static final String REMOVE_GROUPED_NOTIFICATIONS = "removeGroupedNotifications"; + + private static final String DISABLE_PUSH = "disablePush"; + private static final String POST_NOTIFICATION = "postNotification"; private static final String SET_EMAIL = "setEmail"; private static final String SET_UNAUTHENTICATED_EMAIL = "setUnauthenticatedEmail"; private static final String LOGOUT_EMAIL = "logoutEmail"; - private static final String ADD_EMAIL_SUBSCRIPTION_OBSERVER = "addEmailSubscriptionObserver"; + + private static final String SET_SMS_NUMBER = "setSMSNumber"; + private static final String SET_UNAUTHENTICATED_SMS_NUMBER = "setUnauthenticatedSMSNumber"; + private static final String LOGOUT_SMS_NUMBER = "logoutSMSNumber"; private static final String SET_LOG_LEVEL = "setLogLevel"; private static final String SET_LOCATION_SHARED = "setLocationShared"; + private static final String IS_LOCATION_SHARED = "isLocationShared"; + private static final String PROMPT_LOCATION = "promptLocation"; private static final String USER_PROVIDED_CONSENT = "userProvidedPrivacyConsent"; + private static final String REQUIRES_CONSENT = "requiresUserPrivacyConsent"; private static final String SET_REQUIRES_CONSENT = "setRequiresUserPrivacyConsent"; - private static final String GRANT_CONSENT = "provideUserConsent"; + private static final String PROVIDE_USER_CONSENT = "provideUserConsent"; private static final String SET_EXTERNAL_USER_ID = "setExternalUserId"; private static final String REMOVE_EXTERNAL_USER_ID = "removeExternalUserId"; @@ -95,54 +100,39 @@ public class OneSignalPush extends CordovaPlugin { private static final String ADD_TRIGGERS = "addTriggers"; private static final String REMOVE_TRIGGERS_FOR_KEYS = "removeTriggersForKeys"; private static final String GET_TRIGGER_VALUE_FOR_KEY = "getTriggerValueForKey"; + private static final String PAUSE_IN_APP_MESSAGES = "pauseInAppMessages"; + private static final String IN_APP_MESSAGING_PAUSED = "isInAppMessagingPaused"; private static final String SEND_OUTCOME = "sendOutcome"; private static final String SEND_UNIQUE_OUTCOME = "sendUniqueOutcome"; private static final String SEND_OUTCOME_WITH_VALUE = "sendOutcomeWithValue"; - private static CallbackContext notifReceivedCallbackContext; - private static CallbackContext notifOpenedCallbackContext; - private static CallbackContext inAppMessageClickedCallbackContext; + private static final HashMap notificationReceivedEventCache = new HashMap<>(); - - public static boolean setNotificationReceivedHandler(CallbackContext callbackContext) { - notifReceivedCallbackContext = callbackContext; + public boolean setNotificationWillShowInForegroundHandler(CallbackContext callbackContext) { + OneSignal.setNotificationWillShowInForegroundHandler(new CordovaNotificationInForegroundHandler(callbackContext)); return true; } - public static boolean setNotificationOpenedHandler(CallbackContext callbackContext) { - notifOpenedCallbackContext = callbackContext; + public boolean setNotificationOpenedHandler(CallbackContext callbackContext) { + OneSignal.setNotificationOpenedHandler(new CordovaNotificationOpenHandler(callbackContext)); return true; } - public static boolean setInAppMessageClickHandler(CallbackContext callbackContext) { - inAppMessageClickedCallbackContext = callbackContext; + public boolean setInAppMessageClickHandler(CallbackContext callbackContext) { + OneSignal.setInAppMessageClickHandler(new CordovaInAppMessageClickHandler(callbackContext)); return true; } - public boolean init(CallbackContext callbackContext, JSONArray data) { + public boolean init(JSONArray data) { try { String appId = data.getString(0); - String googleProjectNumber = data.getString(1); OneSignal.sdkType = "cordova"; - OneSignal.Builder builder = OneSignal.getCurrentOrNewInitBuilder(); - builder.unsubscribeWhenNotificationsAreDisabled(true); - builder.filterOtherGCMReceivers(true); - builder.setInAppMessageClickHandler(new CordovaInAppMessageClickHandler(inAppMessageClickedCallbackContext)); - - OneSignal.init(this.cordova.getActivity(), - googleProjectNumber, - appId, - new CordovaNotificationOpenedHandler(notifOpenedCallbackContext), - new CordovaNotificationReceivedHandler(notifReceivedCallbackContext) - ); - // data.getJSONObject(2) is for iOS settings. - - int displayOption = data.getInt(3); - OneSignal.setInFocusDisplaying(displayOption); + OneSignal.setAppId(appId); + OneSignal.initWithContext(this.cordova.getActivity()); return true; } catch (JSONException e) { @@ -155,26 +145,33 @@ public boolean init(CallbackContext callbackContext, JSONArray data) { public boolean execute(String action, JSONArray data, CallbackContext callbackContext) { boolean result = false; - switch(action) { case SET_NOTIFICATION_OPENED_HANDLER: result = setNotificationOpenedHandler(callbackContext); break; - case SET_NOTIFICATION_RECEIVED_HANDLER: - result = setNotificationReceivedHandler(callbackContext); + case SET_NOTIFICATION_WILL_SHOW_IN_FOREGROUND_HANDLER: + result = setNotificationWillShowInForegroundHandler(callbackContext); break; case SET_IN_APP_MESSAGE_CLICK_HANDLER: result = setInAppMessageClickHandler(callbackContext); break; + case COMPLETE_NOTIFICATION: + result = completeNotification(data); + break; + case INIT: - result = init(callbackContext, data); + result = init(data); + break; + + case GET_DEVICE_STATE: + result = OneSignalController.getDeviceState(callbackContext); break; - case SET_IN_FOCUS_DISPLAYING: - result = OneSignalController.setInFocusDisplaying(data); + case SET_LANGUAGE: + result = OneSignalController.setLanguage(data); break; case ADD_PERMISSION_OBSERVER: @@ -189,16 +186,12 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo result = OneSignalObserverController.addEmailSubscriptionObserver(callbackContext); break; - case GET_TAGS: - result = OneSignalController.getTags(callbackContext); - break; - - case GET_PERMISSION_SUBCRIPTION_STATE: - result = OneSignalController.getPermissionSubscriptionState(callbackContext); + case ADD_SMS_SUBSCRIPTION_OBSERVER: + result = OneSignalObserverController.addSMSSubscriptionObserver(callbackContext); break; - case GET_IDS: - result = OneSignalController.getIds(callbackContext); + case GET_TAGS: + result = OneSignalController.getTags(callbackContext); break; case SEND_TAGS: @@ -209,40 +202,40 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo result = OneSignalController.deleteTags(data); break; - case REGISTER_FOR_PUSH_NOTIFICATIONS: - result = OneSignalController.registerForPushNotifications(); + case REGISTER_FOR_PROVISIONAL_AUTHORIZATION: + result = OneSignalController.registerForProvisionalAuthorization(); break; - case ENABLE_VIBRATE: - result = OneSignalController.enableVibrate(data); + case PROMPT_FOR_PUSH_NOTIFICATIONS_WITH_USER_RESPONSE: + result = OneSignalController.promptForPushNotificationsWithUserResponse(); break; - case ENABLE_SOUND: - result = OneSignalController.enableSound(data); + case UNSUBSCRIBE_WHEN_NOTIFICATIONS_DISABLED: + result = OneSignalController.unsubscribeWhenNotificationsAreDisabled(data); break; - case SET_SUBSCRIPTION: - result = OneSignalController.setSubscription(data); + case CLEAR_ONESIGNAL_NOTIFICATIONS: + result = OneSignalController.clearOneSignalNotifications(); break; - case POST_NOTIFICATION: - result = OneSignalController.postNotification(callbackContext, data); + case REMOVE_NOTIFICATION: + result = OneSignalController.removeNotification(data); break; - case PROMPT_LOCATION: - OneSignalController.promptLocation(); + case REMOVE_GROUPED_NOTIFICATIONS: + result = OneSignalController.removeGroupedNotifications(data); break; - case SYNC_HASHED_EMAIL: - OneSignalEmailController.syncHashedEmail(data); + case DISABLE_PUSH: + result = OneSignalController.disablePush(data); break; - case SET_LOG_LEVEL: - OneSignalController.setLogLevel(data); + case POST_NOTIFICATION: + result = OneSignalController.postNotification(callbackContext, data); break; - case CLEAR_ONESIGNAL_NOTIFICATIONS: - result = OneSignalController.clearOneSignalNotifications(); + case SET_LOG_LEVEL: + OneSignalController.setLogLevel(data); break; case SET_EMAIL: @@ -257,20 +250,44 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo result = OneSignalEmailController.logoutEmail(callbackContext); break; + case SET_SMS_NUMBER: + result = OneSignalSMSController.setSMSNumber(callbackContext, data); + break; + + case SET_UNAUTHENTICATED_SMS_NUMBER: + result = OneSignalSMSController.setUnauthenticatedEmail(callbackContext, data); + break; + + case LOGOUT_SMS_NUMBER: + result = OneSignalSMSController.logoutSMSNumber(callbackContext); + break; + + case PROMPT_LOCATION: + OneSignalController.promptLocation(); + break; + case SET_LOCATION_SHARED: OneSignalController.setLocationShared(data); break; + case IS_LOCATION_SHARED: + result = OneSignalController.isLocationShared(callbackContext); + break; + case USER_PROVIDED_CONSENT: result = OneSignalController.userProvidedConsent(callbackContext); break; + case REQUIRES_CONSENT: + result = OneSignalController.requiresUserPrivacyConsent(callbackContext); + break; + case SET_REQUIRES_CONSENT: result = OneSignalController.setRequiresConsent(callbackContext, data); break; - case GRANT_CONSENT: - result = OneSignalController.grantConsent(data); + case PROVIDE_USER_CONSENT: + result = OneSignalController.provideUserConsent(data); break; case SET_EXTERNAL_USER_ID: @@ -297,6 +314,10 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo result = OneSignalInAppMessagingController.pauseInAppMessages(data); break; + case IN_APP_MESSAGING_PAUSED: + result = OneSignalInAppMessagingController.isInAppMessagingPaused(callbackContext); + break; + case SEND_OUTCOME: result = OneSignalOutcomeController.sendOutcome(callbackContext, data); break; @@ -317,50 +338,75 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo return result; } + private boolean completeNotification(JSONArray data) { + try { + String notificationId = data.getString(0); + boolean shouldDisplay = data.getBoolean(1); + + OSNotificationReceivedEvent notificationReceivedEvent = notificationReceivedEventCache.get(notificationId); + + if (notificationReceivedEvent == null) { + OneSignal.onesignalLog(OneSignal.LOG_LEVEL.ERROR, "Could not find notification completion block with id: " + notificationId); + return false; + } + + if (shouldDisplay) + notificationReceivedEvent.complete(notificationReceivedEvent.getNotification()); + else + notificationReceivedEvent.complete(null); + + return true; + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } /** * Handlers */ - private class CordovaNotificationReceivedHandler implements NotificationReceivedHandler { + private static class CordovaNotificationInForegroundHandler implements OneSignal.OSNotificationWillShowInForegroundHandler { - private CallbackContext jsNotificationReceivedCallBack; + private CallbackContext jsNotificationInForegroundCallBack; - public CordovaNotificationReceivedHandler(CallbackContext inCallbackContext) { - jsNotificationReceivedCallBack = inCallbackContext; + public CordovaNotificationInForegroundHandler(CallbackContext inCallbackContext) { + jsNotificationInForegroundCallBack = inCallbackContext; } @Override - public void notificationReceived(OSNotification notification) { + public void notificationWillShowInForeground(OSNotificationReceivedEvent notificationReceivedEvent) { try { - CallbackHelper.callbackSuccess(jsNotificationReceivedCallBack, new JSONObject(notification.stringify())); - } - catch (Throwable t) { + OSNotification notification = notificationReceivedEvent.getNotification(); + notificationReceivedEventCache.put(notification.getNotificationId(), notificationReceivedEvent); + + CallbackHelper.callbackSuccess(jsNotificationInForegroundCallBack, notificationReceivedEvent.toJSONObject()); + } catch (Throwable t) { t.printStackTrace(); } } } - private class CordovaNotificationOpenedHandler implements NotificationOpenedHandler { + private static class CordovaNotificationOpenHandler implements OneSignal.OSNotificationOpenedHandler { private CallbackContext jsNotificationOpenedCallBack; - public CordovaNotificationOpenedHandler(CallbackContext inCallbackContext) { + public CordovaNotificationOpenHandler(CallbackContext inCallbackContext) { jsNotificationOpenedCallBack = inCallbackContext; } @Override - public void notificationOpened(OSNotificationOpenResult result) { + public void notificationOpened(OSNotificationOpenedResult result) { try { - CallbackHelper.callbackSuccess(jsNotificationOpenedCallBack, new JSONObject(result.stringify())); - } - catch (Throwable t) { + if (jsNotificationOpenedCallBack != null) + CallbackHelper.callbackSuccess(jsNotificationOpenedCallBack, result.toJSONObject()); + } catch (Throwable t) { t.printStackTrace(); } } } - private class CordovaInAppMessageClickHandler implements InAppMessageClickHandler { + private static class CordovaInAppMessageClickHandler implements OneSignal.OSInAppMessageClickHandler { private CallbackContext jsInAppMessageClickedCallback; @@ -381,7 +427,7 @@ public void inAppMessageClicked(OSInAppMessageAction result) { @Override public void onDestroy() { - OneSignal.removeNotificationOpenedHandler(); - OneSignal.removeNotificationReceivedHandler(); + OneSignal.setNotificationOpenedHandler(null); + OneSignal.setNotificationWillShowInForegroundHandler(null); } } diff --git a/src/android/com/onesignal/cordova/OneSignalSMSController.java b/src/android/com/onesignal/cordova/OneSignalSMSController.java new file mode 100644 index 00000000..67830a80 --- /dev/null +++ b/src/android/com/onesignal/cordova/OneSignalSMSController.java @@ -0,0 +1,88 @@ +package com.onesignal.cordova; + +import com.onesignal.OneSignal; +import com.onesignal.OneSignal.EmailUpdateError; +import com.onesignal.OneSignal.EmailUpdateHandler; + +import org.apache.cordova.CallbackContext; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class OneSignalSMSController { + public static boolean setSMSNumber(CallbackContext callbackContext, JSONArray data) { + final CallbackContext jsSetSMSNumberContext = callbackContext; + try { + OneSignal.setSMSNumber(data.getString(0), data.getString(1), new OneSignal.OSSMSUpdateHandler() { + @Override + public void onSuccess(JSONObject result) { + CallbackHelper.callbackSuccess(jsSetSMSNumberContext, result); + } + + @Override + public void onFailure(OneSignal.OSSMSUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetSMSNumberContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + + public static boolean setUnauthenticatedEmail(CallbackContext callbackContext, JSONArray data) { + final CallbackContext jsSetSMSNumberContext = callbackContext; + try { + OneSignal.setSMSNumber(data.getString(0), null, new OneSignal.OSSMSUpdateHandler() { + @Override + public void onSuccess(JSONObject result) { + CallbackHelper.callbackSuccess(jsSetSMSNumberContext, result); + } + + @Override + public void onFailure(OneSignal.OSSMSUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetSMSNumberContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + + public static boolean logoutSMSNumber(CallbackContext callbackContext) { + final CallbackContext jsSetSMSNumberContext = callbackContext; + OneSignal.logoutSMSNumber(new OneSignal.OSSMSUpdateHandler() { + @Override + public void onSuccess(JSONObject result) { + CallbackHelper.callbackSuccess(jsSetSMSNumberContext, result); + } + + @Override + public void onFailure(OneSignal.OSSMSUpdateError error) { + try { + JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); + CallbackHelper.callbackError(jsSetSMSNumberContext, errorObject); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + + return true; + } +} diff --git a/src/android/com/plugin/gcm/OneSignalEmailController.java b/src/android/com/plugin/gcm/OneSignalEmailController.java deleted file mode 100644 index b4598530..00000000 --- a/src/android/com/plugin/gcm/OneSignalEmailController.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.plugin.gcm; - -import org.apache.cordova.CallbackContext; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import com.onesignal.OneSignal; -import com.onesignal.OneSignal.EmailUpdateHandler; -import com.onesignal.OneSignal.EmailUpdateError; - - -public class OneSignalEmailController { - public static boolean setEmail(CallbackContext callbackContext, JSONArray data) { - final CallbackContext jsSetEmailContext = callbackContext; - try { - OneSignal.setEmail(data.getString(0), data.getString(1), new EmailUpdateHandler() { - @Override - public void onSuccess() { - CallbackHelper.callbackSuccess(jsSetEmailContext, null); - } - - @Override - public void onFailure(EmailUpdateError error) { - try { - JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); - CallbackHelper.callbackError(jsSetEmailContext, errorObject); - } catch (JSONException e) { - e.printStackTrace(); - } - } - }); - - return true; - } catch(Throwable t) { - t.printStackTrace(); - return false; - } - } - - public static boolean setUnauthenticatedEmail(CallbackContext callbackContext, JSONArray data) { - final CallbackContext jsSetEmailContext = callbackContext; - try { - OneSignal.setEmail(data.getString(0), null, new EmailUpdateHandler() { - @Override - public void onSuccess() { - CallbackHelper.callbackSuccess(jsSetEmailContext, null); - } - - @Override - public void onFailure(EmailUpdateError error) { - try { - JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); - CallbackHelper.callbackError(jsSetEmailContext, errorObject); - } catch (JSONException e) { - e.printStackTrace(); - } - } - }); - - return true; - } catch (Throwable t) { - t.printStackTrace(); - return false; - } - } - - public static boolean logoutEmail(CallbackContext callbackContext) { - final CallbackContext jsSetEmailContext = callbackContext; - OneSignal.logoutEmail(new EmailUpdateHandler() { - @Override - public void onSuccess() { - CallbackHelper.callbackSuccess(jsSetEmailContext, null); - } - - @Override - public void onFailure(EmailUpdateError error) { - try { - JSONObject errorObject = new JSONObject("{'error' : '" + error.getMessage() + "'}"); - CallbackHelper.callbackError(jsSetEmailContext, errorObject); - } catch (JSONException e) { - e.printStackTrace(); - } - } - }); - - return true; - } - - public static void syncHashedEmail(JSONArray data) { - try { - OneSignal.syncHashedEmail(data.getString(0)); - } catch(Throwable t) { - t.printStackTrace(); - } - } -} diff --git a/src/android/com/plugin/gcm/OneSignalInAppMessagingController.java b/src/android/com/plugin/gcm/OneSignalInAppMessagingController.java deleted file mode 100644 index 090d94c2..00000000 --- a/src/android/com/plugin/gcm/OneSignalInAppMessagingController.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.plugin.gcm; - -import org.apache.cordova.CallbackContext; - -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - - -import com.onesignal.OneSignal; - - -public class OneSignalInAppMessagingController { - - // This is to prevent an issue where if two Javascript calls are made to OneSignal expecting a callback then only one would fire. - private static void callbackSuccess(CallbackContext callbackContext, JSONObject jsonObject) { - if (jsonObject == null) // in case there are no data - jsonObject = new JSONObject(); - - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, jsonObject); - pluginResult.setKeepCallback(true); - callbackContext.sendPluginResult(pluginResult); - } - - - public static boolean addTriggers(JSONArray data) { - try { - OneSignal.addTriggersFromJsonString(data.getJSONObject(0).toString()); - return true; - } catch (JSONException e) { - e.printStackTrace(); - return false; - } - } - - public static boolean removeTriggersForKeys(JSONArray data) { - try{ - OneSignal.removeTriggersForKeysFromJsonArrayString(data.getString(0)); - return true; - } catch (JSONException e){ - e.printStackTrace(); - return false; - } - } - - public static boolean getTriggerValueForKey(CallbackContext callbackContext, JSONArray data) { - try { - Object value = OneSignal.getTriggerValueForKey(data.getString(0)); - if (value == null) { - callbackSuccess(callbackContext, new JSONObject()); - } else { - callbackSuccess(callbackContext, new JSONObject( - "{value:" - + value.toString() - + "}")); - } - return true; - } catch (JSONException e){ - e.printStackTrace(); - return false; - } - } - - public static boolean pauseInAppMessages(JSONArray data) { - try { - OneSignal.pauseInAppMessages(data.getBoolean(0)); - return true; - } catch (JSONException e){ - e.printStackTrace(); - return false; - } - } - -} - diff --git a/src/android/com/plugin/gcm/OneSignalOutcomeController.java b/src/android/com/plugin/gcm/OneSignalOutcomeController.java deleted file mode 100644 index a671a8ad..00000000 --- a/src/android/com/plugin/gcm/OneSignalOutcomeController.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.plugin.gcm; - -import android.util.Log; - -import com.onesignal.OneSignal; -import com.onesignal.OutcomeEvent; -import com.onesignal.OneSignal.OutcomeCallback; - -import org.apache.cordova.CallbackContext; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public class OneSignalOutcomeController { - - private static final String TAG = "OneSignalOutcome"; - - public static boolean sendUniqueOutcome(CallbackContext callbackContext, JSONArray data) { - try { - final CallbackContext jsSendUniqueOutcomeCallback = callbackContext; - final String name = data.getString(0); - OneSignal.sendUniqueOutcome(name, new OutcomeCallback(){ - @Override - public void onSuccess(OutcomeEvent outcomeEvent) { - if (outcomeEvent == null) - CallbackHelper.callbackSuccess(jsSendUniqueOutcomeCallback, new JSONObject()); - else { - try { - CallbackHelper.callbackSuccess(jsSendUniqueOutcomeCallback, outcomeEvent.toJSONObject()); - } catch (JSONException e) { - Log.e(TAG, "sendUniqueOutcome with name: " + name + ", failed with message: " + e.getMessage()); - } - } - } - }); - return true; - } catch (JSONException e) { - e.printStackTrace(); - return false; - } - } - - public static boolean sendOutcome(CallbackContext callbackContext, JSONArray data) { - try { - final CallbackContext jsSendOutcomeCallback = callbackContext; - final String name = data.getString(0); - OneSignal.sendOutcome(name, new OutcomeCallback() { - @Override - public void onSuccess(OutcomeEvent outcomeEvent) { - if (outcomeEvent == null) - CallbackHelper.callbackSuccess(jsSendOutcomeCallback, new JSONObject()); - else { - try { - CallbackHelper.callbackSuccess(jsSendOutcomeCallback, outcomeEvent.toJSONObject()); - } catch (JSONException e) { - Log.e(TAG, "sendOutcome with name: " + name + ", failed with message: " + e.getMessage()); - } - } - } - }); - return true; - } catch (JSONException e) { - e.printStackTrace(); - return false; - } - } - - public static boolean sendOutcomeWithValue(CallbackContext callbackContext, JSONArray data) { - try { - final CallbackContext jsSendOutcomeWithValueCallback = callbackContext; - final String name = data.getString(0); - final float value = Double.valueOf(data.optDouble(1)).floatValue(); - OneSignal.sendOutcomeWithValue(name, value, new OutcomeCallback() { - @Override - public void onSuccess(OutcomeEvent outcomeEvent) { - if (outcomeEvent == null) - CallbackHelper.callbackSuccess(jsSendOutcomeWithValueCallback, new JSONObject()); - else { - try { - CallbackHelper.callbackSuccess(jsSendOutcomeWithValueCallback, outcomeEvent.toJSONObject()); - } catch (JSONException e) { - Log.e(TAG, "sendOutcomeWithValue with name: " + name + " and value: " + value + ", failed with message: " + e.getMessage()); - } - } - } - }); - return true; - } catch (JSONException e) { - e.printStackTrace(); - return false; - } - } -} \ No newline at end of file diff --git a/src/ios/OneSignalPush.h b/src/ios/OneSignalPush.h index dc173535..d48dfa46 100644 --- a/src/ios/OneSignalPush.h +++ b/src/ios/OneSignalPush.h @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2017 OneSignal + * Copyright 2021 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,58 +31,75 @@ #import -@interface OneSignalPush : CDVPlugin - -- (void)setNotificationReceivedHandler:(CDVInvokedUrlCommand*)command; -- (void)setNotificationOpenedHandler:(CDVInvokedUrlCommand*)command; -- (void)init:(CDVInvokedUrlCommand*)command; - -- (void)setInFocusDisplaying:(CDVInvokedUrlCommand*)command; -- (void)getPermissionSubscriptionState:(CDVInvokedUrlCommand*)command; - -- (void)addPermissionObserver:(CDVInvokedUrlCommand*)command; -- (void)addSubscriptionObserver:(CDVInvokedUrlCommand*)command; -- (void)addEmailSubscriptionObserver:(CDVInvokedUrlCommand *)command; - -- (void)getTags:(CDVInvokedUrlCommand*)command; -- (void)getIds:(CDVInvokedUrlCommand*)command; -- (void)sendTags:(CDVInvokedUrlCommand*)command; -- (void)deleteTags:(CDVInvokedUrlCommand*)command; -- (void)promptForPushNotificationsWithUserResponse:(CDVInvokedUrlCommand*)command; -- (void)registerForPushNotifications:(CDVInvokedUrlCommand*)command; -- (void)setSubscription:(CDVInvokedUrlCommand*)command; -- (void)postNotification:(CDVInvokedUrlCommand*)command; -- (void)setLogLevel:(CDVInvokedUrlCommand*)command; -- (void)promptLocation:(CDVInvokedUrlCommand*)command; -- (void)syncHashedEmail:(CDVInvokedUrlCommand*)command; -- (void)setLocationShared:(CDVInvokedUrlCommand *)command; - -//email -- (void)setEmail:(CDVInvokedUrlCommand *)command; -- (void)setUnauthenticatedEmail:(CDVInvokedUrlCommand *)command; -- (void)logoutEmail:(CDVInvokedUrlCommand *)command; - -// Android Only -- (void)enableVibrate:(CDVInvokedUrlCommand*)command; -- (void)enableSound:(CDVInvokedUrlCommand*)command; -- (void)clearOneSignalNotifications:(CDVInvokedUrlCommand*)command; - -- (void)userProvidedPrivacyConsent:(CDVInvokedUrlCommand *)command; -- (void)setRequiresUserPrivacyConsent:(CDVInvokedUrlCommand *)command; -- (void)provideUserConsent:(CDVInvokedUrlCommand *)command; - -- (void)setExternalUserId:(CDVInvokedUrlCommand *)command; -- (void)removeExternalUserId:(CDVInvokedUrlCommand *)command; +@interface OneSignalPush : CDVPlugin + +- (void)setProvidesNotificationSettingsView:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setNotificationWillShowInForegroundHandler:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setNotificationOpenedHandler:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)completeNotification:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)init:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)getDeviceState:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)addPermissionObserver:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)addSubscriptionObserver:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)addEmailSubscriptionObserver:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)addSMSSubscriptionObserver:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)setLogLevel:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)getTags:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)sendTags:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)deleteTags:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)promptForPushNotificationsWithUserResponse:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)registerForProvisionalAuthorization:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)disablePush:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)postNotification:(CDVInvokedUrlCommand* _Nonnull)command; + +// Start Android Only +- (void)clearOneSignalNotifications:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)unsubscribeWhenNotificationsAreDisabled:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)removeNotification:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)removeGroupedNotifications:(CDVInvokedUrlCommand* _Nonnull)command; +// End Android Only + +- (void)userProvidedPrivacyConsent:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)requiresUserPrivacyConsent:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setRequiresUserPrivacyConsent:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)provideUserConsent:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)setExternalUserId:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)removeExternalUserId:(CDVInvokedUrlCommand* _Nonnull)command; + +// Email +- (void)setEmail:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setUnauthenticatedEmail:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)logoutEmail:(CDVInvokedUrlCommand* _Nonnull)command; + +// SMS +- (void)setSMSNumber:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setUnauthenticatedSMSNumber:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)logoutSMSNumber:(CDVInvokedUrlCommand* _Nonnull)command; -// in app -- (void)setInAppMessageClickHandler:(CDVInvokedUrlCommand*)command; -- (void)addTriggers:(CDVInvokedUrlCommand*)command; -- (void)removeTriggersForKeys:(CDVInvokedUrlCommand*)command; -- (void)getTriggerValueForKey:(CDVInvokedUrlCommand*)command; -- (void)pauseInAppMessages:(CDVInvokedUrlCommand*)command; - -// outcomes -- (void)sendOutcome:(CDVInvokedUrlCommand*)command; -- (void)sendUniqueOutcome:(CDVInvokedUrlCommand*)command; -- (void)sendOutcomeWithValue:(CDVInvokedUrlCommand*)command; +// In App Message +- (void)setLaunchURLsInApp:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setInAppMessageClickHandler:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)addTriggers:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)removeTriggersForKeys:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)getTriggerValueForKey:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)pauseInAppMessages:(CDVInvokedUrlCommand* _Nonnull)command; + +// Outcomes +- (void)sendOutcome:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)sendUniqueOutcome:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)sendOutcomeWithValue:(CDVInvokedUrlCommand* _Nonnull)command; + +// Location +- (void)promptLocation:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)setLocationShared:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)isLocationShared:(CDVInvokedUrlCommand* _Nonnull)command; + +- (void)setLanguage:(CDVInvokedUrlCommand* _Nonnull)command; + @end diff --git a/src/ios/OneSignalPush.m b/src/ios/OneSignalPush.m index 4bffac46..d4b6532b 100644 --- a/src/ios/OneSignalPush.m +++ b/src/ios/OneSignalPush.m @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2017 OneSignal + * Copyright 2021 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,7 +31,7 @@ #import "OneSignalPush.h" #import -NSString* notificationReceivedCallbackId; +NSString* notificationWillShowInForegoundCallbackId; NSString* notificationOpenedCallbackId; NSString* getTagsCallbackId; NSString* getIdsCallbackId; @@ -39,11 +39,16 @@ NSString* permissionObserverCallbackId; NSString* subscriptionObserverCallbackId; NSString* promptForPushNotificationsWithUserResponseCallbackId; +NSString* registerForProvisionalAuthorizationCallbackId; NSString* setEmailCallbackId; NSString* setUnauthenticatedEmailCallbackId; +NSString* setSMSNumberCallbackId; +NSString* setUnauthenticatedSMSNumberCallbackId; NSString* setExternalIdCallbackId; NSString* logoutEmailCallbackId; +NSString* logoutSMSNumberCallbackId; NSString* emailSubscriptionCallbackId; +NSString* smsSubscriptionCallbackId; OSNotificationOpenedResult* actionNotification; OSNotification *notification; @@ -64,7 +69,7 @@ void failureCallback(NSString* callbackId, NSDictionary* data) { [pluginCommandDelegate sendPluginResult:commandResult callbackId:callbackId]; } -void processNotificationReceived(OSNotification* _notif) { +void processNotificationWillShowInForeground(OSNotification* _notif) { NSString * data = [_notif stringify]; NSError *jsonError; NSData *objectData = [data dataUsingEncoding:NSUTF8StringEncoding]; @@ -72,7 +77,7 @@ void processNotificationReceived(OSNotification* _notif) { options:NSJSONReadingMutableContainers error:&jsonError]; if(!jsonError) { - successCallback(notificationReceivedCallbackId, json); + successCallback(notificationWillShowInForegoundCallbackId, json); notification = nil; } } @@ -90,27 +95,11 @@ void processNotificationOpened(OSNotificationOpenedResult* result) { } } -void initOneSignalObject(NSDictionary* launchOptions, const char* appId, int displayOption, BOOL inAppLaunchURL, BOOL autoPrompt, BOOL fromColdStart) { - [OneSignal setValue:@"cordova" forKey:@"mSDKType"]; - - NSString* appIdStr = (appId ? [NSString stringWithUTF8String: appId] : nil); - NSDictionary *iOSSettings = initialLaunchFired ? @{kOSSettingsKeyAutoPrompt : @(autoPrompt), - kOSSettingsKeyInFocusDisplayOption : @(displayOption), - kOSSettingsKeyInAppLaunchURL : @(inAppLaunchURL), - @"kOSSettingsKeyInOmitNoAppIdLogging": @(fromColdStart)} : @{@"kOSSettingsKeyInOmitNoAppIdLogging": @(fromColdStart), - kOSSettingsKeyAutoPrompt : @false - }; - - [OneSignal initWithLaunchOptions:launchOptions appId:appIdStr handleNotificationReceived:^(OSNotification* _notif) { - notification = _notif; - if (pluginCommandDelegate) - processNotificationReceived(_notif); - } handleNotificationAction:^(OSNotificationOpenedResult* openResult) { - actionNotification = openResult; - if (pluginCommandDelegate) - processNotificationOpened(openResult); - } settings: iOSSettings]; - +void initOneSignalObject(NSDictionary* launchOptions, const char* appId) { + NSString* appIdStr = (appId ? [NSString stringWithUTF8String: appId] : nil); + [OneSignal setMSDKType:@"cordova"]; + [OneSignal setAppId:appIdStr]; + [OneSignal initWithLaunchOptions:launchOptions]; initialLaunchFired = true; } @@ -138,7 +127,7 @@ + (void)load { static Class delegateClass = nil; -- (void) setOneSignalCordovaDelegate:(id)delegate { +- (void)setOneSignalCordovaDelegate:(id)delegate { if(delegateClass != nil) return; delegateClass = [delegate class]; @@ -149,7 +138,7 @@ - (void) setOneSignalCordovaDelegate:(id)delegate { } - (BOOL)oneSignalApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - initOneSignalObject(launchOptions, nil, 1, YES, NO, YES); + initOneSignalObject(launchOptions, nil); if ([self respondsToSelector:@selector(oneSignalApplication:didFinishLaunchingWithOptions:)]) return [self oneSignalApplication:application didFinishLaunchingWithOptions:launchOptions]; @@ -158,6 +147,13 @@ - (BOOL)oneSignalApplication:(UIApplication*)application didFinishLaunchingWithO @end +@interface OneSignalPush () + +@property (strong, nonatomic) NSMutableDictionary* notificationCompletionCache; +@property (strong, nonatomic) NSMutableDictionary* receivedNotificationCache; + +@end + @implementation OneSignalPush - (void)onOSPermissionChanged:(OSPermissionStateChanges*)stateChanges { @@ -168,38 +164,113 @@ - (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges*)stateChanges { successCallback(subscriptionObserverCallbackId, [stateChanges toDictionary]); } --(void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges *)stateChanges { +- (void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges *)stateChanges { successCallback(emailSubscriptionCallbackId, [stateChanges toDictionary]); } -- (void)setNotificationReceivedHandler:(CDVInvokedUrlCommand*)command { - notificationReceivedCallbackId = command.callbackId; +- (void)onOSSMSSubscriptionChanged:(OSSMSSubscriptionStateChanges *)stateChanges { + successCallback(smsSubscriptionCallbackId, [stateChanges toDictionary]); +} + +- (void)setProvidesNotificationSettingsView:(CDVInvokedUrlCommand *)command { + BOOL providesView = command.arguments[0]; + [OneSignal setProvidesNotificationSettingsView:providesView]; +} + +- (void)setNotificationWillShowInForegroundHandler:(CDVInvokedUrlCommand*)command { + notificationWillShowInForegoundCallbackId = command.callbackId; + + [OneSignal setNotificationWillShowInForegroundHandler:^(OSNotification *notification, OSNotificationDisplayResponse completion) { + self.receivedNotificationCache[notification.notificationId] = notification; + self.notificationCompletionCache[notification.notificationId] = completion; + processNotificationWillShowInForeground(notification); + }]; } - (void)setNotificationOpenedHandler:(CDVInvokedUrlCommand*)command { notificationOpenedCallbackId = command.callbackId; + + [OneSignal setNotificationOpenedHandler:^(OSNotificationOpenedResult * _Nonnull result) { + actionNotification = result; + if (pluginCommandDelegate) + processNotificationOpened(actionNotification); + }]; } -- (void)init:(CDVInvokedUrlCommand*)command { +- (void)completeNotification:(CDVInvokedUrlCommand*)command { + NSString *notificationId = command.arguments[0]; + BOOL shouldDisplay = [command.arguments[1] boolValue]; + OSNotificationDisplayResponse completion = self.notificationCompletionCache[notificationId]; - pluginCommandDelegate = self.commandDelegate; + if (!completion) { + [OneSignal onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification completion block with id: %@", notificationId]]; + return; + } - NSString* appId = (NSString*)command.arguments[0]; - NSDictionary* settings = command.arguments[2] == [NSNull null] ? @{} : (NSDictionary*)command.arguments[2]; - - BOOL inAppLaunchURL = settings[@"kOSSettingsKeyInAppLaunchURL"] ? [(NSNumber*)settings[@"kOSSettingsKeyInAppLaunchURL"] boolValue] : YES; - BOOL autoPrompt = settings[@"kOSSettingsKeyAutoPrompt"] ? [(NSNumber*)settings[@"kOSSettingsKeyAutoPrompt"] boolValue] : YES; + if (shouldDisplay) { + OSNotification *notification = self.receivedNotificationCache[notificationId]; + completion(notification); + } else { + completion(nil); + } - int displayOption = [(NSNumber*)command.arguments[3] intValue]; + [self.notificationCompletionCache removeObjectForKey:notificationId]; + [self.receivedNotificationCache removeObjectForKey:notificationId]; +} - initOneSignalObject(nil, [appId UTF8String], displayOption, inAppLaunchURL, autoPrompt, NO); +- (void)init:(CDVInvokedUrlCommand*)command { + _receivedNotificationCache = [NSMutableDictionary new]; + _notificationCompletionCache = [NSMutableDictionary new];; + + pluginCommandDelegate = self.commandDelegate; + + NSString* appId = (NSString*)command.arguments[0]; + initOneSignalObject(nil, [appId UTF8String]); - if (notification) - processNotificationReceived(notification); if (actionNotification) processNotificationOpened(actionNotification); } +- (void)getDeviceState:(CDVInvokedUrlCommand*)command { + successCallback(command.callbackId, [[OneSignal getDeviceState] jsonRepresentation]); +} + +- (void)setLanguage:(CDVInvokedUrlCommand*)command { + [OneSignal setLanguage:command.arguments[0]]; +} + +- (void)addPermissionObserver:(CDVInvokedUrlCommand*)command { + bool first = permissionObserverCallbackId == nil; + permissionObserverCallbackId = command.callbackId; + if (first) + [OneSignal addPermissionObserver:self]; +} + +- (void)addSubscriptionObserver:(CDVInvokedUrlCommand*)command { + bool first = subscriptionObserverCallbackId == nil; + subscriptionObserverCallbackId = command.callbackId; + if (first) + [OneSignal addSubscriptionObserver:self]; +} + +- (void)addEmailSubscriptionObserver:(CDVInvokedUrlCommand *)command { + bool first = emailSubscriptionCallbackId == nil; + emailSubscriptionCallbackId = command.callbackId; + if (first) + [OneSignal addEmailSubscriptionObserver:self]; +} + +- (void)addSMSSubscriptionObserver:(CDVInvokedUrlCommand *)command { + bool first = smsSubscriptionCallbackId == nil; + smsSubscriptionCallbackId = command.callbackId; + if (first) + [OneSignal addSMSSubscriptionObserver:self]; +} + +- (void)setLogLevel:(CDVInvokedUrlCommand*)command { + [OneSignal setLogLevel:[command.arguments[0] intValue] visualLevel:[command.arguments[1] intValue]]; +} + - (void)getTags:(CDVInvokedUrlCommand*)command { getTagsCallbackId = command.callbackId; [OneSignal getTags:^(NSDictionary* result) { @@ -207,16 +278,6 @@ - (void)getTags:(CDVInvokedUrlCommand*)command { }]; } -- (void)getIds:(CDVInvokedUrlCommand*)command { - getIdsCallbackId = command.callbackId; - [OneSignal IdsAvailable:^(NSString* userId, NSString* pushToken) { - if (pushToken == nil) - pushToken = @""; - - successCallback(getIdsCallbackId, @{@"userId" : userId, @"pushToken" : pushToken}); - }]; -} - - (void)sendTags:(CDVInvokedUrlCommand*)command { [OneSignal sendTags:command.arguments[0]]; } @@ -225,14 +286,6 @@ - (void)deleteTags:(CDVInvokedUrlCommand*)command { [OneSignal deleteTags:command.arguments]; } -- (void)registerForPushNotifications:(CDVInvokedUrlCommand*)command { - [OneSignal registerForPushNotifications]; -} - -- (void)setLocationShared:(CDVInvokedUrlCommand *)command { - [OneSignal setLocationShared:[command.arguments[0] boolValue]]; -} - - (void)promptForPushNotificationsWithUserResponse:(CDVInvokedUrlCommand*)command { promptForPushNotificationsWithUserResponseCallbackId = command.callbackId; [OneSignal promptForPushNotificationsWithUserResponse:^(BOOL accepted) { @@ -240,8 +293,15 @@ - (void)promptForPushNotificationsWithUserResponse:(CDVInvokedUrlCommand*)comman }]; } -- (void)setSubscription:(CDVInvokedUrlCommand*)command { - [OneSignal setSubscription:[command.arguments[0] boolValue]]; +- (void)registerForProvisionalAuthorization:(CDVInvokedUrlCommand *)command { + registerForProvisionalAuthorizationCallbackId = command.callbackId; + [OneSignal registerForProvisionalAuthorization:^(BOOL accepted) { + successCallback(registerForProvisionalAuthorizationCallbackId, @{@"accepted": (accepted ? @"true" : @"false")}); + }]; +} + +- (void)disablePush:(CDVInvokedUrlCommand*)command { + [OneSignal disablePush:[command.arguments[0] boolValue]]; } - (void)postNotification:(CDVInvokedUrlCommand*)command { @@ -260,52 +320,38 @@ - (void)postNotification:(CDVInvokedUrlCommand*)command { }]; } -- (void)promptLocation:(CDVInvokedUrlCommand*)command { - [OneSignal promptLocation]; -} - -- (void)syncHashedEmail:(CDVInvokedUrlCommand*)command { - [OneSignal syncHashedEmail:command.arguments[0]]; -} - -- (void)setLogLevel:(CDVInvokedUrlCommand*)command { - NSDictionary* options = command.arguments[0]; - [OneSignal setLogLevel:[options[@"logLevel"] intValue] visualLevel:[options[@"visualLevel"] intValue]]; -} - -// Android only -- (void)enableVibrate:(CDVInvokedUrlCommand*)command {} -- (void)enableSound:(CDVInvokedUrlCommand*)command {} +// Start Android only - (void)clearOneSignalNotifications:(CDVInvokedUrlCommand*)command {} +- (void)unsubscribeWhenNotificationsAreDisabled:(CDVInvokedUrlCommand *)command {} -- (void)setInFocusDisplaying:(CDVInvokedUrlCommand*)command { - OneSignal.inFocusDisplayType = [(NSNumber*)command.arguments[0] intValue]; -} +- (void)removeNotification:(CDVInvokedUrlCommand *)command {} -- (void)getPermissionSubscriptionState:(CDVInvokedUrlCommand*)command { - successCallback(command.callbackId, [[OneSignal getPermissionSubscriptionState] toDictionary]); -} +- (void)removeGroupedNotifications:(CDVInvokedUrlCommand *)command {} +// Finish Android only -- (void)addPermissionObserver:(CDVInvokedUrlCommand*)command { - bool first = permissionObserverCallbackId == nil; - permissionObserverCallbackId = command.callbackId; - if (first) - [OneSignal addPermissionObserver:self]; +- (void)userProvidedPrivacyConsent:(CDVInvokedUrlCommand *)command { + CDVPluginResult* commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:!OneSignal.requiresUserPrivacyConsent]; + commandResult.keepCallback = @1; + [pluginCommandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; +} + +- (void)requiresUserPrivacyConsent:(CDVInvokedUrlCommand *)command { + BOOL requiresUserPrivacyConsent = [OneSignal requiresUserPrivacyConsent]; + NSDictionary *result = @{ + @"value" : @(requiresUserPrivacyConsent) + }; + successCallback(command.callbackId, result); } -- (void)addSubscriptionObserver:(CDVInvokedUrlCommand*)command { - bool first = subscriptionObserverCallbackId == nil; - subscriptionObserverCallbackId = command.callbackId; - if (first) - [OneSignal addSubscriptionObserver:self]; +- (void)setRequiresUserPrivacyConsent:(CDVInvokedUrlCommand *)command { + if (command.arguments.count >= 1) + [OneSignal setRequiresUserPrivacyConsent:[command.arguments[0] boolValue]]; } -- (void)addEmailSubscriptionObserver:(CDVInvokedUrlCommand *)command { - bool first = emailSubscriptionCallbackId == nil; - emailSubscriptionCallbackId = command.callbackId; - if (first) - [OneSignal addEmailSubscriptionObserver:self]; +- (void)provideUserConsent:(CDVInvokedUrlCommand *)command { + if (command.arguments.count >= 1) + [OneSignal consentGranted:[command.arguments[0] boolValue]]; } - (void)setEmail:(CDVInvokedUrlCommand *)command { @@ -343,20 +389,39 @@ - (void)logoutEmail:(CDVInvokedUrlCommand *)command { }]; } -- (void)userProvidedPrivacyConsent:(CDVInvokedUrlCommand *)command { - CDVPluginResult* commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:!OneSignal.requiresUserPrivacyConsent]; - commandResult.keepCallback = @1; - [pluginCommandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; +- (void)setSMSNumber:(CDVInvokedUrlCommand *)command { + setSMSNumberCallbackId = command.callbackId; + + NSString *smsNumber = command.arguments[0]; + NSString *smsAuthHashToken = command.arguments[1]; + + [OneSignal setSMSNumber:smsNumber withSMSAuthHashToken:smsAuthHashToken withSuccess:^(NSDictionary *results){ + successCallback(setSMSNumberCallbackId, results); + } withFailure:^(NSError *error) { + failureCallback(setSMSNumberCallbackId, error.userInfo); + }]; } + +- (void)setUnauthenticatedSMSNumber:(CDVInvokedUrlCommand *)command { + setUnauthenticatedSMSNumberCallbackId = command.callbackId; -- (void)setRequiresUserPrivacyConsent:(CDVInvokedUrlCommand *)command { - if (command.arguments.count >= 1) - [OneSignal setRequiresUserPrivacyConsent:[command.arguments[0] boolValue]]; + NSString *smsNumber = command.arguments[0]; + + [OneSignal setSMSNumber:smsNumber withSuccess:^(NSDictionary *results){ + successCallback(setUnauthenticatedSMSNumberCallbackId, results); + } withFailure:^(NSError *error) { + failureCallback(setUnauthenticatedSMSNumberCallbackId, error.userInfo); + }]; } -- (void)provideUserConsent:(CDVInvokedUrlCommand *)command { - if (command.arguments.count >= 1) - [OneSignal consentGranted:[command.arguments[0] boolValue]]; +- (void)logoutSMSNumber:(CDVInvokedUrlCommand *)command { + logoutSMSNumberCallbackId = command.callbackId; + + [OneSignal logoutSMSNumberWithSuccess:^(NSDictionary *results){ + successCallback(logoutSMSNumberCallbackId, results); + } withFailure:^(NSError *error) { + failureCallback(logoutSMSNumberCallbackId, error.userInfo); + }]; } - (void)setExternalUserId:(CDVInvokedUrlCommand *)command { @@ -371,7 +436,7 @@ - (void)setExternalUserId:(CDVInvokedUrlCommand *)command { [OneSignal setExternalUserId:externalId withExternalIdAuthHashToken:authHashToken withSuccess:^(NSDictionary *results) { successCallback(setExternalIdCallbackId, results); } withFailure: ^(NSError* error) { - [OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Set external user id Failure with error: %@", error]]; + [OneSignal onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Set external user id Failure with error: %@", error]]; failureCallback(setExternalIdCallbackId, error.userInfo); }]; } @@ -379,6 +444,9 @@ - (void)setExternalUserId:(CDVInvokedUrlCommand *)command { - (void)removeExternalUserId:(CDVInvokedUrlCommand *)command { [OneSignal removeExternalUserId:^(NSDictionary *results) { successCallback(command.callbackId, results); + } withFailure:^(NSError* error) { + [OneSignal onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Remove external user id Failure with error: %@", error]]; + failureCallback(command.callbackId, error.userInfo); }]; } @@ -386,6 +454,11 @@ - (void)removeExternalUserId:(CDVInvokedUrlCommand *)command { * In-App Messaging */ +- (void)setLaunchURLsInApp:(CDVInvokedUrlCommand *)command { + BOOL launchInApp = command.arguments[0]; + [OneSignal setLaunchURLsInApp:launchInApp]; +} + - (void)setInAppMessageClickHandler:(CDVInvokedUrlCommand*)command { [OneSignal setInAppMessageClickHandler:^(OSInAppMessageAction* action) { NSDictionary *result = @{ @@ -421,6 +494,10 @@ - (void)pauseInAppMessages:(CDVInvokedUrlCommand*)command { [OneSignal pauseInAppMessages:pause]; } +/** + * Outcomes + */ + - (void)sendOutcome:(CDVInvokedUrlCommand*)command { NSString *name = command.arguments[0]; @@ -446,4 +523,24 @@ - (void)sendOutcomeWithValue:(CDVInvokedUrlCommand*)command { }]; } +/** + * Location + */ + +- (void)promptLocation:(CDVInvokedUrlCommand*)command { + [OneSignal promptLocation]; +} + +- (void)setLocationShared:(CDVInvokedUrlCommand *)command { + [OneSignal setLocationShared:[command.arguments[0] boolValue]]; +} + +- (void)isLocationShared:(CDVInvokedUrlCommand *)command { + BOOL locationShared = [OneSignal isLocationShared]; + NSDictionary *result = @{ + @"value" : @(locationShared) + }; + successCallback(command.callbackId, result); +} + @end diff --git a/types/Extras.d.ts b/types/Extras.d.ts new file mode 100644 index 00000000..bf689082 --- /dev/null +++ b/types/Extras.d.ts @@ -0,0 +1,9 @@ + /* O P T I O N T Y P E V A L U E S */ +// 0 = None, 1 = Fatal, 2 = Errors, 3 = Warnings, 4 = Info, 5 = Debug, 6 = Verbose +export type LogLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6; + +/* O B S E R V E R C H A N G E E V E N T S */ +export interface ChangeEvent { + from : T; + to : T; +} diff --git a/types/InAppMessage.d.ts b/types/InAppMessage.d.ts new file mode 100644 index 00000000..29877d2e --- /dev/null +++ b/types/InAppMessage.d.ts @@ -0,0 +1,6 @@ +export interface InAppMessageAction { + closes_message : boolean; + first_click : boolean; + click_name ?: string; + click_url ?: string; +} diff --git a/types/Notification.d.ts b/types/Notification.d.ts new file mode 100644 index 00000000..6d1a5799 --- /dev/null +++ b/types/Notification.d.ts @@ -0,0 +1,53 @@ +// 0 = NotificationClicked, 1 = ButtonClicked +export type OpenedEventActionType = 0 | 1; + + /* N O T I F I C A T I O N S */ +export interface OSNotification { + body : string; + sound ?: string; + title ?: string; + launchURL ?: string; + rawPayload : object; + actionButtons ?: object[]; + additionalData : object; + notificationId : string; + // android only + groupKey ?: string; + groupMessage ?: string; + ledColor ?: string; + priority ?: number; + smallIcon ?: string; + largeIcon ?: string; + bigPicture ?: string; + collapseId ?: string; + fromProjectNumber ?: string; + smallIconAccentColor ?: string; + lockScreenVisibility ?: string; + androidNotificationId ?: number; + // ios only + badge ?: string; + badgeIncrement ?: string; + category ?: string; + threadId ?: string; + subtitle ?: string; + templateId ?: string; + templateName ?: string; + attachments ?: object; + mutableContent ?: boolean; + contentAvailable ?: string; +} + +/* N O T I F I C A T I O N & I A M E V E N T S */ +export interface NotificationReceivedEvent { + complete : (notification?: OSNotification) => void; + getNotification : () => OSNotification; +} + +export interface OpenedEvent { + action : OpenedEventAction; + notification : OSNotification; +} + +export interface OpenedEventAction { + type : OpenedEventActionType +} diff --git a/types/OneSignalPlugin.d.ts b/types/OneSignalPlugin.d.ts new file mode 100644 index 00000000..e5015785 --- /dev/null +++ b/types/OneSignalPlugin.d.ts @@ -0,0 +1,340 @@ +import { NotificationReceivedEvent, OpenedEvent, OpenedEventAction } from './Notification'; +import { OutcomeEvent } from './Outcomes'; +import { InAppMessageAction } from './InAppMessage'; +import { PermissionChange, SubscriptionChange, EmailSubscriptionChange, SMSSubscriptionChange, DeviceState } from './Subscription'; +import { LogLevel, ChangeEvent } from './Extras'; + +/* O N E S I G N A L I N T E R F A C E */ +export interface OneSignalPlugin { + /** + * Completes OneSignal initialization by setting the OneSignal Application ID. + * @param {string} appId + * @returns void + */ + setAppId(appId: string): void; + + /** + * Add a callback that fires when the native push permission changes. + * @param {(event:ChangeEvent)=>void} observer + * @returns void + */ + addPermissionObserver(observer: (event: ChangeEvent) => void): void; + + /** + * Add a callback that fires when the OneSignal subscription state changes. + * @param {(event:ChangeEvent)=>void} observer + * @returns void + */ + addSubscriptionObserver(observer: (event: ChangeEvent) => void): void; + + /** + * Add a callback that fires when the OneSignal email subscription changes. + * @param {(event:ChangeEvent)=>void} observer + * @returns void + */ + addEmailSubscriptionObserver(observer: (event: ChangeEvent) => void): void; + + /** + * Add a callback that fires when the OneSignal sms subscription changes. + * @param {(event:ChangeEvent)=>void} observer + * @returns void + */ + addSMSSubscriptionObserver(observer: (event: ChangeEvent) => void): void; + + /** + * Set the callback to run just before displaying a notification while the app is in focus. + * @param {(event:NotificationReceivedEvent)=>void} handler + * @returns void + */ + setNotificationWillShowInForegroundHandler(handler: (event: NotificationReceivedEvent) => void): void; + + /** + * Set the callback to run on notification open. + * @param {(openedEvent:OpenedEvent)=>void} handler + * @returns void + */ + setNotificationOpenedHandler(handler: (openedEvent: OpenedEvent) => void): void; + + /** + * Prompts the iOS user for push notifications. + * @param {(response:boolean)=>void} handler + * @returns void + */ + promptForPushNotificationsWithUserResponse(handler?: (response: boolean) => void): void; + + /** + * Only applies to iOS (does nothing on Android as it always silently registers) + * Request for Direct-To-History push notification authorization + * + * For more information: https://documentation.onesignal.com/docs/ios-customizations#provisional-push-notifications + * + * @param {(response:boolean)=>void} handler + * @returns void + */ + registerForProvisionalAuthorization(handler?: (response: boolean) => void): void; + + /** + * Disable the push notification subscription to OneSignal. + * @param {boolean} disable + * @returns void + */ + disablePush(disable: boolean): void; + + /** + * Android Only. If notifications are disabled for your application, unsubscribe the user from OneSignal. + * @param {boolean} unsubscribe + * @returns void + */ + unsubscribeWhenNotificationsAreDisabled(unsubscribe: boolean): void; + + /** + * True if the application has location share activated, false otherwise + * @returns Promise + */ + isLocationShared(): Promise; + + /** + * Disable or enable location collection (defaults to enabled if your app has location permission). + * @param {boolean} shared + * @returns void + */ + setLocationShared(shared: boolean): void; + + /** + * Prompts the user for location permissions to allow geotagging from the OneSignal dashboard. + * @returns void + */ + promptLocation(): void; + + /** + * This method returns a "snapshot" of the device state for when it was called. + * @returns Promise + */ + getDeviceState(): Promise; + + /** + * Allows you to set the app defined language with the OneSignal SDK. + * @param {string} language + * @returns void + */ + setLanguage(language: string): void; + + /** + * Tag a user based on an app event of your choosing so they can be targeted later via segments. + * @param {string} key + * @param {string} value + * @returns void + */ + sendTag(key: string, value: string): void; + + /** + * Tag a user wiht multiple tags based on an app event of your choosing so they can be targeted later via segments. + * @param {object} tags + * @returns void + */ + sendTags(tags: object): void; + + /** + * Retrieve a list of tags that have been set on the user from the OneSignal server. + * @param {(tags:object)=>void} handler + * @returns void + */ + getTags(handler: (tags: object) => void): void; + + /** + * Deletes a single tag that was previously set on a user. + * @param {string} key + * @returns void + */ + deleteTag(key: string): void; + + /** + * Deletes multiple tags that were previously set on a user. + * @param {string[]} keys + */ + deleteTags(keys: string[]); + + /** + * Allows you to set the user's email address with the OneSignal SDK. + * @param {string} email + * @param {string} authCode + * @param {Function} handler + * @returns void + */ + setEmail(email: string, authCode?: string, handler?: Function): void; + + /** + * If your app implements logout functionality, you can call logoutEmail to dissociate the email from the device. + * @param {Function} handler + */ + logoutEmail(handler?: Function); + + /** + * Allows you to set the user's SMS number with the OneSignal SDK. + * @param {string} smsNumber + * @param {string} authCode + * @param {Function} handler + * @returns void + */ + setSMSNumber(smsNumber: string, authCode?: string, handler?: Function): void; + + /** + * If your app implements logout functionality, you can call logoutSMSNumber to dissociate the SMS number from the device. + * @param {Function} handler + */ + logoutSMSNumber(handler?: Function); + + /** + * Send a notification + * @param {string} notificationObjectString - JSON string payload (see REST API reference) + * @param {(success:object)=>void} onSuccess + * @param {(failure:object)=>void} onFailure + * @returns void + */ + postNotification(notificationObjectString: string, onSuccess?: (success: object) => void, onFailure?: (failure: object) => void): void; + + /** + * Android Only. iOS provides a standard way to clear notifications by clearing badge count. + * @returns void + */ + clearOneSignalNotifications(): void; + + /** + * Removes a single OneSignal notification based on its Android notification integer id. + * @param {number} id - notification id to cancel + * @returns void + */ + removeNotification(id: number): void; + + /** + * Removes all OneSignal notifications based on its Android notification group Id. + * @param {string} id - notification group id to cancel + * @returns void + */ + removeGroupedNotifications(id: string): void; + + /** + * Allows you to use your own system's user ID's to send push notifications to your users. + * @param {string} externalId + * @param {(results:object)=>void} handler + * @returns void + */ + setExternalUserId(externalId: string, handlerOrAuth?: ((results: object) => void) | string, handler?: (results: object) => void): void; + + /** + * Removes whatever was set as the current user's external user ID. + * @param {(results:object)=>void} handler + * @returns void + */ + removeExternalUserId(handler?: (results: object) => void): void; + + /** + * Sets an In-App Message click event handler. + * @param {(action:InAppMessageAction)=>void} handler + * @returns void + */ + setInAppMessageClickHandler(handler: (action: InAppMessageAction) => void): void; + + /** + * Add an In-App Message Trigger. + * @param {string} key + * @param {string} value + * @returns void + */ + addTrigger(key: string, value: string): void; + + /** + * Adds Multiple In-App Message Triggers. + * @param {object} triggers + * @returns void + */ + addTriggers(triggers: object): void; + + /** + * Removes a list of triggers based on a collection of keys. + * @param {string[]} keys + * @returns void + */ + removeTriggersForKeys(keys: string[]): void; + + /** + * Removes a list of triggers based on a key. + * @param {string} key + * @returns void + */ + removeTriggerForKey(key: string): void; + + /** + * Gets a trigger value for a provided trigger key. + * @param {string} key + * @returns void + */ + getTriggerValueForKey(key: string): Promise; + + /** + * Pause & unpause In-App Messages + * @param {boolean} pause + * @returns void + */ + pauseInAppMessages(pause: boolean): void; + + /** + * Increases the "Count" of this Outcome by 1 and will be counted each time sent. + * @param {string} name + * @param {(event:OutcomeEvent)=>void} handler + * @returns void + */ + sendOutcome(name: string, handler?: (event: OutcomeEvent) => void): void; + + /** + * Increases "Count" by 1 only once. This can only be attributed to a single notification. + * @param {string} name + * @param {(event:OutcomeEvent)=>void} handler + * @returns void + */ + sendUniqueOutcome(name: string, handler?: (event: OutcomeEvent) => void): void; + + /** + * Increases the "Count" of this Outcome by 1 and the "Sum" by the value. Will be counted each time sent. + * If the method is called outside of an attribution window, it will be unattributed until a new session occurs. + * @param {string} name + * @param {string|number} value + * @param {(event:OutcomeEvent)=>void} handler + * @returns void + */ + sendOutcomeWithValue(name: string, value: string|number, handler?: (event: OutcomeEvent) => void): void; + + /** + * Enable logging to help debug if you run into an issue setting up OneSignal. + * @param {LogLevel} nsLogLevel - Sets the logging level to print to the Android LogCat log or Xcode log. + * @param {LogLevel} visualLogLevel - Sets the logging level to show as alert dialogs. + * @returns void + */ + setLogLevel(nsLogLevel: LogLevel, visualLogLevel: LogLevel): void; + + /** + * Did the user provide privacy consent for GDPR purposes. + * @returns Promise + */ + userProvidedPrivacyConsent(): Promise; + + /** + * True if the application requires user privacy consent, false otherwise + * @returns Promise + */ + requiresUserPrivacyConsent(): Promise; + + /** + * For GDPR users, your application should call this method before setting the App ID. + * @param {boolean} required + * @returns void + */ + setRequiresUserPrivacyConsent(required: boolean): void; + + /** + * If your application is set to require the user's privacy consent, you can provide this consent using this method. + * @param {boolean} granted + * @returns void + */ + provideUserConsent(granted: boolean): void; +} diff --git a/types/Outcomes.d.ts b/types/Outcomes.d.ts new file mode 100644 index 00000000..b52215c3 --- /dev/null +++ b/types/Outcomes.d.ts @@ -0,0 +1,7 @@ +export interface OutcomeEvent { + session : string; + id : string; + timestamp : number; + weight : number; + notification_ids: string[]; +} diff --git a/types/Subscription.d.ts b/types/Subscription.d.ts new file mode 100644 index 00000000..e432c020 --- /dev/null +++ b/types/Subscription.d.ts @@ -0,0 +1,43 @@ +// 0 = NotDetermined, 1 = Denied, 2 = Authorized, 3 = Provisional, 4 = Ephemeral +export type PermissionStatus = 0 | 1 | 2 | 3 | 4; + +/* D E V I C E */ +export interface DeviceState { + userId : string; + pushToken : string; + emailUserId : string; + emailAddress : string; + smsUserId : string; + smsNumber : string; + isSubscribed : boolean; + isPushDisabled : boolean; + isEmailSubscribed : boolean; + isSMSSubscribed : boolean; + hasNotificationPermission : boolean; + notificationPermissionStatus ?: PermissionStatus; // ios only + // areNotificationsEnabled (android) not included since it is converted to hasNotificationPermission in bridge +} + +export interface PermissionChange { + status : PermissionStatus; + hasPrompted ?: boolean; // ios + provisional ?: boolean; // ios +} + +export interface SubscriptionChange { + userId ?: string; + pushToken ?: string; + isSubscribed : boolean; +} + +export interface EmailSubscriptionChange { + emailAddress ?: string; + emailUserId ?: string; + isEmailSubscribed : boolean; +} + +export interface SMSSubscriptionChange { + smsNumber ?: string; + smsUserId ?: string; + isSMSSubscribed : boolean; +} diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 00000000..72402e35 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,4 @@ +import { OneSignalPlugin } from './OneSignalPlugin'; +export declare const OneSignal: OneSignalPlugin; +export { OneSignalPlugin }; +export default OneSignal; diff --git a/www/InAppMessage.js b/www/InAppMessage.js new file mode 100644 index 00000000..63664367 --- /dev/null +++ b/www/InAppMessage.js @@ -0,0 +1,8 @@ +function OSInAppMessageAction (json) { + this.clickName = json.click_name; + this.clickUrl = json.click_url; + this.firstClick = json.first_click; + this.closesMessage = json.closes_message; +} + +module.exports = OSInAppMessageAction; \ No newline at end of file diff --git a/www/NotificationOpened.js b/www/NotificationOpened.js new file mode 100644 index 00000000..c341042f --- /dev/null +++ b/www/NotificationOpened.js @@ -0,0 +1,28 @@ +var OSNotification = require('./NotificationReceived').OSNotification; + +/// An instance of this class represents a user interaction with +/// your push notification, ie. if they tap a button +function OSNotificationOpenedResult (json) { + this.notification = new OSNotification(json.notification); + + if (json.action) { + this.action = new OSNotificationAction(json.action); + } +} + +/// Represents an action taken on a push notification, such as +/// tapping the notification (or a button on the notification), +/// or if your `inFocusDisplayType` is set to true - if they +/// tapped 'close'. +function OSNotificationAction (json) { + /// The ID of the button on your notification + /// that the user tapped + this.actionId = json.actionId; + + /// An int that represents whether the user `opened` or + /// took a more specific `action` (such as tapping a button + /// on the notification) + this.type = json.type; +} + +module.exports = OSNotificationOpenedResult; diff --git a/www/NotificationReceived.js b/www/NotificationReceived.js new file mode 100644 index 00000000..ea5910fc --- /dev/null +++ b/www/NotificationReceived.js @@ -0,0 +1,268 @@ +function OSNotification (receivedEvent) { + /// The OneSignal notification ID for this notification + this.notificationId = receivedEvent.notificationId; + /// The body (should contain most of the text) + this.body = receivedEvent.body; + /// The title for the notification + this.title = receivedEvent.title; + /// Any additional custom data you want to send along + /// with this notification. + this.additionalData = receivedEvent.additionalData; + /// A hashmap object representing the raw key/value + /// properties of the push notification + if (typeof receivedEvent.rawPayload === 'string' || receivedEvent.rawPayload instanceof String) { + this.rawPayload = JSON.parse(receivedEvent.rawPayload); + } else { + this.rawPayload = receivedEvent.rawPayload; + } + /// If set, he launch URL will be opened when the user + /// taps on your push notification. You can control + /// whether or not it opens in an in-app webview or + /// in Safari (with iOS). + this.launchURL = receivedEvent.launchURL; + /// The sound file (ie. ping.aiff) that should be played + /// when the notification is received + this.sound = receivedEvent.sound; + + /// Any buttons you want to add to the notification. + /// The notificationOpened handler will provide an + /// OSNotificationAction object, which will contain + /// the ID of the Action the user tapped. + if (receivedEvent.actionButtons) { + this.actionButtons = []; + for (let btn of receivedEvent.actionButtons) { + this.actionButtons.push(new OSActionButton(btn)); + } + } + + // Android + + /// (Android only) + /// All notifications with the same group key + /// from the same app will be grouped together + if (receivedEvent.groupKey) { + this.groupKey = receivedEvent.groupKey; + } + /// (Android Only) + /// The color to use to light up the LED (if + /// applicable) when the notification is received + /// Given in hex ARGB format. + if (receivedEvent.ledColor) { + this.ledColor = receivedEvent.ledColor; + } + /// (Android Only) + /// The priority used with GCM/FCM to describe how + /// urgent the notification is. A higher priority + /// means the notification will be delivered faster. + if (typeof(receivedEvent.priority) !== "undefined") { + this.priority = receivedEvent.priority; + } + /// (Android Only) + /// The filename of the image to use as the small + /// icon for the notification + if (receivedEvent.smallIcon) { + this.smallIcon = receivedEvent.smallIcon; + } + /// (Android Only) + /// The filename for the image to use as the large + /// icon for the notification + if (receivedEvent.largeIcon) { + this.largeIcon = receivedEvent.largeIcon; + } + /// (Android Only) + /// The URL or filename for the image to use as + /// the big picture for the notification + if (receivedEvent.bigPicture) { + this.bigPicture = receivedEvent.bigPicture; + } + /// (Android Only) + /// The collapse ID for the notification + /// As opposed to groupKey (which causes stacking), + /// the collapse ID will completely replace any + /// previously received push notifications that + /// use the same collapse_id + if (receivedEvent.collapseId) { + this.collapseId = receivedEvent.collapseId; + } + /// (Android only) Android 6 and earlier only + /// The message to display when multiple + /// notifications have been stacked together. + /// Note: Android 7 allows groups (stacks) + /// to be expanded, so group message is no + /// longer necessary + if (receivedEvent.groupMessage) { + this.groupMessage = receivedEvent.groupMessage; + } + /// (Android Only) + /// Tells you what project number/sender ID + /// the notification was sent from + if (receivedEvent.fromProjectNumber) { + this.fromProjectNumber = receivedEvent.fromProjectNumber; + } + /// (Android Only) + /// The accent color to use on the notification + /// Hex value in ARGB format (it's a normal + /// hex color value, but it includes the alpha + /// channel in addition to red, green, blue) + if (receivedEvent.smallIconAccentColor) { + this.smallIconAccentColor = receivedEvent.smallIconAccentColor; + } + /// (Android only) API level 21+ + /// Sets the visibility of the notification + /// 1 = Public (default) + /// 0 = Private (hidden from lock screen + /// if user set 'Hide Sensitive content') + /// -1 = Secret (doesn't appear at all) + if (receivedEvent.lockScreenVisibililty) { + this.lockScreenVisibility = receivedEvent.lockScreenVisibililty; + } + /// (Android Only) + /// The android notification ID (not same as the OneSignal + /// notification ID) + if (receivedEvent.androidNotificationId) { + this.androidNotificationId = receivedEvent.androidNotificationId; + } + /// (Android Only) + /// Describes the background image layout of the + /// notification (if set) + if (receivedEvent.backgroundImageLayout) { + this.backgroundImageLayout = new OSAndroidBackgroundImageLayout(receivedEvent.backgroundImageLayout); + } + /// (Android Only) + /// Summary notifications grouped + /// Notification payload will have the most recent notification received. + if (receivedEvent.groupedNotifications && receivedEvent.groupedNotifications.length) { + this.groupedNotifications = receivedEvent.groupedNotificationss.map(function(num) { + return new OSNotification(item); + }); + } + + // iOS + + /// (iOS Only) + /// If you set the badge to a specific value, this integer + /// property will be that value + if (receivedEvent.badge) { + this.badge = receivedEvent.badge; + } + /// (iOS Only) + /// The category for this notification. This can trigger custom + /// behavior (ie. if this notification should display a + /// custom Content Extension for custom UI) + if (receivedEvent.category) { + this.category = receivedEvent.category; + } + /// (iOS Only) + /// The subtitle of the notification + if (receivedEvent.subtitle) { + this.subtitle = receivedEvent.subtitle; + } + /// If this notification was created from a Template on the + /// OneSignal dashboard, this will be the ID of that template + if (receivedEvent.templateId) { + this.templateId = receivedEvent.templateId; + } + /// (iOS Only) + /// Any attachments (images, sounds, videos) you want + /// to display with this notification. + if (receivedEvent.attachments) { + this.attachments = receivedEvent.attachments; + } + /// The name of the template (if any) that was used to + /// create this push notification + if (receivedEvent.templateName) { + this.templateName = receivedEvent.templateName; + } + /// (iOS Only) + /// Tells the system to launch the Notification Extension Service + if (receivedEvent.mutableContent) { + this.mutableContent = receivedEvent.mutableContent; + } + /// (iOS Only) + /// If you want to increment the badge by some value, this + /// integer will be the increment/decrement + if (receivedEvent.badgeIncrement) { + this.badgeIncrement = receivedEvent.badgeIncrement; + } + /// (iOS Only) + /// Tells the system to launch your app in the background (ie. if + /// content is available to download in the background) + if (receivedEvent.contentAvailable) { + this.contentAvailable = receivedEvent.contentAvailable; + } +} + +/// Represents a button sent as part of a push notification +class OSActionButton { + constructor(json) { + /// The custom unique ID for this button + this.id = json.id; + /// The text to display for the button + this.text = json.text; + + /// (Android only) + /// The URL/filename to show as the + /// button's icon + if (json.icon) { + this.icon = json.icon; + } + } +} + +/// (Android Only) +/// This class represents the background image layout +/// used for push notifications that show a background image +class OSAndroidBackgroundImageLayout { + constructor(json) { + /// (Android Only) + /// The image URL/filename to show as the background image + if (json.image) { + this.image = json.image; + } + /// (Android Only) + /// The color of the title text + if (json.titleTextColor) { + this.titleTextColor = json.titleTextColor; + } + /// (Android Only) + /// The color of the body text + if (json.bodyTextColor) { + this.bodyTextColor = json.bodyTextColor; + } + } +} + +var OSNotificationReceivedEvent = { + notification: null, + create : function (receivedEvent) { + if (receivedEvent.notification) { + // Android case + this.notification = new OSNotification(receivedEvent.notification); + } else { + // iOS case + this.notification = new OSNotification(receivedEvent); + } + return this; + }, + complete : function (notification) { + if (!notification) { + // if the notificationReceivedEvent is null, we want to call the native-side + // complete/completion with null to silence the notification + cordova.exec(function(){}, function(){}, "OneSignalPush", "completeNotification", [this.notification.notificationId, false]); + return; + } + + // if the notificationReceivedEvent is not null, we want to pass the specific event + // future: Android side: make the notification modifiable + // iOS & Android: the notification id is associated with the native-side complete handler / completion block + cordova.exec(function(){}, function(){}, "OneSignalPush", "completeNotification", [this.notification.notificationId, true]); + }, + getNotification: function() { + return this.notification; + } +}; + +module.exports = { + OSNotification: OSNotification, + OSNotificationReceivedEvent: OSNotificationReceivedEvent +}; diff --git a/www/OneSignal.js b/www/OneSignal.js deleted file mode 100644 index b2b90e4e..00000000 --- a/www/OneSignal.js +++ /dev/null @@ -1,433 +0,0 @@ -/** - * Modified MIT License - * - * Copyright 2019 OneSignal - * - * 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: - * - * 1. The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * 2. All copies of substantial portions of the Software may only be used in connection - * with services provided by OneSignal. - * - * 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. - */ - -var OneSignal = function() { - var _appID = ""; - var _googleProjectNumber = ""; - var _iOSSettings = {}; - var _notificationReceivedDelegate = function() {}; - var _notificationOpenedDelegate = function() {}; - var _inAppMessageClickDelegate = function () {}; -}; - -OneSignal.prototype.OSInFocusDisplayOption = { - None: 0, - InAppAlert : 1, - Notification : 2 -}; - -OneSignal.prototype.OSNotificationPermission = { - NotDetermined: 0, - Authorized: 1, - Denied: 2 -}; - -OneSignal._displayOption = OneSignal.prototype.OSInFocusDisplayOption.InAppAlert; - -OneSignal._permissionObserverList = []; -OneSignal._subscriptionObserverList = []; -OneSignal._emailSubscriptionObserverList = []; - - -// You must call init before any other OneSignal function. -// Android - googleProjectNumber: Deprecated; pulled from dashboard, local value is ignored -OneSignal.prototype.startInit = function(appId, googleProjectNumber) { - OneSignal._appID = appId; - OneSignal._googleProjectNumber = googleProjectNumber; - return this; -}; - -OneSignal.prototype.handleNotificationReceived = function(handleNotificationReceivedCallback) { - OneSignal._notificationReceivedDelegate = handleNotificationReceivedCallback; - return this; -}; - -OneSignal.prototype.handleNotificationOpened = function(handleNotificationOpenedCallback) { - OneSignal._notificationOpenedDelegate = handleNotificationOpenedCallback; - return this; -}; - -OneSignal.prototype.handleInAppMessageClicked = function(handler) { - OneSignal._inAppMessageClickDelegate = handler; - return this; -}; - -OneSignal.prototype.inFocusDisplaying = function(display) { - OneSignal._displayOption = display; - return this; -}; - -//Possible settings keys: -// kOSSettingsKeyInAppLaunchURL: Bool. Enable in-app webviews for urls. Default: Enabled -// kOSSettingsKeyAutoPrompt: Bool. Enable automatic prompting for notifications. Default: Enabled -OneSignal.prototype.iOSSettings = function(settings) { - OneSignal._iOSSettings = settings; - return this; -}; - -OneSignal.prototype.endInit = function() { - - //Pass notification received handler - cordova.exec(OneSignal._notificationReceivedDelegate, function(){}, "OneSignalPush", "setNotificationReceivedHandler", []); - cordova.exec(OneSignal._notificationOpenedDelegate, function(){}, "OneSignalPush", "setNotificationOpenedHandler", []); - cordova.exec(OneSignal._inAppMessageClickDelegate, function() {}, "OneSignalPush", "setInAppMessageClickHandler", []); - //Call Init - cordova.exec(function() {}, function(){}, "OneSignalPush", "init", [OneSignal._appID, OneSignal._googleProjectNumber, OneSignal._iOSSettings, OneSignal._displayOption]); -}; - -OneSignal._processFunctionList = function(array, param) { - for (var i = 0; i < array.length; i++) - array[i](param); -}; - -OneSignal._formatPermissionObj = function(state) { - // If Android format, match it to the iOS format - if ("undefined" !== typeof state.enabled) { - state.hasPrompted = true; - state.state = state.enabled ? OneSignal.prototype.OSNotificationPermission.Authorized : OneSignal.prototype.OSNotificationPermission.Denied; - delete state.enabled - } -}; - -OneSignal.prototype.addPermissionObserver = function(callback) { - OneSignal._permissionObserverList.push(callback); - var permissionCallBackProcessor = function(state) { - OneSignal._formatPermissionObj(state.to); - OneSignal._formatPermissionObj(state.from); - OneSignal._processFunctionList(OneSignal._permissionObserverList, state); - }; - cordova.exec(permissionCallBackProcessor, function(){}, "OneSignalPush", "addPermissionObserver", []); -}; - -OneSignal.prototype.addSubscriptionObserver = function(callback) { - OneSignal._subscriptionObserverList.push(callback); - var subscriptionCallBackProcessor = function(state) { - OneSignal._processFunctionList(OneSignal._subscriptionObserverList, state); - }; - cordova.exec(subscriptionCallBackProcessor, function(){}, "OneSignalPush", "addSubscriptionObserver", []); -}; - -OneSignal.prototype.addEmailSubscriptionObserver = function(callback) { - OneSignal._emailSubscriptionObserverList.push(callback); - var emailSubscriptionCallbackProcessor = function(state) { - OneSignal._processFunctionList(OneSignal._emailSubscriptionObserverList, state); - }; - cordova.exec(emailSubscriptionCallbackProcessor, function(){}, "OneSignalPush", "addEmailSubscriptionObserver", []); -}; - -OneSignal.prototype.setInFocusDisplaying = function(displayType) { - OneSignal._displayOption = displayType; - cordova.exec(function(){}, function(){}, "OneSignalPush", "setInFocusDisplaying", [displayType]); -}; - -OneSignal.prototype.getPermissionSubscriptionState = function(callback) { - var internalCallBackProcessor = function(state) { - OneSignal._formatPermissionObj(state.permissionStatus); - callback(state); - }; - cordova.exec(internalCallBackProcessor, function(){}, "OneSignalPush", "getPermissionSubscriptionState", []); -}; - -OneSignal.prototype.getIds = function(IdsReceivedCallBack) { - cordova.exec(IdsReceivedCallBack, function(){}, "OneSignalPush", "getIds", []); -}; - -OneSignal.prototype.getTags = function(tagsReceivedCallBack) { - cordova.exec(tagsReceivedCallBack, function(){}, "OneSignalPush", "getTags", []); -}; - -OneSignal.prototype.sendTag = function(key, value) { - jsonKeyValue = {}; - jsonKeyValue[key] = value; - cordova.exec(function(){}, function(){}, "OneSignalPush", "sendTags", [jsonKeyValue]); -}; - -OneSignal.prototype.sendTags = function(tags) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "sendTags", [tags]); -}; - -OneSignal.prototype.deleteTag = function(key) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "deleteTags", [key]); -}; - -OneSignal.prototype.deleteTags = function(keys) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "deleteTags", keys); -}; - -// Only applies to iOS(does nothing on Android as it always silently registers) -// Call only if you passed false to autoRegister -OneSignal.prototype.registerForPushNotifications = function() { - cordova.exec(function(){}, function(){}, "OneSignalPush", "registerForPushNotifications", []); -}; - -OneSignal.prototype.promptForPushNotificationsWithUserResponse = function(callback) { - var internalCallback = function(data) { - callback(data.accepted === "true"); - }; - cordova.exec(internalCallback, function(){}, "OneSignalPush", "promptForPushNotificationsWithUserResponse", []); -}; - -OneSignal.prototype.clearOneSignalNotifications = function() { - cordova.exec(function(){}, function(){}, "OneSignalPush", "clearOneSignalNotifications", []); -}; - -// Only applies to Android, vibrate is on by default but can be disabled by passing in false. -OneSignal.prototype.enableVibrate = function(enable) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "enableVibrate", [enable]); -}; - -// Only applies to Android, sound is on by default but can be disabled by passing in false. -OneSignal.prototype.enableSound = function(enable) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "enableSound", [enable]); -}; - -OneSignal.prototype.enableNotificationsWhenActive = function(enable) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "enableNotificationsWhenActive", [enable]); -}; - -OneSignal.prototype.setSubscription = function(enable) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "setSubscription", [enable]); -}; - -OneSignal.prototype.postNotification = function(jsonData, onSuccess, onFailure) { - if (onSuccess == null) - onSuccess = function() {}; - - if (onFailure == null) - onFailure = function() {}; - - cordova.exec(onSuccess, onFailure, "OneSignalPush", "postNotification", [jsonData]); -}; - -OneSignal.prototype.promptLocation = function() { - cordova.exec(function(){}, function(){}, "OneSignalPush", "promptLocation", []); -}; - -OneSignal.prototype.syncHashedEmail = function(email) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "syncHashedEmail", [email]); -}; - -OneSignal.prototype.setLogLevel = function(logLevel) { - cordova.exec(function(){}, function(){}, "OneSignalPush", "setLogLevel", [logLevel]); -}; - -OneSignal.prototype.setLocationShared = function(shared) { - cordova.exec(function() {}, function() {}, "OneSignalPush", "setLocationShared", [shared]); -}; - -//email - -OneSignal.prototype.setEmail = function(email, emailAuthToken, onSuccess, onFailure) { - if (onSuccess == null) - onSuccess = function() {}; - - if (onFailure == null) - onFailure = function() {}; - - if (typeof emailAuthToken == 'function') { - onFailure = onSuccess; - onSuccess = emailAuthToken; - - cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedEmail", [email]); - } else if (emailAuthToken == undefined) { - cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedEmail", [email]); - } else { - cordova.exec(onSuccess, onFailure, "OneSignalPush", "setEmail", [email, emailAuthToken]); - } -}; - -OneSignal.prototype.logoutEmail = function(onSuccess, onFailure) { - if (onSuccess == null) - onSuccess = function() {}; - - - if (onFailure == null) - onFailure = function() {}; - - cordova.exec(onSuccess, onFailure, "OneSignalPush", "logoutEmail", []); -}; - -OneSignal.prototype.userProvidedPrivacyConsent = function(callback) { - cordova.exec(callback, function(){}, "OneSignalPush", "userProvidedPrivacyConsent", []); -}; - -OneSignal.prototype.setRequiresUserPrivacyConsent = function(required) { - cordova.exec(function() {}, function() {}, "OneSignalPush", "setRequiresUserPrivacyConsent", [required]); -}; - -OneSignal.prototype.provideUserConsent = function(granted) { - cordova.exec(function() {}, function() {}, "OneSignalPush", "provideUserConsent", [granted]); -}; - -/** Possible function usages - setExternalUserId(externalId: string?): void - setExternalUserId(externalId: string?, callback: function): void - setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback: function): void -*/ -OneSignal.prototype.setExternalUserId = function(externalId, varArg1, varArg2) { - if (externalId == undefined) - externalId = null; - - var externalIdAuthHash = null; - var callback = function() {}; - - if (typeof varArg1 === "function") { - // Method was called like setExternalUserId(externalId: string?, callback: function) - callback = varArg1; - } - else if (typeof varArg1 === "string") { - // Method was called like setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback: function) - externalIdAuthHash = varArg1; - callback = varArg2; - } - else if (typeof varArg1 === "undefined") { - // Method was called like setExternalUserId(externalId: string?) - // Defaults defined above for externalIdAuthHash and callback - } - else { - // This does not catch all possible wrongly typed params but prevents a good number of them - console.error("Invalid param types passed to OneSignal.setExternalUserId(). Definition is setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback?: function): void") - return; - } - - var passToNativeParams = [externalId]; - if (externalIdAuthHash !== null) - passToNativeParams.push(externalIdAuthHash) - cordova.exec(callback, function() {}, "OneSignalPush", "setExternalUserId", passToNativeParams); -}; - -OneSignal.prototype.removeExternalUserId = function(externalUserIdCallback) { - if (externalUserIdCallback == undefined) - externalUserIdCallback = function() {}; - - cordova.exec(externalUserIdCallback, function() {}, "OneSignalPush", "removeExternalUserId", []); -}; - -/** - * in app messaging - */ - -OneSignal.prototype.addTriggers = function(triggers) { - Object.keys(triggers).forEach(function(key){ - // forces values to be string types - if (typeof triggers[key] !== "string") { - triggers[key] = JSON.stringify(triggers[key]); - } - }); - cordova.exec(function() {}, function() {}, "OneSignalPush", "addTriggers", [triggers]); -}; - -OneSignal.prototype.addTrigger = function(key, value) { - var obj = {}; - obj[key] = value; - OneSignal.prototype.addTriggers(obj); -}; - -OneSignal.prototype.removeTriggerForKey = function(key) { - OneSignal.prototype.removeTriggersForKeys([key]); -}; - -OneSignal.prototype.removeTriggersForKeys = function(keys) { - if (!Array.isArray(keys)){ - console.error("OneSignal: removeTriggersForKeys: argument must be of type Array") - } - cordova.exec(function() {}, function() {}, "OneSignalPush", "removeTriggersForKeys", [keys]); -}; - -OneSignal.prototype.getTriggerValueForKey = function(key, callback) { - var getTriggerValueForKeyCallback = function(obj) { - callback(obj.value); - }; - cordova.exec(getTriggerValueForKeyCallback, function() {}, "OneSignalPush", "getTriggerValueForKey", [key]); -}; - -OneSignal.prototype.pauseInAppMessages = function(pause) { - cordova.exec(function() {}, function() {}, "OneSignalPush", "pauseInAppMessages", [pause]); -}; - -/** - * outcomes - */ - -OneSignal.prototype.sendOutcome = function(name, callback) { - if (typeof callback === "undefined") - callback = function() {}; - - if (typeof callback !== "function") { - console.error("OneSignal: sendOutcome: must provide a valid callback"); - return; - } - - const sendOutcomeCallback = function(result) { - callback(result); - }; - - cordova.exec(sendOutcomeCallback, function() {}, "OneSignalPush", "sendOutcome", [name]); -}; - -OneSignal.prototype.sendUniqueOutcome = function(name, callback) { - if (typeof callback === "undefined") - callback = function() {}; - - if (typeof callback !== "function") { - console.error("OneSignal: sendUniqueOutcome: must provide a valid callback"); - return; - } - - const sendUniqueOutcomeCallback = function(result) { - callback(result); - }; - - cordova.exec(sendUniqueOutcomeCallback, function() {}, "OneSignalPush", "sendUniqueOutcome", [name]); -}; - -OneSignal.prototype.sendOutcomeWithValue = function(name, value, callback) { - if (typeof callback === "undefined") - callback = function() {}; - - if (typeof callback !== "function") { - console.error("OneSignal: sendOutcomeWithValue: must provide a valid callback"); - return; - } - - const sendOutcomeWithValueCallback = function(result) { - callback(result); - }; - - cordova.exec(sendOutcomeWithValueCallback, function() {}, "OneSignalPush", "sendOutcomeWithValue", [name, Number(value)]); -}; - -//------------------------------------------------------------------- - -if(!window.plugins) - window.plugins = {}; - -if (!window.plugins.OneSignal) - window.plugins.OneSignal = new OneSignal(); - -if (typeof module != 'undefined' && module.exports) - module.exports = OneSignal; diff --git a/www/OneSignalPlugin.js b/www/OneSignalPlugin.js new file mode 100644 index 00000000..f5a4c4a9 --- /dev/null +++ b/www/OneSignalPlugin.js @@ -0,0 +1,463 @@ +/** + * Modified MIT License + * + * Copyright 2019 OneSignal + * + * 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: + * + * 1. The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 2. All copies of substantial portions of the Software may only be used in connection + * with services provided by OneSignal. + * + * 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. + */ + +var OSNotificationReceivedEvent = require('./NotificationReceived').OSNotificationReceivedEvent; +var OSNotificationOpenedResult = require('./NotificationOpened'); +var OSInAppMessageAction = require('./InAppMessage'); +var OSDeviceState = require('./Subscription').OSDeviceState; +var OSPermissionStateChanges = require('./Subscription').OSPermissionStateChanges; +var OSSubscriptionStateChanges = require('./Subscription').OSSubscriptionStateChanges; +var OSEmailSubscriptionStateChanges = require('./Subscription').OSEmailSubscriptionStateChanges; +var OSSMSSubscriptionStateChanges = require('./Subscription').OSSMSSubscriptionStateChanges; + +var OneSignalPlugin = function() { + var _appID = ""; + var _notificationWillShowInForegroundDelegate = function(notificationReceived) {}; + var _notificationOpenedDelegate = function(notificationOpened) {}; + var _inAppMessageClickDelegate = function (action) {}; +}; + +OneSignalPlugin.prototype.OSNotificationPermission = { + NotDetermined: 0, + Authorized: 1, + Denied: 2 +}; + +OneSignalPlugin._permissionObserverList = []; +OneSignalPlugin._subscriptionObserverList = []; +OneSignalPlugin._emailSubscriptionObserverList = []; +OneSignalPlugin._smsSubscriptionObserverList = []; + +// You must call init before any other OneSignal function. +OneSignalPlugin.prototype.setAppId = function(appId) { + OneSignalPlugin._appID = appId; + + window.cordova.exec(function() {}, function(){}, "OneSignalPush", "init", [OneSignalPlugin._appID]); +}; + +OneSignalPlugin.prototype.setNotificationWillShowInForegroundHandler = function(handleNotificationWillShowInForegroundCallback) { + OneSignalPlugin._notificationWillShowInForegroundDelegate = handleNotificationWillShowInForegroundCallback; + + var foregroundParsingHandler = function(notificationReceived) { + console.log("foregroundParsingHandler " + JSON.stringify(notificationReceived)); + OneSignalPlugin._notificationWillShowInForegroundDelegate(OSNotificationReceivedEvent.create(notificationReceived)); + }; + + window.cordova.exec(foregroundParsingHandler, function(){}, "OneSignalPush", "setNotificationWillShowInForegroundHandler", []); +}; + +OneSignalPlugin.prototype.setNotificationOpenedHandler = function(handleNotificationOpenedCallback) { + OneSignalPlugin._notificationOpenedDelegate = handleNotificationOpenedCallback; + + var notificationOpenedHandler = function(json) { + OneSignalPlugin._notificationOpenedDelegate(new OSNotificationOpenedResult(json)); + }; + + window.cordova.exec(notificationOpenedHandler, function(){}, "OneSignalPush", "setNotificationOpenedHandler", []); +}; + +OneSignalPlugin.prototype.setInAppMessageClickHandler = function(handler) { + OneSignalPlugin._inAppMessageClickDelegate = handler; + + var inAppMessageClickHandler = function(json) { + OneSignalPlugin._inAppMessageClickDelegate(new OSInAppMessageAction(json)); + }; + + window.cordova.exec(inAppMessageClickHandler, function() {}, "OneSignalPush", "setInAppMessageClickHandler", []); +}; + +OneSignalPlugin._processFunctionList = function(array, param) { + for (var i = 0; i < array.length; i++) + array[i](param); +}; + +OneSignalPlugin.prototype.completeNotification = function(notification, shouldDisplay) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "completeNotification", [notification.notificationId, shouldDisplay]); +}; + +OneSignalPlugin.prototype.getDeviceState = function(deviceStateReceivedCallBack) { + var deviceStateCallback = function(json) { + deviceStateReceivedCallBack(new OSDeviceState(json)); + }; + window.cordova.exec(deviceStateCallback, function(){}, "OneSignalPush", "getDeviceState", []); +}; + +OneSignalPlugin.prototype.setLanguage = function(language) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "setLanguage", [language]); +} + +OneSignalPlugin.prototype.addSubscriptionObserver = function(callback) { + OneSignalPlugin._subscriptionObserverList.push(callback); + var subscriptionCallBackProcessor = function(state) { + OneSignalPlugin._processFunctionList(OneSignalPlugin._subscriptionObserverList, new OSSubscriptionStateChanges(state)); + }; + window.cordova.exec(subscriptionCallBackProcessor, function(){}, "OneSignalPush", "addSubscriptionObserver", []); +}; + +OneSignalPlugin.prototype.addEmailSubscriptionObserver = function(callback) { + OneSignalPlugin._emailSubscriptionObserverList.push(callback); + var emailSubscriptionCallbackProcessor = function(state) { + OneSignalPlugin._processFunctionList(OneSignalPlugin._emailSubscriptionObserverList, new OSEmailSubscriptionStateChanges(state)); + }; + window.cordova.exec(emailSubscriptionCallbackProcessor, function(){}, "OneSignalPush", "addEmailSubscriptionObserver", []); +}; + +OneSignalPlugin.prototype.addSMSSubscriptionObserver = function(callback) { + OneSignalPlugin._smsSubscriptionObserverList.push(callback); + var smsSubscriptionCallbackProcessor = function(state) { + OneSignalPlugin._processFunctionList(OneSignalPlugin._smsSubscriptionObserverList, new OSSMSSubscriptionStateChanges(state)); + }; + window.cordova.exec(smsSubscriptionCallbackProcessor, function(){}, "OneSignalPush", "addSMSSubscriptionObserver", []); +}; + +OneSignalPlugin.prototype.addPermissionObserver = function(callback) { + OneSignalPlugin._permissionObserverList.push(callback); + var permissionCallBackProcessor = function(state) { + OneSignalPlugin._processFunctionList(OneSignalPlugin._permissionObserverList, new OSPermissionStateChanges(state)); + }; + window.cordova.exec(permissionCallBackProcessor, function(){}, "OneSignalPush", "addPermissionObserver", []); +}; + +OneSignalPlugin.prototype.getTags = function(tagsReceivedCallBack) { + window.cordova.exec(tagsReceivedCallBack, function(){}, "OneSignalPush", "getTags", []); +}; + +OneSignalPlugin.prototype.sendTag = function(key, value) { + const jsonKeyValue = {}; + jsonKeyValue[key] = value; + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "sendTags", [jsonKeyValue]); +}; + +OneSignalPlugin.prototype.sendTags = function(tags) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "sendTags", [tags]); +}; + +OneSignalPlugin.prototype.deleteTag = function(key) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "deleteTags", [key]); +}; + +OneSignalPlugin.prototype.deleteTags = function(keys) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "deleteTags", keys); +}; + +// Only applies to iOS (does nothing on Android as it always silently registers) +// Call only if you passed false to autoRegister +OneSignalPlugin.prototype.registerForProvisionalAuthorization = function(provisionalAuthCallback) { + window.cordova.exec(provisionalAuthCallback, function(){}, "OneSignalPush", "registerForProvisionalAuthorization", []); +}; + +// Only applies to iOS (does nothing on Android as it always silently registers without user permission) +OneSignalPlugin.prototype.promptForPushNotificationsWithUserResponse = function(callback) { + var internalCallback = function(data) { + callback(data.accepted === "true"); + }; + window.cordova.exec(internalCallback, function(){}, "OneSignalPush", "promptForPushNotificationsWithUserResponse", []); +}; + +// Only applies to Android. +OneSignalPlugin.prototype.clearOneSignalNotifications = function() { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "clearOneSignalNotifications", []); +}; + +// Only applies to Android. +// If notifications are disabled for your app, unsubscribe the user from OneSignalPlugin. +OneSignalPlugin.prototype.unsubscribeWhenNotificationsAreDisabled = function(unsubscribe) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "unsubscribeWhenNotificationsAreDisabled", [unsubscribe]); +}; + +// Only applies to Android. Cancels a single OneSignal notification based on its Android notification integer ID +OneSignalPlugin.prototype.removeNotification = function(id) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "removeNotification", [id]); +}; + +// Only applies to Android. Cancels a single OneSignal notification based on its Android notification group ID +OneSignalPlugin.prototype.removeGroupedNotifications = function(groupId) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "removeGroupedNotifications", [groupId]); +}; + +OneSignalPlugin.prototype.disablePush = function(disable) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "disablePush", [disable]); +}; + +OneSignalPlugin.prototype.postNotification = function(jsonData, onSuccess, onFailure) { + if (onSuccess == null) + onSuccess = function() {}; + + if (onFailure == null) + onFailure = function() {}; + + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "postNotification", [jsonData]); +}; + +OneSignalPlugin.prototype.setLogLevel = function(nsLogLevel, visualLogLevel) { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "setLogLevel", [nsLogLevel, visualLogLevel]); +}; + +OneSignalPlugin.prototype.userProvidedPrivacyConsent = function(callback) { + window.cordova.exec(callback, function(){}, "OneSignalPush", "userProvidedPrivacyConsent", []); +}; + +OneSignalPlugin.prototype.requiresUserPrivacyConsent = function(callback) { + window.cordova.exec(callback, function(){}, "OneSignalPush", "requiresUserPrivacyConsent", []); +}; + +OneSignalPlugin.prototype.setRequiresUserPrivacyConsent = function(required) { + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "setRequiresUserPrivacyConsent", [required]); +}; + +OneSignalPlugin.prototype.provideUserConsent = function(granted) { + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "provideUserConsent", [granted]); +}; + +/** + * Email + */ +OneSignalPlugin.prototype.setEmail = function(email, emailAuthToken, onSuccess, onFailure) { + if (onSuccess == null) + onSuccess = function() {}; + + if (onFailure == null) + onFailure = function() {}; + + if (typeof emailAuthToken == 'function') { + onFailure = onSuccess; + onSuccess = emailAuthToken; + + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedEmail", [email]); + } else if (emailAuthToken == undefined) { + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedEmail", [email]); + } else { + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setEmail", [email, emailAuthToken]); + } +}; + +OneSignalPlugin.prototype.logoutEmail = function(onSuccess, onFailure) { + if (onSuccess == null) + onSuccess = function() {}; + + + if (onFailure == null) + onFailure = function() {}; + + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "logoutEmail", []); +}; + +/** + * SMS + */ +OneSignalPlugin.prototype.setSMSNumber = function(smsNumber, smsAuthToken, onSuccess, onFailure) { + if (onSuccess == null) + onSuccess = function() {}; + + if (onFailure == null) + onFailure = function() {}; + + if (typeof smsAuthToken == 'function') { + onFailure = onSuccess; + onSuccess = smsAuthToken; + + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedSMSNumber", [smsNumber]); + } else if (smsAuthToken == undefined) { + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setUnauthenticatedSMSNumber", [smsNumber]); + } else { + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "setSMSNumber", [smsNumber, smsAuthToken]); + } +}; + +OneSignalPlugin.prototype.logoutSMSNumber = function(onSuccess, onFailure) { + if (onSuccess == null) + onSuccess = function() {}; + + + if (onFailure == null) + onFailure = function() {}; + + window.cordova.exec(onSuccess, onFailure, "OneSignalPush", "logoutSMSNumber", []); +}; + +/** Possible function usages + setExternalUserId(externalId: string?): void + setExternalUserId(externalId: string?, callback: function): void + setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback: function): void +*/ +OneSignalPlugin.prototype.setExternalUserId = function(externalId, varArg1, varArg2) { + if (externalId == undefined) + externalId = null; + + var externalIdAuthHash = null; + var callback = function() {}; + + if (typeof varArg1 === "function") { + // Method was called like setExternalUserId(externalId: string?, callback: function) + callback = varArg1; + } + else if (typeof varArg1 === "string") { + // Method was called like setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback: function) + externalIdAuthHash = varArg1; + callback = varArg2; + } + else if (typeof varArg1 === "undefined") { + // Method was called like setExternalUserId(externalId: string?) + // Defaults defined above for externalIdAuthHash and callback + } + else { + // This does not catch all possible wrongly typed params but prevents a good number of them + console.error("Invalid param types passed to OneSignalPlugin.setExternalUserId(). Definition is setExternalUserId(externalId: string?, externalIdAuthHash: string?, callback?: function): void") + return; + } + + var passToNativeParams = [externalId]; + if (externalIdAuthHash !== null) + passToNativeParams.push(externalIdAuthHash) + window.cordova.exec(callback, function() {}, "OneSignalPush", "setExternalUserId", passToNativeParams); +}; + +OneSignalPlugin.prototype.removeExternalUserId = function(externalUserIdCallback) { + if (externalUserIdCallback == undefined) + externalUserIdCallback = function() {}; + + window.cordova.exec(externalUserIdCallback, function() {}, "OneSignalPush", "removeExternalUserId", []); +}; + +/** + * In app messaging + */ +OneSignalPlugin.prototype.addTriggers = function(triggers) { + Object.keys(triggers).forEach(function(key){ + // forces values to be string types + if (typeof triggers[key] !== "string") { + triggers[key] = JSON.stringify(triggers[key]); + } + }); + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "addTriggers", [triggers]); +}; + +OneSignalPlugin.prototype.addTrigger = function(key, value) { + var obj = {}; + obj[key] = value; + OneSignalPlugin.prototype.addTriggers(obj); +}; + +OneSignalPlugin.prototype.removeTriggerForKey = function(key) { + OneSignalPlugin.prototype.removeTriggersForKeys([key]); +}; + +OneSignalPlugin.prototype.removeTriggersForKeys = function(keys) { + if (!Array.isArray(keys)){ + console.error("OneSignal: removeTriggersForKeys: argument must be of type Array") + } + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "removeTriggersForKeys", [keys]); +}; + +OneSignalPlugin.prototype.getTriggerValueForKey = function(key, callback) { + var getTriggerValueForKeyCallback = function(obj) { + callback(obj.value); + }; + window.cordova.exec(getTriggerValueForKeyCallback, function() {}, "OneSignalPush", "getTriggerValueForKey", [key]); +}; + +OneSignalPlugin.prototype.pauseInAppMessages = function(pause) { + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "pauseInAppMessages", [pause]); +}; + +/** + * Outcomes + */ +OneSignalPlugin.prototype.sendOutcome = function(name, callback) { + if (typeof callback === "undefined") + callback = function() {}; + + if (typeof callback !== "function") { + console.error("OneSignal: sendOutcome: must provide a valid callback"); + return; + } + + const sendOutcomeCallback = function(result) { + callback(result); + }; + + window.cordova.exec(sendOutcomeCallback, function() {}, "OneSignalPush", "sendOutcome", [name]); +}; + +OneSignalPlugin.prototype.sendUniqueOutcome = function(name, callback) { + if (typeof callback === "undefined") + callback = function() {}; + + if (typeof callback !== "function") { + console.error("OneSignal: sendUniqueOutcome: must provide a valid callback"); + return; + } + + const sendUniqueOutcomeCallback = function(result) { + callback(result); + }; + + window.cordova.exec(sendUniqueOutcomeCallback, function() {}, "OneSignalPush", "sendUniqueOutcome", [name]); +}; + +OneSignalPlugin.prototype.sendOutcomeWithValue = function(name, value, callback) { + if (typeof callback === "undefined") + callback = function() {}; + + if (typeof callback !== "function") { + console.error("OneSignal: sendOutcomeWithValue: must provide a valid callback"); + return; + } + + const sendOutcomeWithValueCallback = function(result) { + callback(result); + }; + + window.cordova.exec(sendOutcomeWithValueCallback, function() {}, "OneSignalPush", "sendOutcomeWithValue", [name, Number(value)]); +}; + +/** + * Location + */ + +OneSignalPlugin.prototype.promptLocation = function() { + window.cordova.exec(function(){}, function(){}, "OneSignalPush", "promptLocation", []); +}; + +OneSignalPlugin.prototype.setLocationShared = function(shared) { + window.cordova.exec(function() {}, function() {}, "OneSignalPush", "setLocationShared", [shared]); +}; + +OneSignalPlugin.prototype.isLocationShared = function(callback) { + window.cordova.exec(callback, function() {}, "OneSignalPush", "isLocationShared", []); +}; + +//------------------------------------------------------------------- + +var OneSignal = new OneSignalPlugin(); +module.exports = OneSignal; + +if(!window.plugins) + window.plugins = {}; + +if (!window.plugins.OneSignal) + window.plugins.OneSignal = OneSignal; \ No newline at end of file diff --git a/www/Subscription.js b/www/Subscription.js new file mode 100644 index 00000000..c4ff7ad2 --- /dev/null +++ b/www/Subscription.js @@ -0,0 +1,124 @@ +function OSDeviceState(json) { + if (json.hasNotificationPermission) { + this.hasNotificationPermission = json.hasNotificationPermission; + } else { + this.hasNotificationPermission = json.areNotificationsEnabled; + } + + if (json.notificationPermissionStatus !== null) { + this.notificationPermissionStatus = json.notificationPermissionStatus; + } + + this.pushDisabled = json.isPushDisabled; + this.subscribed = json.isSubscribed; + this.emailSubscribed = json.isEmailSubscribed; + this.smsSubscribed = json.isSMSSubscribed; + this.userId = json.userId; + this.pushToken = json.pushToken; + this.emailUserId = json.emailUserId; + this.emailAddress = json.emailAddress; + this.smsUserId = json.smsUserId; + this.smsNumber = json.smsNumber; +} + +function OSPermissionState(json) { + if (json.status !== null) { + this.status = json.status; + } else { + this.status = json.areNotificationsEnabled ? OneSignal.prototype.OSNotificationPermission.Authorized : OneSignal.prototype.OSNotificationPermission.Denied; + } + + // iOS only + if (json.provisional !== null) { + this.provisional = json.provisional; + } else { + this.provisional = false; + } + + // iOS only + if (json.hasPrompted !== null) { + this.hasPrompted = json.hasPrompted; + } else { + this.hasPrompted = false; + } +} + +function OSPermissionStateChanges(json) { + if (json.from) { + this.from = new OSPermissionState(json.from); + } + if (json.to) { + this.to = new OSPermissionState(json.to); + } +} + +/// Represents the current user's subscription state with OneSignal +function OSSubscriptionState(json) { + /// A boolean parameter that indicates if the user + /// is subscribed to your app with OneSignal + /// This is only true if the `userId`, `pushToken`, and + /// `userSubscriptionSetting` parameters are defined/true. + this.isSubscribed = json.isSubscribed; + + /// The current user's User ID (AKA playerID) with OneSignal + this.userId = json.userId; + + /// The APNS (iOS), GCM/FCM (Android) push token + this.pushToken = json.pushToken; +} + +/// An instance of this class describes a change in the user's OneSignal +/// push notification subscription state, ie. the user subscribed to +/// push notifications with your app. +function OSSubscriptionStateChanges(json) { + if (json.from) { + this.from = new OSSubscriptionState(json.from); + } + if (json.to) { + this.to = new OSSubscriptionState(json.to); + } +} + +/// Represents the user's OneSignal email subscription state, +function OSEmailSubscriptionState(json) { + this.isEmailSubscribed = json.isSubscribed; + this.emailAddress = json.emailAddress; + this.emailUserId = json.emailUserId; +} + +/// An instance of this class describes a change in the user's +/// email subscription state with OneSignal +function OSEmailSubscriptionStateChanges(json) { + if (json.from) { + this.from = new OSEmailSubscriptionState(json.from); + } + if (json.to) { + this.to = new OSEmailSubscriptionState(json.to); + } +} + +/// Represents the user's OneSignal SMS subscription state, +function OSSMSSubscriptionState(json) { + this.isSMSSubscribed = json.isSubscribed; + this.smsNumber = json.smsNumber; + this.smsUserId = json.smsUserId; +} + +/// An instance of this class describes a change in the user's +/// SMS subscription state with OneSignal +function OSSMSSubscriptionStateChanges(json) { + if (json.from) { + this.from = new OSSMSSubscriptionState(json.from); + } + if (json.to) { + this.to = new OSSMSSubscriptionState(json.to); + } +} + +module.exports = { + OSDeviceState: OSDeviceState, + OSPermissionStateChanges: OSPermissionStateChanges, + OSSubscriptionStateChanges: OSSubscriptionStateChanges, + OSEmailSubscriptionStateChanges: OSEmailSubscriptionStateChanges, + OSSMSSubscriptionStateChanges: OSSMSSubscriptionStateChanges, +};