From b8875d7bf138ac62c03a2b898dc758193152d679 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Tue, 12 Nov 2024 11:04:09 +0100 Subject: [PATCH 1/5] all: bump batch to 2.1 --- dist/plugin.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/plugin.xml b/dist/plugin.xml index 2113401..de4da34 100755 --- a/dist/plugin.xml +++ b/dist/plugin.xml @@ -19,7 +19,7 @@ - + @@ -79,7 +79,7 @@ - + From c538ead912206cc3aabde787779ecbf7c3db3b65 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Tue, 12 Nov 2024 17:23:46 +0100 Subject: [PATCH 2/5] bridge: add phone number and sms subscription apis --- dist/src/android/interop/Bridge.java | 26 +++++++++++ dist/src/ios/interop/BatchProfileBridge.m | 14 ++++++ src/actions.ts | 2 + src/batchStub.ts | 7 ++- src/modules/profile/profileAttributeEditor.ts | 36 +++++++++++++++ types/index.d.ts | 45 +++++++++++++------ 6 files changed, 116 insertions(+), 14 deletions(-) diff --git a/dist/src/android/interop/Bridge.java b/dist/src/android/interop/Bridge.java index 2855d07..54e254b 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; @@ -410,6 +411,31 @@ private static void editProfileAttributes(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/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..cd4c9fa 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -62,6 +62,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..bffef6d 100644 --- a/src/batchStub.ts +++ b/src/batchStub.ts @@ -132,13 +132,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..249ad32 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/types/index.d.ts b/types/index.d.ts index 5acf331..901febc 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -146,11 +146,11 @@ 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. + * Even if you opt in afterward, data that has been generated while opted out WILL be lost. * * If you're also looking at deleting user data, please use batch.optOutAndWipeData() * @@ -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; @@ -417,8 +417,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 +658,7 @@ export declare namespace BatchSDK { } /** - * User data editor + * Profile attribute editor */ interface BatchProfileAttributeEditor { /** @@ -676,7 +676,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 +685,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 +693,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. From d17a5431628207d62f40f168a150a06b5f85e0cf Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Tue, 12 Nov 2024 17:47:08 +0100 Subject: [PATCH 3/5] all: update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e227f7c..e1433ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,16 @@ Batch Cordova Plugin ## UPCOMING +**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. ## 6.0.0 From 494735e6a326317a1b576470a4c1b55794546981 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Tue, 12 Nov 2024 17:57:39 +0100 Subject: [PATCH 4/5] all: lint fix --- src/modules/profile/profileAttributeEditor.ts | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/modules/profile/profileAttributeEditor.ts b/src/modules/profile/profileAttributeEditor.ts index 249ad32..32f6fc3 100644 --- a/src/modules/profile/profileAttributeEditor.ts +++ b/src/modules/profile/profileAttributeEditor.ts @@ -96,41 +96,41 @@ 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 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 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, From 652223088052f9f54f902b74ce2ae6f45ff64fd4 Mon Sep 17 00:00:00 2001 From: Arnaud Roland Date: Wed, 13 Nov 2024 15:46:39 +0100 Subject: [PATCH 5/5] fix: typo --- types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/index.d.ts b/types/index.d.ts index 901febc..541d6cf 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -150,7 +150,7 @@ export declare namespace BatchSDK { * - Make the SDK reject any editor calls * - Make the SDK reject calls to batch.profile.trackEvent(), batch.profile.trackLocation() and any related methods * - * Even if you opt in afterward, data that has been generated while opted out WILL be lost. + * Even if you opt in afterwards, data that has been generated while opted out WILL be lost. * * If you're also looking at deleting user data, please use batch.optOutAndWipeData() *