diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b3424..5e676e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ Batch Cordova Plugin +## 7.0.0 + +**Plugin** +* Updated Batch to 2.1 +* Batch requires to compile with SDK 35 (Android 15) (cordova-android@14). + +**iOS** +* `BatchBridgeNotificationCenterDelegate` now defaults to showing foreground notifications. + +**Profile** +- Added `setPhoneNumber` API to the `BatchProfileAttributeEditor` class. This requires to have a user identifier registered or to call the `identify` method beforehand. +- Added `setSMSMarketingSubscription` API to the `BatchProfileAttributeEditor` class. + +**Push** +- Removed deprecated API `registerForRemoteNotifications`. Please use `requestNotificationAuthorization` to request permission when needed, and `requestToken` at each app launch. + ## 6.0.0 This is a major release, please see our [migration guide](https://doc.batch.com/cordova/migrations/5x-migration/) for more info on how to update your current Batch implementation. diff --git a/README.md b/README.md index 6cf6539..ab7ab46 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This repository contains the plugin's source code (native code + cordova) and bu This plugin is compatible with: - cordova 9.0.0+ -- cordova-android 9.0.0+ +- cordova-android 14.0.0+ - cordova-ios 6.0.0+ Subsequent major Cordova and Cordova platform versions are _not_ supported until told otherwise. diff --git a/dist/package.json b/dist/package.json index 2df6d08..4270007 100644 --- a/dist/package.json +++ b/dist/package.json @@ -1,6 +1,6 @@ { "name": "@batch.com/cordova-plugin", - "version": "6.0.0", + "version": "7.0.0", "description": "Batch.com SDK Cordova/Ionic plugin for Android and iOS", "types": "index.d.ts", "cordova": { @@ -56,6 +56,11 @@ "cordova": ">=9.0.0", "cordova-android": ">=9.0.0", "cordova-ios": ">=6.0.0" + }, + "7.0.0": { + "cordova": ">=9.0.0", + "cordova-android": ">=14.0.0", + "cordova-ios": ">=6.0.0" } }, "author": "Batch.com", diff --git a/dist/plugin.xml b/dist/plugin.xml index 2113401..b213fc6 100755 --- a/dist/plugin.xml +++ b/dist/plugin.xml @@ -2,10 +2,10 @@ + version="7.0.0"> - + Batch @@ -19,7 +19,7 @@ - + @@ -79,7 +79,7 @@ - + diff --git a/dist/src/android/BatchCordovaPlugin.java b/dist/src/android/BatchCordovaPlugin.java index 18ff3c1..7aa7936 100644 --- a/dist/src/android/BatchCordovaPlugin.java +++ b/dist/src/android/BatchCordovaPlugin.java @@ -39,7 +39,7 @@ public class BatchCordovaPlugin extends CordovaPlugin implements Callback, Logge private static final String PLUGIN_VERSION_ENVIRONEMENT_VAR = "batch.plugin.version"; - private static final String PLUGIN_VERSION = "Cordova/6.0.0"; + private static final String PLUGIN_VERSION = "Cordova/7.0.0"; /** * Key used to add extra to an intent to prevent it to be used more than once to compute opens diff --git a/dist/src/android/interop/Action.java b/dist/src/android/interop/Action.java index e6a35e4..8d93aa0 100644 --- a/dist/src/android/interop/Action.java +++ b/dist/src/android/interop/Action.java @@ -21,7 +21,6 @@ public enum Action MESSAGING_SET_DO_NOT_DISTURB_ENABLED("messaging.setDoNotDisturbEnabled"), MESSAGING_SHOW_PENDING_MESSAGE("messaging.showPendingMessage"), PUSH_GET_LAST_KNOWN_TOKEN("push.getLastKnownPushToken"), - PUSH_REGISTER("push.register"), PUSH_SET_GCM_SENDER_ID("push.setGCMSenderID"), PUSH_CLEAR_BADGE("push.clearBadge"), PUSH_DISMISS_NOTIFICATIONS("push.dismissNotifications"), diff --git a/dist/src/android/interop/Bridge.java b/dist/src/android/interop/Bridge.java index 2855d07..3e06b6b 100644 --- a/dist/src/android/interop/Bridge.java +++ b/dist/src/android/interop/Bridge.java @@ -17,6 +17,7 @@ import com.batch.android.Batch; import com.batch.android.BatchAttributesFetchListener; import com.batch.android.BatchEmailSubscriptionState; +import com.batch.android.BatchSMSSubscriptionState; import com.batch.android.BatchEventAttributes; import com.batch.android.BatchMessage; import com.batch.android.BatchMigration; @@ -138,9 +139,6 @@ private static SimplePromise doAction(String actionName, Map parameters) throws Log.e(TAG, "Invalid SET_EMAIL_MARKETING_SUBSCRIPTION value: it can only be `subscribed` or `unsubscribed`."); } } + case "SET_PHONE_NUMBER" -> { + Object value = operationDescription.get("value"); + if (value != null && !(value instanceof String)) { + Log.e(TAG, "Invalid SET_PHONE_NUMBER value: it can only be a string or null"); + // Invalid value, continue. NULL is allowed though + continue; + } + editor.setPhoneNumber((String) value); + } + case "SET_SMS_MARKETING_SUB" -> { + Object value = operationDescription.get("value"); + if (value == null || !(value instanceof String)) { + Log.e(TAG, "Invalid SET_SMS_MARKETING_SUB value: it can only be a string"); + // Invalid value, continue. + continue; + } + + if ("subscribed".equals(value)) { + editor.setSMSMarketingSubscription(BatchSMSSubscriptionState.SUBSCRIBED); + } else if ("unsubscribed".equals(value)) { + editor.setSMSMarketingSubscription(BatchSMSSubscriptionState.UNSUBSCRIBED); + } else { + Log.e(TAG, "Invalid SET_SMS_MARKETING_SUB value: it can only be `subscribed` or `unsubscribed`."); + } + } case "SET_ATTRIBUTE" -> { String key = getTypedParameter(operationDescription, "key", String.class); String type = getTypedParameter(operationDescription, "type", String.class); diff --git a/dist/src/ios/BatchCordovaPlugin.h b/dist/src/ios/BatchCordovaPlugin.h index 656c203..419d42b 100644 --- a/dist/src/ios/BatchCordovaPlugin.h +++ b/dist/src/ios/BatchCordovaPlugin.h @@ -11,7 +11,7 @@ #import "BatchBridge.h" #import "BatchBridgeCallback.h" -#define PluginVersion "Cordova/6.0.0" +#define PluginVersion "Cordova/7.0.0" @interface BatchCordovaPlugin : CDVPlugin diff --git a/dist/src/ios/interop/BatchBridge.m b/dist/src/ios/interop/BatchBridge.m index 260ba45..9fcc888 100644 --- a/dist/src/ios/interop/BatchBridge.m +++ b/dist/src/ios/interop/BatchBridge.m @@ -274,10 +274,6 @@ + (NSString *)boolToBridgeString:(BOOL)value { // Do nothing } - else if ([action caseInsensitiveCompare:REGISTER_NOTIFS] == NSOrderedSame) - { - [BatchBridge registerForRemoteNotifications]; - } else if ([action caseInsensitiveCompare:DISMISS_NOTIFS] == NSOrderedSame) { [BatchBridge dismissNotifications]; @@ -483,12 +479,6 @@ + (void)setNotificationTypes:(BatchNotificationType)type [BatchPush setRemoteNotificationTypes:type]; } -+ (void)registerForRemoteNotifications -{ - [BatchPush requestNotificationAuthorization]; - [BatchPush refreshToken]; -} - + (void)clearBadge { [BatchPush clearBadge]; diff --git a/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.h b/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.h index b7a0918..6532ada 100644 --- a/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.h +++ b/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN + (void)registerAsDelegate; /// Should iOS display notifications even if the app is in foreground? -/// Default: false +/// Default: true @property (assign) BOOL showForegroundNotifications; /// Should Batch use the chained delegate's completionHandler responses or force its own, while still calling the chained delegate. diff --git a/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.m b/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.m index eddf34a..57f9eed 100644 --- a/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.m +++ b/dist/src/ios/interop/BatchBridgeNotificationCenterDelegate.m @@ -77,7 +77,7 @@ - (instancetype)init { self = [super init]; if (self) { - _showForegroundNotifications = false; + _showForegroundNotifications = true; _shouldUseChainedCompletionHandlerResponse = true; _isBatchReady = false; _enqueuedNotificationResponses = [NSMutableArray new]; diff --git a/dist/src/ios/interop/BatchBridgeShared.h b/dist/src/ios/interop/BatchBridgeShared.h index 937c920..19d2262 100644 --- a/dist/src/ios/interop/BatchBridgeShared.h +++ b/dist/src/ios/interop/BatchBridgeShared.h @@ -28,7 +28,6 @@ if (error == NULL) {\ #define PUSH_REQUEST_AUTHORIZATION @"push.requestAuthorization" #define PUSH_REQUEST_PROVISIONAL_AUTH @"push.iOS.requestProvisionalAuthorization" -#define REGISTER_NOTIFS @"push.register" #define DISMISS_NOTIFS @"push.dismissNotifications" #define CLEAR_BADGE @"push.clearBadge" diff --git a/dist/src/ios/interop/BatchProfileBridge.m b/dist/src/ios/interop/BatchProfileBridge.m index 6e4415a..44781fd 100644 --- a/dist/src/ios/interop/BatchProfileBridge.m +++ b/dist/src/ios/interop/BatchProfileBridge.m @@ -60,6 +60,20 @@ + (void)editAttributes:(NSDictionary*)params NSLog(@"Batch Bridge - Invalid value for email marketing subscription state. Must be `subscribed` or `unsubscribed`."); } } + else if([@"SET_PHONE_NUMBER" isEqualToString:operationName]) + { + [editor setPhoneNumber:[BatchBridgeUtils nullableString:operationDescription forKey:@"value"] error:nil]; + } + else if([@"SET_SMS_MARKETING_SUB" isEqualToString:operationName]) { + NSString* value = [operationDescription objectForKey:@"value"]; + if([[value uppercaseString] isEqualToString:@"SUBSCRIBED"]) { + [editor setSMSMarketingSubscriptionState:BatchSMSSubscriptionStateSubscribed]; + } else if ([[value uppercaseString] isEqualToString:@"UNSUBSCRIBED"]) { + [editor setSMSMarketingSubscriptionState: BatchSMSSubscriptionStateUnsubscribed]; + } else { + NSLog(@"Batch Bridge - Invalid value for SMS marketing subscription state. Must be `subscribed` or `unsubscribed`."); + } + } else if ([@"SET_ATTRIBUTE" isEqualToString:operationName]) { NSString *type = operationDescription[@"type"]; diff --git a/src/actions.ts b/src/actions.ts index 8bf7cfc..0cb54fa 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -14,7 +14,6 @@ export enum Push { SetIOSShowForegroundNotifications = "push.setIOSShowForegroundNotifications", SetIOSNotifTypes = "push.setIOSNotifTypes", SetAndroidNotifTypes = "push.setAndroidNotifTypes", - Register = "push.register", DismissNotifications = "push.dismissNotifications", ClearBadge = "push.clearBadge", RefreshToken = "push.iOS.refreshToken", @@ -62,6 +61,8 @@ export enum ProfileAttributeOperation { SetRegion = "SET_REGION", SetEmail = "SET_EMAIL_ADDRESS", SetEmailMarketingSubscription = "SET_EMAIL_MARKETING_SUB", + SetPhoneNumber = "SET_PHONE_NUMBER", + SetSMSMarketingSubscription = "SET_SMS_MARKETING_SUB", SetAttribute = "SET_ATTRIBUTE", RemoveAttribute = "REMOVE_ATTRIBUTE", AddToArray = "ADD_TO_ARRAY", diff --git a/src/batchStub.ts b/src/batchStub.ts index a3c2ea0..d955ff9 100644 --- a/src/batchStub.ts +++ b/src/batchStub.ts @@ -19,7 +19,6 @@ class PushStub implements BatchSDK.PushModule { this.iOSNotificationTypes = iOSNotificationTypes; } - public registerForRemoteNotifications() {} public refreshToken() {} public requestNotificationAuthorization() {} public requestProvisionalNotificationAuthorization() {} @@ -132,13 +131,18 @@ class BatchUserDataEditorStub implements BatchSDK.BatchProfileAttributeEditor { public setRegion(_region: string | null) { return this; } - public setEmailAddress(_email: string | null) { return this; } public setEmailMarketingSubscription(_state: "subscribed" | "unsubscribed") { return this; } + public setPhoneNumber(_phoneNumber: string | null) { + return this; + } + public setSMSMarketingSubscription(_state: "subscribed" | "unsubscribed") { + return this; + } public setAttribute( _key: string, _value: string | number | boolean | Date | URL diff --git a/src/modules/profile/profileAttributeEditor.ts b/src/modules/profile/profileAttributeEditor.ts index 80904b1..32f6fc3 100644 --- a/src/modules/profile/profileAttributeEditor.ts +++ b/src/modules/profile/profileAttributeEditor.ts @@ -96,6 +96,42 @@ export class BatchProfileAttributeEditor return this; } + public setPhoneNumber(phoneNumber: string | null): this { + if (typeof phoneNumber !== "string" && phoneNumber !== null) { + writeBatchLog( + false, + "BatchProfileAttributeEditor - Phone number must be a string or null" + ); + return this; + } + this._enqueueOperation(ProfileAttributeOperation.SetPhoneNumber, { + value: phoneNumber, + }); + return this; + } + + public setSMSMarketingSubscription( + state: "subscribed" | "unsubscribed" + ): this { + if ( + typeof state !== "string" || + (state !== "subscribed" && state !== "unsubscribed") + ) { + writeBatchLog( + false, + "BatchProfileAttributeEditor - SMS marketing subscription state must be `subscribed` or `unsubscribed`." + ); + return this; + } + this._enqueueOperation( + ProfileAttributeOperation.SetSMSMarketingSubscription, + { + value: state, + } + ); + return this; + } + public setAttribute( key: string, value: string | number | boolean | Date | URL | Array diff --git a/src/modules/push.ts b/src/modules/push.ts index 3300bcf..7251651 100644 --- a/src/modules/push.ts +++ b/src/modules/push.ts @@ -34,10 +34,6 @@ export class PushModule implements BatchSDK.PushModule { this.iOSNotificationTypes = iOSNotificationTypes; } - public registerForRemoteNotifications(): void { - sendToBridge(null, PushActions.Register, null); - } - public refreshToken(): void { sendToBridge(null, PushActions.RefreshToken, null); } diff --git a/types/index.d.ts b/types/index.d.ts index 5acf331..fd0f257 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -146,9 +146,9 @@ export declare namespace BatchSDK { * - Prevent batch.start() * - Disable any network capability from the SDK * - Disable all In-App campaigns - * - Make the Inbox module return an error immediatly when used + * - Make the Inbox module return an error immediately when used * - Make the SDK reject any editor calls - * - Make the SDK reject calls to batch.user.trackEvent(), batch.user.trackTransaction(), batch.user.trackLocation() and any related methods + * - Make the SDK reject calls to batch.profile.trackEvent(), batch.profile.trackLocation() and any related methods * * Even if you opt in afterwards, data that has been generated while opted out WILL be lost. * @@ -282,8 +282,8 @@ export declare namespace BatchSDK { identify(identifier: string | null): void; /** - * Get the user data editor. Don't forget to call save when you're done. - * @return Batch user data editor + * Get the profile data editor. Don't forget to call save when you're done. + * @return Batch profile data editor */ getEditor(): BatchProfileAttributeEditor; @@ -318,20 +318,20 @@ export declare namespace BatchSDK { getInstallationID(): Promise; /** - * Get the application language override set using BatchUserDataEditor. Batch must be started to read it. + * Get the application language override set using BatchProfileAttributeEditor. Batch must be started to read it. * The promise will return the language you have previously set, if any, or undefined. Might be null/undefined if Batch isn't started. * Might throw if Batch isn't started. */ getLanguage(): Promise; /** - * Get the application region override set using BatchUserDataEditor. Batch must be started to read it. + * Get the application region override set using BatchProfileAttributeEditor. Batch must be started to read it. * The promise will return the region you have previously set, if any, or undefined. Might be null/undefined if Batch isn't started. */ getRegion(): Promise; /** - * Get the user identifier set using BatchUserDataEditor. Batch must be started to read it. + * Get the user identifier set using BatchProfileAttributeEditor. Batch must be started to read it. * The promise will return the user identifier you have previously set, if any, or undefined. Might be null/undefined if Batch isn't started. */ getIdentifier(): Promise; @@ -362,13 +362,6 @@ export declare namespace BatchSDK { AndroidNotificationTypes: typeof AndroidNotificationTypes; iOSNotificationTypes: typeof iOSNotificationTypes; - /** - * Ask iOS users if they want to accept push notifications. Required to be able to push users. - * No effect on Android. - * @deprecated Use requestNotificationAuthorization/requestProvisionalNotificationAuthorization and refreshToken - */ - registerForRemoteNotifications(): void; - /** * Ask iOS to refresh the push token. If the app didn't prompt the user for consent yet, this will not be done. * You should call this at the start of your app, to make sure Batch always gets a valid token after app updates. @@ -417,8 +410,8 @@ export declare namespace BatchSDK { setiOSNotificationTypes(notifTypes: iOSNotificationTypes): void; /** - * Set whether notifications should be show in the foreground on iOS. - * If true, notifications will be shown like if the user was outside of your application and + * Set whether notifications should be shown in the foreground on iOS. + * If true, notifications will be shown like if the user was outside your application and * `batchPushReceived` will only be triggered when the notification is tapped. * @param showForegroundNotifications Show foreground notifications? */ @@ -658,7 +651,7 @@ export declare namespace BatchSDK { } /** - * User data editor + * Profile attribute editor */ interface BatchProfileAttributeEditor { /** @@ -676,7 +669,7 @@ export declare namespace BatchSDK { setRegion(region: string | null): BatchProfileAttributeEditor; /** - * Set the user email address. + * Set the profile email address. * * This requires to have a custom user ID registered * or to call the `setIdentifier` method on the editor instance beforehand. @@ -685,7 +678,7 @@ export declare namespace BatchSDK { setEmailAddress(email: string | null): BatchProfileAttributeEditor; /** - * Set the user email marketing subscription state + * Set the profile email marketing subscription state * * @param state The state of the marketing email subscription. Must be "subscribed" or "unsubscribed". */ @@ -693,6 +686,25 @@ export declare namespace BatchSDK { state: "subscribed" | "unsubscribed" ): BatchProfileAttributeEditor; + /** + * Set the profile phone number. + * + * This requires to have a custom profile ID registered or to call the `identify` method beforehand. + * @param phoneNumber A valid E.164 formatted string. Must start with a `+` and not be longer than 15 digits + * without special characters (eg: "+33123456789"). Null to reset. + */ + setPhoneNumber(phoneNumber: string | null): BatchProfileAttributeEditor; + + /** + * Set the profile SMS marketing subscription state. + * + * Note that profile's subscription status is automatically set to unsubscribed when users send a STOP message. + * @param state The state of the SMS marketing subscription. Must be "subscribed" or "unsubscribed". + */ + setSMSMarketingSubscription( + state: "subscribed" | "unsubscribed" + ): BatchProfileAttributeEditor; + /** * Set an attribute for a key * @param key Attribute key. Cannot be null, empty or undefined. It should be made of letters, numbers or underscores ([a-z0-9_]) and can't be longer than 30 characters.