From 37f7f126b1ef4a96a549f6b05d0356582e1eb6a6 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Fri, 15 Nov 2024 14:36:13 +0100 Subject: [PATCH 1/4] all: bump batch to 2.1 --- RNBatchPush.podspec | 2 +- android/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RNBatchPush.podspec b/RNBatchPush.podspec index bb6eb72..8d6adf4 100644 --- a/RNBatchPush.podspec +++ b/RNBatchPush.podspec @@ -15,6 +15,6 @@ Pod::Spec.new do |s| install_modules_dependencies(s) s.dependency "React" - s.dependency 'Batch', '~> 2.0.0' + s.dependency 'Batch', '~> 2.1.0' end diff --git a/android/build.gradle b/android/build.gradle index b6003fa..e9d588a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,7 +2,7 @@ def DEFAULT_MIN_SDK_VERSION = 21 def DEFAULT_COMPILE_SDK_VERSION = 34 def DEFAULT_BUILD_TOOLS_VERSION = "34.0.0" def DEFAULT_TARGET_SDK_VERSION = 34 -def DEFAULT_BATCH_SDK_VERSION = "2.0.+" +def DEFAULT_BATCH_SDK_VERSION = "2.1.+" def safeExtGet(prop, fallback) { rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback From 45fe35de687db13e57b9e0918bbbd2b4abc792e5 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Fri, 15 Nov 2024 14:37:30 +0100 Subject: [PATCH 2/4] bridge: add phone number and sms subscription apis --- .../com/batch/batch_rn/RNBatchModuleImpl.java | 12 +++++++ ios/RNBatch.mm | 13 +++++++ src/BatchProfileAttributeEditor.ts | 36 ++++++++++++++++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/batch/batch_rn/RNBatchModuleImpl.java b/android/src/main/java/com/batch/batch_rn/RNBatchModuleImpl.java index 716a1bc..dc7b870 100644 --- a/android/src/main/java/com/batch/batch_rn/RNBatchModuleImpl.java +++ b/android/src/main/java/com/batch/batch_rn/RNBatchModuleImpl.java @@ -23,6 +23,7 @@ import com.batch.android.BatchPushRegistration; import com.batch.android.BatchTagCollectionsFetchListener; import com.batch.android.BatchEmailSubscriptionState; +import com.batch.android.BatchSMSSubscriptionState; import com.batch.android.BatchUserAttribute; import com.batch.android.PushNotificationType; import com.batch.android.BatchInboxFetcher; @@ -654,6 +655,17 @@ public void profile_saveEditor(ReadableArray actions) { } else if (type.equals("setEmailMarketingSubscription")) { String value = action.getString("value"); editor.setEmailMarketingSubscription(BatchEmailSubscriptionState.valueOf(value)); + } else if (type.equals("setPhoneNumber")) { + ReadableType valueType = action.getType("value"); + if (valueType.equals(ReadableType.Null)) { + editor.setPhoneNumber(null); + } else { + String value = action.getString("value"); + editor.setPhoneNumber(value); + } + } else if (type.equals("setSMSMarketingSubscription")) { + String value = action.getString("value"); + editor.setSMSMarketingSubscription(BatchSMSSubscriptionState.valueOf(value)); } else if (type.equals("setLanguage")) { ReadableType valueType = action.getType("value"); if (valueType.equals(ReadableType.Null)) { diff --git a/ios/RNBatch.mm b/ios/RNBatch.mm index c12c59c..5912db1 100644 --- a/ios/RNBatch.mm +++ b/ios/RNBatch.mm @@ -583,6 +583,19 @@ - (BatchEventAttributes*) convertSerializedEventDataToEventAttributes:(NSDiction } } + else if([type isEqualToString:@"setPhoneNumber"]) { + [editor setPhoneNumber:[self safeNilValue:action[@"value"]] error:nil]; + } + + else if([type isEqualToString:@"setSMSMarketingSubscription"]) { + NSString* value = action[@"value"]; + if([value isEqualToString:@"SUBSCRIBED"]) { + [editor setSMSMarketingSubscriptionState:BatchSMSSubscriptionStateSubscribed]; + } else if ([value isEqualToString:@"UNSUBSCRIBED"]) { + [editor setSMSMarketingSubscriptionState: BatchSMSSubscriptionStateUnsubscribed]; + } + } + else if([type isEqualToString:@"setLanguage"]) { [editor setLanguage:[self safeNilValue:action[@"value"]] error:nil]; } diff --git a/src/BatchProfileAttributeEditor.ts b/src/BatchProfileAttributeEditor.ts index 48039b1..27b6f1d 100644 --- a/src/BatchProfileAttributeEditor.ts +++ b/src/BatchProfileAttributeEditor.ts @@ -8,6 +8,14 @@ export enum BatchEmailSubscriptionState { UNSUBSCRIBED = 'UNSUBSCRIBED', } +/** + * Enum defining the state of an SMS subscription + */ +export enum BatchSMSSubscriptionState { + SUBSCRIBED = 'SUBSCRIBED', + UNSUBSCRIBED = 'UNSUBSCRIBED', +} + interface IUserSettingsSetAttributeAction { type: 'setAttribute'; key: string; @@ -51,6 +59,16 @@ interface IUserSettingsSetEmailMarketingSubscriptionAction { value: BatchEmailSubscriptionState; } +interface IUserSettingsSetPhoneNumberAction { + type: 'setPhoneNumber'; + value: string | null; +} + +interface IUserSettingsSetSMSMarketingSubscriptionAction { + type: 'setSMSMarketingSubscription'; + value: BatchSMSSubscriptionState; +} + interface IUserSettingsAddToArrayAction { type: 'addToArray'; key: string; @@ -73,7 +91,9 @@ type IUserSettingsAction = | IUserSettingsAddToArrayAction | IUserSettingsRemoveFromArrayAction | IUserSettingsSetEmailAddressAction - | IUserSettingsSetEmailMarketingSubscriptionAction; + | IUserSettingsSetEmailMarketingSubscriptionAction + | IUserSettingsSetPhoneNumberAction + | IUserSettingsSetSMSMarketingSubscriptionAction; type IUserSettingsActions = IUserSettingsAction[]; @@ -137,6 +157,20 @@ export class BatchProfileAttributeEditor { }); } + public setPhoneNumber(value: string | null): BatchProfileAttributeEditor { + return this.addAction({ + type: 'setPhoneNumber', + value, + }); + } + + public setSMSMarketingSubscription(value: BatchSMSSubscriptionState): BatchProfileAttributeEditor { + return this.addAction({ + type: 'setSMSMarketingSubscription', + value, + }); + } + public setLanguage(value: string | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setLanguage', From 669e81839632de37d2cd3d0fd2d5ca43a762684a Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Fri, 15 Nov 2024 15:18:08 +0100 Subject: [PATCH 3/4] all: update changelog --- CHANGELOG.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dca7a5..6bbde09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,20 @@ UPCOMING ---- **Plugin** - +* Updated Batch to 2.1 +* Batch requires iOS 13.0 or higher. +* Batch requires to compile with SDK 35 (Android 15). * Added support for React-Native [New Architecture](https://reactnative.dev/docs/the-new-architecture/landing-page) Turbo Module. This requires React-Native 0.71+ when running with new architecture enabled, as Codegen and Turbo Module are fully supported. Batch is still backwards compatible with legacy Native Modules. -**Push** +**Expo** +* Batch now automatically adds Apple push notification entitlement since it was removed from Expo SDK 51. +**Push** * Removed deprecated API `registerForRemoteNotifications`. Please use `requestNotificationAuthorization` to request permission when needed, and `requestToken` at each app launch. -**Expo** - -* Batch now automatically adds Apple push notification entitlement since it was removed from Expo SDK 51. +**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. 9.0.2 From 3435be69bec447445c4a22df7135835ecbf901dc Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Fri, 15 Nov 2024 15:33:19 +0100 Subject: [PATCH 4/4] profile: add tsdoc comments to batch profile attribute editor --- src/BatchProfileAttributeEditor.ts | 93 +++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/src/BatchProfileAttributeEditor.ts b/src/BatchProfileAttributeEditor.ts index 27b6f1d..0f145a9 100644 --- a/src/BatchProfileAttributeEditor.ts +++ b/src/BatchProfileAttributeEditor.ts @@ -98,7 +98,7 @@ type IUserSettingsAction = type IUserSettingsActions = IUserSettingsAction[]; /** - * Editor class used to create and save user tags and attributes + * Editor class used to create and save profile attributes */ export class BatchProfileAttributeEditor { private _settings: IUserSettingsActions; @@ -112,6 +112,12 @@ export class BatchProfileAttributeEditor { return this; } + /** + * 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. + * @param value Attribute value. Accepted types are strings, numbers, booleans and array of strings. + */ public setAttribute(key: string, value: string | boolean | number | string[] | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setAttribute', @@ -120,6 +126,19 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set a Date 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. + * @param value The date value + * + * Example: + * ```js + * // Set a date attribute with a timestamp + * BatchProfile.editor().setDateAttribute("birthday", new Date('July 20, 69 00:20:18 GMT+00:00').getTime()) + * ``` + */ public setDateAttribute(key: string, value: number): BatchProfileAttributeEditor { return this.addAction({ type: 'setDateAttribute', @@ -128,6 +147,19 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set an URL 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. + * @param value The URL value + * + * Example: + * ```js + * // set an url attribute + * BatchProfile.editor().setURLAttribute('website', 'https://example.com') + * ``` + */ public setURLAttribute(key: string, value: string): BatchProfileAttributeEditor { return this.addAction({ type: 'setURLAttribute', @@ -136,6 +168,10 @@ export class BatchProfileAttributeEditor { }); } + /** + * Remove an attribute + * @param key The key of the attribute to remove + */ public removeAttribute(key: string): BatchProfileAttributeEditor { return this.addAction({ type: 'removeAttribute', @@ -143,6 +179,13 @@ export class BatchProfileAttributeEditor { }); } + /** + * 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. + * @param value A valid email address. Null to erase. + */ public setEmailAddress(value: string | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setEmailAddress', @@ -150,6 +193,11 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set the profile email marketing subscription state + * + * @param value The state of the marketing email subscription. Must be "subscribed" or "unsubscribed". + */ public setEmailMarketingSubscription(value: BatchEmailSubscriptionState): BatchProfileAttributeEditor { return this.addAction({ type: 'setEmailMarketingSubscription', @@ -157,6 +205,13 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set the profile phone number. + * + * This requires to have a custom profile ID registered or to call the `identify` method beforehand. + * @param value 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. + */ public setPhoneNumber(value: string | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setPhoneNumber', @@ -164,6 +219,12 @@ export class 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 value The state of the SMS marketing subscription. Must be "subscribed" or "unsubscribed". + */ public setSMSMarketingSubscription(value: BatchSMSSubscriptionState): BatchProfileAttributeEditor { return this.addAction({ type: 'setSMSMarketingSubscription', @@ -171,6 +232,12 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set the application language. Overrides Batch's automatically detected language. + * + * Send null to let Batch autodetect it again. + * @param value Language code. 2 chars minimum, or null + */ public setLanguage(value: string | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setLanguage', @@ -178,6 +245,12 @@ export class BatchProfileAttributeEditor { }); } + /** + * Set the application region. Overrides Batch's automatically detected region. + * + * Send "null" to let Batch autodetect it again. + * @param value Region code. 2 chars minimum, or null + */ public setRegion(value: string | null): BatchProfileAttributeEditor { return this.addAction({ type: 'setRegion', @@ -185,6 +258,14 @@ export class BatchProfileAttributeEditor { }); } + /** + * Add value to an array attribute. If the array doesn't exist it will be created. + * + * @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. + * @param value The value to add. Cannot be null, undefined or empty. Must be an array of string or a string no longer + * than 64 characters. + */ public addToArray(key: string, value: string | string[]): BatchProfileAttributeEditor { return this.addAction({ type: 'addToArray', @@ -193,6 +274,13 @@ export class BatchProfileAttributeEditor { }); } + /** + * Remove a value from an array attribute. + * + * @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. + * @param value The value to remove. Can be a String or an Array of String. Cannot be null, empty or undefined. + */ public removeFromArray(key: string, value: string | string[]): BatchProfileAttributeEditor { return this.addAction({ type: 'removeFromArray', @@ -201,6 +289,9 @@ export class BatchProfileAttributeEditor { }); } + /** + * Save all the pending changes made in that editor. This action cannot be undone. + */ public save(): void { RNBatch.profile_saveEditor(this._settings); }