diff --git a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java
index 1dedc7fbc..9c352093f 100644
--- a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java
+++ b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java
@@ -642,6 +642,17 @@ public void onInboxUpdated() {
// ---------------------------------------------------------------------------------------
// region Embedded messaging
+
+ public void startEmbeddedSession() {
+ IterableLogger.d(TAG, "startEmbeddedSession");
+ IterableApi.getInstance().getEmbeddedManager().getEmbeddedSessionManager().startSession();
+ }
+
+ public void endEmbeddedSession() {
+ IterableLogger.d(TAG, "endEmbeddedSession");
+ IterableApi.getInstance().getEmbeddedManager().getEmbeddedSessionManager().endSession();
+ }
+
public void getEmbeddedPlacementIds(Promise promise) {
IterableLogger.d(TAG, "getEmbeddedPlacementIds");
try {
diff --git a/android/src/newarch/java/com/RNIterableAPIModule.java b/android/src/newarch/java/com/RNIterableAPIModule.java
index 50e814f0b..4c67af4e5 100644
--- a/android/src/newarch/java/com/RNIterableAPIModule.java
+++ b/android/src/newarch/java/com/RNIterableAPIModule.java
@@ -224,6 +224,16 @@ public void pauseAuthRetries(boolean pauseRetry) {
moduleImpl.pauseAuthRetries(pauseRetry);
}
+ @Override
+ public void startEmbeddedSession() {
+ moduleImpl.startEmbeddedSession();
+ }
+
+ @Override
+ public void endEmbeddedSession() {
+ moduleImpl.endEmbeddedSession();
+ }
+
@Override
public void getEmbeddedPlacementIds(Promise promise) {
moduleImpl.getEmbeddedPlacementIds(promise);
diff --git a/android/src/oldarch/java/com/RNIterableAPIModule.java b/android/src/oldarch/java/com/RNIterableAPIModule.java
index 4555fd71b..868f4051d 100644
--- a/android/src/oldarch/java/com/RNIterableAPIModule.java
+++ b/android/src/oldarch/java/com/RNIterableAPIModule.java
@@ -228,6 +228,16 @@ public void pauseAuthRetries(boolean pauseRetry) {
moduleImpl.pauseAuthRetries(pauseRetry);
}
+ @ReactMethod
+ public void startEmbeddedSession() {
+ moduleImpl.startEmbeddedSession();
+ }
+
+ @ReactMethod
+ public void endEmbeddedSession() {
+ moduleImpl.endEmbeddedSession();
+ }
+
@ReactMethod
public void getEmbeddedPlacementIds(Promise promise) {
moduleImpl.getEmbeddedPlacementIds(promise);
diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx
index 1fa87ae5c..cf46ed730 100644
--- a/example/src/components/Embedded/Embedded.tsx
+++ b/example/src/components/Embedded/Embedded.tsx
@@ -14,6 +14,20 @@ export const Embedded = () => {
});
}, []);
+ const startEmbeddedSession = useCallback(() => {
+ console.log(
+ 'startEmbeddedSession --> check android/ios logs to check if it worked'
+ );
+ Iterable.embeddedManager.startSession();
+ }, []);
+
+ const endEmbeddedSession = useCallback(() => {
+ console.log(
+ 'endEmbeddedSession --> check android/ios logs to check if it worked'
+ );
+ Iterable.embeddedManager.endSession();
+ }, []);
+
return (
EMBEDDED
@@ -30,6 +44,12 @@ export const Embedded = () => {
Get placement ids
+
+ Start embedded session
+
+
+ End embedded session
+
);
};
diff --git a/example/src/hooks/useIterableApp.tsx b/example/src/hooks/useIterableApp.tsx
index 53de3d126..2a392dd0d 100644
--- a/example/src/hooks/useIterableApp.tsx
+++ b/example/src/hooks/useIterableApp.tsx
@@ -123,7 +123,7 @@ export const IterableAppProvider: FunctionComponent<
return jwtToken;
}, [userId]);
- const login = useCallback(() => {
+ const login = useCallback(async () => {
const id = userId ?? process.env.ITBL_ID;
if (!id) return Promise.reject('No User ID or Email set');
@@ -132,12 +132,18 @@ export const IterableAppProvider: FunctionComponent<
const fn = getIsEmail(id) ? Iterable.setEmail : Iterable.setUserId;
- fn(id);
+ let token;
+
+ if (process.env.ITBL_IS_JWT_ENABLED === 'true' && process.env.ITBL_JWT_SECRET) {
+ token = await getJwtToken();
+ }
+
+ fn(id, token);
setIsLoggedIn(true);
setLoginInProgress(false);
return Promise.resolve(true);
- }, [userId]);
+ }, [getJwtToken, userId]);
const initialize = useCallback(
(navigation: Navigation) => {
diff --git a/src/__mocks__/MockRNIterableAPI.ts b/src/__mocks__/MockRNIterableAPI.ts
index c7f325677..fc7ed502f 100644
--- a/src/__mocks__/MockRNIterableAPI.ts
+++ b/src/__mocks__/MockRNIterableAPI.ts
@@ -129,6 +129,14 @@ export class MockRNIterableAPI {
static getHtmlInAppContentForMessage = jest.fn();
+ static startEmbeddedSession = jest.fn();
+
+ static endEmbeddedSession = jest.fn();
+
+ static getEmbeddedPlacementIds = jest
+ .fn()
+ .mockResolvedValue([1, 2, 3] as number[]);
+
// set messages function is to set the messages static property
// this is for testing purposes only
static setMessages(messages: IterableInAppMessage[]): void {
diff --git a/src/api/NativeRNIterableAPI.ts b/src/api/NativeRNIterableAPI.ts
index 9dd2af2b7..931be6f29 100644
--- a/src/api/NativeRNIterableAPI.ts
+++ b/src/api/NativeRNIterableAPI.ts
@@ -119,6 +119,8 @@ export interface Spec extends TurboModule {
pauseAuthRetries(pauseRetry: boolean): void;
// Embedded Messaging
+ startEmbeddedSession(): void;
+ endEmbeddedSession(): void;
getEmbeddedPlacementIds(): Promise;
// Wake app -- android only
diff --git a/src/core/classes/IterableApi.ts b/src/core/classes/IterableApi.ts
index 9825f42ae..84c8f3a7a 100644
--- a/src/core/classes/IterableApi.ts
+++ b/src/core/classes/IterableApi.ts
@@ -510,6 +510,22 @@ export class IterableApi {
// ======================= EMBEDDED ===================== //
// ====================================================== //
+ /**
+ * Starts an embedded session.
+ */
+ static startEmbeddedSession() {
+ IterableLogger.log('startEmbeddedSession');
+ return RNIterableAPI.startEmbeddedSession();
+ }
+
+ /**
+ * Ends an embedded session.
+ */
+ static endEmbeddedSession() {
+ IterableLogger.log('endEmbeddedSession');
+ return RNIterableAPI.endEmbeddedSession();
+ }
+
/**
* Get the embedded placement IDs.
*/
diff --git a/src/embedded/classes/IterableEmbeddedManager.test.ts b/src/embedded/classes/IterableEmbeddedManager.test.ts
index 96a09ddf4..c05e38533 100644
--- a/src/embedded/classes/IterableEmbeddedManager.test.ts
+++ b/src/embedded/classes/IterableEmbeddedManager.test.ts
@@ -1,10 +1,18 @@
+import { MockRNIterableAPI } from '../../__mocks__/MockRNIterableAPI';
import { IterableEmbeddedManager } from './IterableEmbeddedManager';
+// Mock the RNIterableAPI module
+jest.mock('../../api', () => ({
+ __esModule: true,
+ default: MockRNIterableAPI,
+}));
+
describe('IterableEmbeddedManager', () => {
let embeddedManager: IterableEmbeddedManager;
beforeEach(() => {
embeddedManager = new IterableEmbeddedManager();
+ jest.clearAllMocks();
});
describe('isEnabled', () => {
@@ -55,5 +63,40 @@ describe('IterableEmbeddedManager', () => {
expect(embeddedManager.isEnabled).toBe(false);
});
});
+
+ describe('getPlacementIds', () => {
+ it('should call IterableApi.getEmbeddedPlacementIds', async () => {
+ // WHEN getPlacementIds is called
+ const result = await embeddedManager.getPlacementIds();
+
+ // THEN IterableApi.getEmbeddedPlacementIds is called
+ expect(MockRNIterableAPI.getEmbeddedPlacementIds).toHaveBeenCalledTimes(
+ 1
+ );
+
+ // AND the result is returned
+ expect(result).toEqual([1, 2, 3]);
+ });
+ });
+
+ describe('startSession', () => {
+ it('should call IterableApi.startEmbeddedSession', () => {
+ // WHEN startSession is called
+ embeddedManager.startSession();
+
+ // THEN IterableApi.startEmbeddedSession is called
+ expect(MockRNIterableAPI.startEmbeddedSession).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('endSession', () => {
+ it('should call IterableApi.endEmbeddedSession', () => {
+ // WHEN endSession is called
+ embeddedManager.endSession();
+
+ // THEN IterableApi.endEmbeddedSession is called
+ expect(MockRNIterableAPI.endEmbeddedSession).toHaveBeenCalledTimes(1);
+ });
+ });
});
diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts
index 879ed6199..d36d11885 100644
--- a/src/embedded/classes/IterableEmbeddedManager.ts
+++ b/src/embedded/classes/IterableEmbeddedManager.ts
@@ -14,6 +14,9 @@ import { IterableApi } from '../../core/classes/IterableApi';
export class IterableEmbeddedManager {
/**
* Whether the embedded manager is enabled.
+ *
+ * This is set through the `enableEmbeddedMessaging` flag in the
+ * `IterableConfig` class.
*/
private _isEnabled = false;
@@ -41,4 +44,41 @@ export class IterableEmbeddedManager {
getPlacementIds() {
return IterableApi.getEmbeddedPlacementIds();
}
+
+ /**
+ * Starts a session.
+ *
+ * As session is a period of time when a user is on a screen or page that can
+ * display embedded messages.
+ *
+ * When a user comes to a screen or page in your app where embedded messages
+ * are displayed (in one or more placements), a session should be started.
+ *
+ * @example
+ * ```typescript
+ * Iterable.embeddedManager.startSession();
+ * ```
+ */
+ startSession() {
+ return IterableApi.startEmbeddedSession();
+ }
+
+ /**
+ * Ends a session.
+ *
+ * When a user leaves a screen in your app where embedded messages are
+ * displayed, the session should be ended. This causes the SDK to send
+ * session and impression data back to the server.
+ *
+ * A session is tracked when it is ended, so you should be able to find
+ * tracking data after this method is called.
+ *
+ * @example
+ * ```typescript
+ * Iterable.embeddedManager.endSession();
+ * ```
+ */
+ endSession() {
+ return IterableApi.endEmbeddedSession();
+ }
}