Skip to content

Commit c578308

Browse files
authored
Merge pull request #745 from Iterable/loren/embedded/MOB-12265-start-end-session
[MOB-12265] Configure start and end session
2 parents e0e83b2 + 433a089 commit c578308

File tree

10 files changed

+169
-3
lines changed

10 files changed

+169
-3
lines changed

android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,17 @@ public void onInboxUpdated() {
693693

694694
// ---------------------------------------------------------------------------------------
695695
// region Embedded messaging
696+
697+
public void startEmbeddedSession() {
698+
IterableLogger.d(TAG, "startEmbeddedSession");
699+
IterableApi.getInstance().getEmbeddedManager().getEmbeddedSessionManager().startSession();
700+
}
701+
702+
public void endEmbeddedSession() {
703+
IterableLogger.d(TAG, "endEmbeddedSession");
704+
IterableApi.getInstance().getEmbeddedManager().getEmbeddedSessionManager().endSession();
705+
}
706+
696707
public void getEmbeddedPlacementIds(Promise promise) {
697708
IterableLogger.d(TAG, "getEmbeddedPlacementIds");
698709
try {

android/src/newarch/java/com/RNIterableAPIModule.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,16 @@ public void pauseAuthRetries(boolean pauseRetry) {
224224
moduleImpl.pauseAuthRetries(pauseRetry);
225225
}
226226

227+
@Override
228+
public void startEmbeddedSession() {
229+
moduleImpl.startEmbeddedSession();
230+
}
231+
232+
@Override
233+
public void endEmbeddedSession() {
234+
moduleImpl.endEmbeddedSession();
235+
}
236+
227237
@Override
228238
public void getEmbeddedPlacementIds(Promise promise) {
229239
moduleImpl.getEmbeddedPlacementIds(promise);

android/src/oldarch/java/com/RNIterableAPIModule.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,16 @@ public void pauseAuthRetries(boolean pauseRetry) {
228228
moduleImpl.pauseAuthRetries(pauseRetry);
229229
}
230230

231+
@ReactMethod
232+
public void startEmbeddedSession() {
233+
moduleImpl.startEmbeddedSession();
234+
}
235+
236+
@ReactMethod
237+
public void endEmbeddedSession() {
238+
moduleImpl.endEmbeddedSession();
239+
}
240+
231241
@ReactMethod
232242
public void getEmbeddedPlacementIds(Promise promise) {
233243
moduleImpl.getEmbeddedPlacementIds(promise);

example/src/components/Embedded/Embedded.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ export const Embedded = () => {
1414
});
1515
}, []);
1616

17+
const startEmbeddedSession = useCallback(() => {
18+
console.log(
19+
'startEmbeddedSession --> check android/ios logs to check if it worked'
20+
);
21+
Iterable.embeddedManager.startSession();
22+
}, []);
23+
24+
const endEmbeddedSession = useCallback(() => {
25+
console.log(
26+
'endEmbeddedSession --> check android/ios logs to check if it worked'
27+
);
28+
Iterable.embeddedManager.endSession();
29+
}, []);
30+
1731
return (
1832
<SafeAreaView style={styles.container}>
1933
<Text style={styles.text}>EMBEDDED</Text>
@@ -30,6 +44,12 @@ export const Embedded = () => {
3044
<TouchableOpacity style={styles.button} onPress={getPlacementIds}>
3145
<Text style={styles.buttonText}>Get placement ids</Text>
3246
</TouchableOpacity>
47+
<TouchableOpacity style={styles.button} onPress={startEmbeddedSession}>
48+
<Text style={styles.buttonText}>Start embedded session</Text>
49+
</TouchableOpacity>
50+
<TouchableOpacity style={styles.button} onPress={endEmbeddedSession}>
51+
<Text style={styles.buttonText}>End embedded session</Text>
52+
</TouchableOpacity>
3353
</SafeAreaView>
3454
);
3555
};

example/src/hooks/useIterableApp.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export const IterableAppProvider: FunctionComponent<
125125
return jwtToken;
126126
}, [userId]);
127127

128-
const login = useCallback(() => {
128+
const login = useCallback(async () => {
129129
const id = userId ?? process.env.ITBL_ID;
130130

131131
if (!id) return Promise.reject('No User ID or Email set');
@@ -134,12 +134,18 @@ export const IterableAppProvider: FunctionComponent<
134134

135135
const fn = getIsEmail(id) ? Iterable.setEmail : Iterable.setUserId;
136136

137-
fn(id);
137+
let token;
138+
139+
if (process.env.ITBL_IS_JWT_ENABLED === 'true' && process.env.ITBL_JWT_SECRET) {
140+
token = await getJwtToken();
141+
}
142+
143+
fn(id, token);
138144
setIsLoggedIn(true);
139145
setLoginInProgress(false);
140146

141147
return Promise.resolve(true);
142-
}, [userId]);
148+
}, [getJwtToken, userId]);
143149

