npm package: @openforge/capacitor-bloomreach-engagement
Description: Capacitor plugin for Bloomreach Engagement (Exponea) SDK integration.
Author: OpenForge
Latest version: 1.0.2

<p align="center">
  <img src="https://github.com/openforge/main-website/blob/master/src/assets/logo-openforge.png?raw=true"/>
</p>
<p align="center">
  <a href="http://www.openforge.io/">Official Website</a> |
  <a href="http://www.openforge.io/opportunities">Opportunities</a> |
  <a href="https://www.facebook.com/openforgemobile/">Facebook</a>
</p>

<p align="center">
  Working with the latest technologies, designing the best products, and sharing our knowledge with the world wide community.
</p>

---

# Bloomreach Engagement Capacitor Plugin

Capacitor plugin for Bloomreach Engagement (formerly Exponea). Native Android/iOS only, with typed options and consent-gated tracking.

## Supported Platforms and Requirements

- iOS 15+ (CocoaPods)
- Android minSdk 22
- Java 21+ for Android builds (Capacitor 8 requirement)
- Capacitor peer dependency: `@capacitor/core` >=5 <9
- Web is not supported (calls reject with `SdkNotAvailable`)

## Install

```bash
npm install @openforge/capacitor-bloomreach-engagement
npx cap sync
```

## Quick Start (Recommended Wrapper)

Use the API wrapper for validation and consistent error handling.
Find your `projectToken`, `authorizationToken`, and `baseUrl` in Bloomreach Engagement: Project settings -> Access management -> API.

```ts
import { BloomreachEngagementApi } from '@openforge/capacitor-bloomreach-engagement';

await BloomreachEngagementApi.initialize({
  projectToken: 'PROJECT_TOKEN',
  authorizationToken: 'YOUR_API_TOKEN',
  baseUrl: 'https://api.exponea.com',
  // Optional native runtime controls (defaults keep v1.0.0 behavior).
  sdk: {
    automaticSessionTracking: false,
    automaticPushNotificationTracking: false,
    requirePushAuthorization: false,
    manualSessionAutoClose: true,
  },
  behavior: { rejectIfNoConsent: true },
  logging: { level: 'info' },
});

await BloomreachEngagementApi.setTrackingConsent({ granted: true });

await BloomreachEngagementApi.trackEvent({
  name: 'screen_view',
  properties: { screen: 'home' },
});
```

## Consent and Lifecycle Rules

- Call `setTrackingConsent({ granted: true })` before any tracking or push handling.
- Default behavior rejects tracking calls with `PermissionDenied` when consent is not granted.
- Set `behavior.rejectIfNoConsent = false` to convert those calls into no-ops.
- When consent is revoked, local customer data is cleared and the SDK is de-initialized.

## Native SDK Runtime Options

Configure native SDK behavior through `initialize({ sdk: ... })`:

- `sdk.automaticSessionTracking` (default: `false`)
- `sdk.automaticPushNotificationTracking` (default: `false`)
- `sdk.requirePushAuthorization` (default: `false`)
- `sdk.manualSessionAutoClose` (default: `true`)

These defaults preserve backward compatibility with this plugin's original behavior.
If you prefer Bloomreach SDK defaults, set:
`automaticSessionTracking: true`, `automaticPushNotificationTracking: true`, `requirePushAuthorization: true`, `manualSessionAutoClose: true`.

## Supported Features

| Feature                          | iOS | Android | Notes                                                |
| -------------------------------- | --- | ------- | ---------------------------------------------------- |
| Initialize SDK                   | Yes | Yes     | `initialize` must be called before tracking.         |
| Set tracking consent             | Yes | Yes     | Required for tracking calls.                         |
| Identify customer                | Yes | Yes     | Uses `customerIds` and optional `properties`.        |
| Track event                      | Yes | Yes     | Optional `properties` and `timestampMs`.             |
| Flush                            | Yes | Yes     | Sends queued events.                                 |
| Anonymize                        | Yes | Yes     | Clears local data.                                   |
| Request push permission          | Yes | Yes     | Android 13+ requires it, iOS supports `provisional`. |
| Push token registration          | Yes | Yes     | APNs on iOS; FCM/HMS on Android.                     |
| Push received/opened tracking    | Yes | Yes     | Host app forwards payloads.                          |
| Content blocks                   | Yes | No      | iOS only via `fetchContentBlock`.                    |
| In-app messages (fetch/show API) | No  | No      | Methods return `NotImplementedInThisSdkVersion`.     |

## Not Supported / Limitations

- Web platform is not supported.
- In-app message fetch/show APIs are not exposed by the public SDKs.
- Android content block fetch is not available in the public SDK API.

## iOS Setup

Minimum iOS deployment target is 15.0 (Capacitor 8 requirement).

1. Install pods:

```bash
npx cap sync ios
```

2. If you use a Notification Service Extension for rich push, add the pod to the extension target:

```ruby
pod 'ExponeaSDK-Notifications', '~> 3.9.0'
```

3. Provide `appGroup` in `initialize` so push-delivered tracking can share data across the extension.

## Android Setup

1. Ensure Google or Huawei push is integrated in your host app.
2. The host app is responsible for obtaining the FCM/HMS token and forwarding it to the plugin.
3. For Android 13+ notification permission, call `requestPushPermission` from your UI flow.

## Push Integration Responsibilities (Host App)

- Obtain the push token (APNs/FCM/HMS) and call `setPushToken`.
- Forward notification payloads to:
  - `handlePushReceived` when the notification is delivered.
  - `handlePushOpened` when the user opens the notification.
- The plugin does not display notifications; the host app decides how to present them.

## Angular Example (Typed Service Wrapper)

```ts
import { Injectable } from '@angular/core';
import {
  BloomreachEngagementApi,
  IdentifyCustomerOptions,
  TrackEventOptions,
} from '@openforge/capacitor-bloomreach-engagement';

@Injectable({ providedIn: 'root' })
export class BloomreachEngagementService {
  async initialize(): Promise<void> {
    await BloomreachEngagementApi.initialize({
      projectToken: 'PROJECT_TOKEN',
      authorizationToken: 'YOUR_API_TOKEN',
      baseUrl: 'https://api.exponea.com',
      behavior: { rejectIfNoConsent: true },
    });
  }

  async setConsent(granted: boolean): Promise<void> {
    await BloomreachEngagementApi.setTrackingConsent({ granted });
  }

  async identifyCustomer(options: IdentifyCustomerOptions): Promise<void> {
    await BloomreachEngagementApi.identifyCustomer(options);
  }

  async trackEvent(options: TrackEventOptions): Promise<void> {
    await BloomreachEngagementApi.trackEvent(options);
  }
}
```

## License

MIT