diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..dfa2771d --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +CLEVERTAP_ACCOUNT_ID=your_account_id_here +CLEVERTAP_ACCOUNT_TOKEN=your_token_here +CLEVERTAP_ACCOUNT_REGION=your_region_here # Optional +CLEVERTAP_HANDSHAKE_DOMAIN=your_handshake_domain_here # Optional \ No newline at end of file diff --git a/README.md b/README.md index 0bf5fce9..1e5a4f1a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + CleverTap Logo

# CleverTap Flutter SDK @@ -8,23 +8,23 @@ -## πŸ‘‹ Introduction +## Introduction The CleverTap Flutter SDK for Mobile Customer Engagement and Analytics solutions. -For more information check out our [website](https://clevertap.com/ "CleverTap") and [documentation](https://developer.clevertap.com/docs/ "CleverTap Technical Documentation"). +For more information, check out our [website](https://clevertap.com/) and [documentation](https://developer.clevertap.com/docs/). To get started, sign up [here](https://clevertap.com/live-product-demo/). -## πŸš€ Installation and Quick Start +## Installation and Quick Start - To add the **CleverTap Flutter SDK** to your project, edit your project's `pubspec.yaml` file: ```yaml dependencies: -clevertap_plugin: 3.2.0 + clevertap_plugin: 3.2.0 ``` -- Run `flutter packages get` to install the SDK +- Run `flutter packages get` to install the SDK. - Now, in your Dart code, you can use: @@ -32,24 +32,73 @@ clevertap_plugin: 3.2.0 import 'package:clevertap_plugin/clevertap_plugin.dart'; ``` -See our [Technical Documentation for Android](doc/Integrate-Android.md) and [Technical Documentation for iOS](doc/Integrate-iOS.md) for instructions on integrating CleverTap into your Flutter app. +### Initialize CleverTap -## πŸ“‘ Documentation & Example +You can initialize CleverTap using either: -- Checkout our [CleverTap Flutter Usage documentation](doc/Usage.md) -- Checkout our [Example Dart project](./example) +1. **Platform-specific configuration files (recommended):** + - Follow the instructions in [Technical Documentation for Android](doc/Integrate-Android.md) and [Technical Documentation for iOS](doc/Integrate-iOS.md) -## πŸ“² CleverTap Push Templates SDK (Available only for Android OS) -[(Back to top)](#-table-of-contents) +2. **Using environment variables:** + - Copy `.env.example` to `.env` in your project root: + ```bash + cp .env.example .env + ``` + - Update the `.env` file with your CleverTap credentials: + ``` + CLEVERTAP_ACCOUNT_ID=your_account_id_here + CLEVERTAP_ACCOUNT_TOKEN=your_token_here + CLEVERTAP_ACCOUNT_REGION=your_region_here # Optional + CLEVERTAP_HANDSHAKE_DOMAIN=your_domain_here # Optional + ``` -CleverTap Push Templates SDK helps you engage with your users using fancy push notification templates built specifically to work with [CleverTap](https://www.clevertap.com). -Find the integration steps for the CleverTap Push Templates SDK [here](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTPUSHTEMPLATES.md) +3. **Programmatically in your Flutter code:** + ```dart + await CleverTapPlugin.initialize( + accountId: 'YOUR_ACCOUNT_ID', + token: 'YOUR_ACCOUNT_TOKEN', + region: 'YOUR_REGION', // Optional + targetDomain: 'YOUR_DOMAIN' // Optional + ); + ``` -## πŸ†• Changelog +See our [Technical Documentation for Android](doc/Integrate-Android.md) and [Technical Documentation for iOS](doc/Integrate-iOS.md) for complete instructions on integrating CleverTap into your Flutter app. -Refer to the [CleverTap Flutter SDK Change Log](./CHANGELOG.md). +## Security Measures + +To ensure secure handling of CleverTap credentials and sensitive data, follow these best practices: + +- **Environment Variable Management:** + - Always add `.env` to your `.gitignore` to prevent accidental commits of sensitive credentials. + - Never store production credentials in the source code or version control. + - Use separate credentials for development, staging, and production environments. + +- **Secure Credential Handling:** + - Utilize secret management tools such as AWS Secrets Manager, Google Secret Manager, or environment variable injection via CI/CD pipelines. + - Ensure access to credentials is restricted to authorized team members only. + - Regularly rotate API keys and tokens to minimize security risks. + +- **CI/CD Pipeline Security:** + - Store secrets in a secure vault instead of hardcoding them in configuration files. + - Use least privilege access policies for CI/CD tools interacting with CleverTap. + - Monitor logs for unauthorized access attempts. + +By implementing these security practices, you can safeguard your application and user data. -## ❓Questions +## Documentation & Example + +- Check out our [CleverTap Flutter Usage documentation](doc/Usage.md). +- Check out our [Example Dart project](./example). + +## CleverTap Push Templates SDK (Available only for Android OS) + +CleverTap Push Templates SDK helps you engage with your users using dynamic push notification templates built specifically for [CleverTap](https://www.clevertap.com). +Find the integration steps for the CleverTap Push Templates SDK [here](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTPUSHTEMPLATES.md). + +## Changelog + +Refer to the [CleverTap Flutter SDK Change Log](./CHANGELOG.md). - If you have questions or concerns, you can reach out to the CleverTap support team from the CleverTap Dashboard. +## Questions +If you have questions or concerns, you can reach out to the CleverTap support team from the CleverTap Dashboard. diff --git a/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapApplication.java b/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapApplication.java index 57224a4e..0b2bdefd 100644 --- a/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapApplication.java +++ b/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapApplication.java @@ -16,6 +16,7 @@ public class CleverTapApplication extends Application implements CTPushNotificat @Override public void onCreate() { + ActivityLifecycleCallback.register(this); // Register ActivityLifecycleCallback automatically super.onCreate(); CleverTapAPI cleverTapAPI = CleverTapAPI.getDefaultInstance(this); if (cleverTapAPI != null) { diff --git a/android/src/main/java/com/clevertap/clevertap_plugin/DartToNativePlatformCommunicator.kt b/android/src/main/java/com/clevertap/clevertap_plugin/DartToNativePlatformCommunicator.kt index 479c8d1b..c2bf91fe 100644 --- a/android/src/main/java/com/clevertap/clevertap_plugin/DartToNativePlatformCommunicator.kt +++ b/android/src/main/java/com/clevertap/clevertap_plugin/DartToNativePlatformCommunicator.kt @@ -75,6 +75,9 @@ class DartToNativePlatformCommunicator( result: MethodChannel.Result ) { when (call.method) { + "initialize" -> { + initializeCleverTap(call = call, result = result) + } "startEmission" -> { startEmission(call = call, result = result) } @@ -2088,6 +2091,29 @@ class DartToNativePlatformCommunicator( } +private fun initializeCleverTap(call: MethodCall, result: MethodChannel.Result) { + val accountId = call.argument("accountId") + val token = call.argument("token") + val region = call.argument("region") + + if (accountId == null || token == null) { + result.error(TAG, "accountId and token are required for initialization", null) + return + } + + try { + val configMap = CleverTapAPI.getDefaultInstance(context)?.config + configMap?.let { + it.accountId = accountId + it.accountToken = token + region?.let { reg -> it.accountRegion = reg } + } + result.success(null) + } catch (e: Exception) { + result.error(TAG, "Failed to initialize CleverTap: ${e.message}", null) + } +} + private fun interface TemplateContextAction { fun execute(context: CustomTemplateContext): Any? } \ No newline at end of file diff --git a/doc/Integrate-Android.md b/doc/Integrate-Android.md index 832d9461..a3ec21b2 100644 --- a/doc/Integrate-Android.md +++ b/doc/Integrate-Android.md @@ -49,19 +49,6 @@ apply plugin: 'com.google.gms.google-services' //skip if not using FCM ``` -- In your app's Android Application class add the following code. - - ```java - public class MyApplication extends Application { - @java.lang.Override - public void onCreate() { - ActivityLifecycleCallback.register(this); //<--- Add this before super.onCreate() - super.onCreate(); - } - } - - ``` - #### Note - To use Header & Footer InApp Notification Templates of CleverTap, change the class from which MainActivity is inherited from `FlutterActivity` to `FlutterFragmentActivity` @@ -90,8 +77,8 @@ ``` -- Add your CleverTap Account ID and Token to your `AndroidManifest.xml`, within the tags. - +- Add your CleverTap Account ID and Token either: + 1. In your `AndroidManifest.xml`, within the tags: ```xml + ``` + 2. Or through environment variables in a .env file and initialize in your code: + ```dart + await CleverTapPlugin.initialize( + accountId: 'YOUR_ACCOUNT_ID', + token: 'YOUR_ACCOUNT_TOKEN', + region: 'YOUR_REGION', // Optional + targetDomain: 'YOUR_DOMAIN' // Optional + ); + ``` - - - - - - ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) - CleverTapAccountID - CLEVERTAP_ACCOUNT_ID - CleverTapToken - CLEVERTAP_ACCOUNT_TOKEN - CleverTapRegion - CLEVERTAP_ACCOUNT_REGION CleverTapUseIFA LSRequiresIPhoneOS diff --git a/example/lib/main.dart b/example/lib/main.dart index 8a11855e..1e66eb37 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -73,6 +73,14 @@ void main() async { CleverTapPlugin.onKilledStateNotificationClicked( onKilledStateNotificationClickedHandler); + // Initialize CleverTap with your credentials (Optional) + await CleverTapPlugin.initialize( + accountId: 'YOUR_ACCOUNT_ID', + token: 'YOUR_ACCOUNT_TOKEN', + region: 'YOUR_REGION', // Optional + targetDomain: 'YOUR_DOMAIN' // Optional + ); + print("CleverTapPlugin main pre runapp"); Future.delayed(Duration(seconds: TEST_RUN_APP_DELAY), () { @@ -122,7 +130,16 @@ class _MyAppState extends State { }); CleverTapPlugin.setDebugLevel(3); if (kIsWeb) { - CleverTapPlugin.init("CLEVERTAP_ACCOUNT_ID", "CLEVERTAP_REGION", "CLEVERTAP_TARGET_DOMAIN"); + // @deprecated Use initialize() method instead. This method will be removed in a future release. + // @deprecated: Use CleverTapPlugin.initialize() instead. + // Example of new initialization: + // await CleverTapPlugin.initialize( + // accountId: "CLEVERTAP_ACCOUNT_ID", + // token: "YOUR_ACCOUNT_TOKEN", + // region: "CLEVERTAP_REGION", + // targetDomain: "CLEVERTAP_TARGET_DOMAIN" + // ); + CleverTapPlugin.init("CLEVERTAP_ACCOUNT_ID", "CLEVERTAP_REGION", "CLEVERTAP_TARGET_DOMAIN"); // deprecated CleverTapPlugin.setDebugLevel(3); CleverTapPlugin.addKVDataChangeListener((obj) { var kv = obj["kv"]; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index fa2e2f89..ce043626 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -50,11 +50,6 @@ flutter: # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/ios/Classes/CleverTapPlugin.m b/ios/Classes/CleverTapPlugin.m index 15056606..773c552c 100644 --- a/ios/Classes/CleverTapPlugin.m +++ b/ios/Classes/CleverTapPlugin.m @@ -23,6 +23,35 @@ @interface CleverTapPlugin () initialize({ + required String accountId, + required String token, + String? region, + String? targetDomain, + }) async { + final initProps = { + 'accountId': accountId, + 'token': token, + 'region': region, + 'targetDomain': targetDomain, + }; + + if (kIsWeb) { + await _dartToNativeMethodChannel.invokeMethod('init', initProps); + } else { + await _dartToNativeMethodChannel.invokeMethod('initialize', initProps); + } + } + + /// Only for Web - Initialize clevertap sdk directly with parameters (legacy method) + @Deprecated('Use initialize() instead') static Future init(String accountId, [String? region, String? targetDomain, String? token]) async { if (!kIsWeb) {