144150
const initialize = useCallback(
145151
(navigation: Navigation) => {

src/__mocks__/MockRNIterableAPI.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ export class MockRNIterableAPI {
141141

142142
static updateVisibleRows = jest.fn();
143143

144+
static startEmbeddedSession = jest.fn();
145+
146+
static endEmbeddedSession = jest.fn();
147+
148+
static getEmbeddedPlacementIds = jest
149+
.fn()
150+
.mockResolvedValue([1, 2, 3] as number[]);
151+
144152
// set messages function is to set the messages static property
145153
// this is for testing purposes only
146154
static setMessages(messages: IterableInAppMessage[]): void {

src/api/NativeRNIterableAPI.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ export interface Spec extends TurboModule {
119119
pauseAuthRetries(pauseRetry: boolean): void;
120120

121121
// Embedded Messaging
122+
startEmbeddedSession(): void;
123+
endEmbeddedSession(): void;
122124
getEmbeddedPlacementIds(): Promise<number[]>;
123125

124126
// Wake app -- android only

src/core/classes/IterableApi.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,22 @@ export class IterableApi {
510510
// ======================= EMBEDDED ===================== //
511511
// ====================================================== //
512512

513+
/**
514+
* Starts an embedded session.
515+
*/
516+
static startEmbeddedSession() {
517+
IterableLogger.log('startEmbeddedSession');
518+
return RNIterableAPI.startEmbeddedSession();
519+
}
520+
521+
/**
522+
* Ends an embedded session.
523+
*/
524+
static endEmbeddedSession() {
525+
IterableLogger.log('endEmbeddedSession');
526+
return RNIterableAPI.endEmbeddedSession();
527+
}
528+
513529
/**
514530
* Get the embedded placement IDs.
515531
*/

src/embedded/classes/IterableEmbeddedManager.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1+
import { MockRNIterableAPI } from '../../__mocks__/MockRNIterableAPI';
12
import { IterableEmbeddedManager } from './IterableEmbeddedManager';
23

4+
// Mock the RNIterableAPI module
5+
jest.mock('../../api', () => ({
6+
__esModule: true,
7+
default: MockRNIterableAPI,
8+
}));
9+
310
describe('IterableEmbeddedManager', () => {
411
let embeddedManager: IterableEmbeddedManager;
512

613
beforeEach(() => {
714
embeddedManager = new IterableEmbeddedManager();
15+
jest.clearAllMocks();
816
});
917

1018
describe('isEnabled', () => {
@@ -55,5 +63,40 @@ describe('IterableEmbeddedManager', () => {
5563
expect(embeddedManager.isEnabled).toBe(false);
5664
});
5765
});
66+
67+
describe('getPlacementIds', () => {
68+
it('should call IterableApi.getEmbeddedPlacementIds', async () => {
69+
// WHEN getPlacementIds is called
70+
const result = await embeddedManager.getPlacementIds();
71+
72+
// THEN IterableApi.getEmbeddedPlacementIds is called
73+
expect(MockRNIterableAPI.getEmbeddedPlacementIds).toHaveBeenCalledTimes(
74+
1
75+
);
76+
77+
// AND the result is returned
78+
expect(result).toEqual([1, 2, 3]);
79+
});
80+
});
81+
82+
describe('startSession', () => {
83+
it('should call IterableApi.startEmbeddedSession', () => {
84+
// WHEN startSession is called
85+
embeddedManager.startSession();
86+
87+
// THEN IterableApi.startEmbeddedSession is called
88+
expect(MockRNIterableAPI.startEmbeddedSession).toHaveBeenCalledTimes(1);
89+
});
90+
});
91+
92+
describe('endSession', () => {
93+
it('should call IterableApi.endEmbeddedSession', () => {
94+
// WHEN endSession is called
95+
embeddedManager.endSession();
96+
97+
// THEN IterableApi.endEmbeddedSession is called
98+
expect(MockRNIterableAPI.endEmbeddedSession).toHaveBeenCalledTimes(1);
99+
});
100+
});
58101
});
59102

src/embedded/classes/IterableEmbeddedManager.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { IterableApi } from '../../core/classes/IterableApi';
1414
export class IterableEmbeddedManager {
1515
/**
1616
* Whether the embedded manager is enabled.
17+
*
18+
* This is set through the `enableEmbeddedMessaging` flag in the
19+
* `IterableConfig` class.
1720
*/
1821
private _isEnabled = false;
1922

@@ -41,4 +44,41 @@ export class IterableEmbeddedManager {
4144
getPlacementIds() {
4245
return IterableApi.getEmbeddedPlacementIds();
4346
}
47+
48+
/**
49+
* Starts a session.
50+
*
51+
* As session is a period of time when a user is on a screen or page that can
52+
* display embedded messages.
53+
*
54+
* When a user comes to a screen or page in your app where embedded messages
55+
* are displayed (in one or more placements), a session should be started.
56+
*
57+
* @example
58+
* ```typescript
59+
* Iterable.embeddedManager.startSession();
60+
* ```
61+
*/
62+
startSession() {
63+
return IterableApi.startEmbeddedSession();
64+
}
65+
66+
/**
67+
* Ends a session.
68+
*
69+
* When a user leaves a screen in your app where embedded messages are
70+
* displayed, the session should be ended. This causes the SDK to send
71+
* session and impression data back to the server.
72+
*
73+
* A session is tracked when it is ended, so you should be able to find
74+
* tracking data after this method is called.
75+
*
76+
* @example
77+
* ```typescript
78+
* Iterable.embeddedManager.endSession();
79+
* ```
80+
*/
81+
endSession() {
82+
return IterableApi.endEmbeddedSession();
83+
}
4484
}

0 commit comments

Comments
 (0)