From 215ddb852e2fc3370152414f8c5036bdebfb8bd9 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Mon, 12 Jan 2026 17:58:47 -0800 Subject: [PATCH 1/5] feat: add embedded message update listener and callback support in Iterable API --- ios/RNIterableAPI/ReactIterableAPI.swift | 25 ++++++++++++++++++++++++ src/core/classes/Iterable.ts | 12 ++++++++++++ src/core/classes/IterableConfig.ts | 25 ++++++++++++++++++++++++ src/core/enums/IterableEventName.ts | 2 ++ 4 files changed, 64 insertions(+) diff --git a/ios/RNIterableAPI/ReactIterableAPI.swift b/ios/RNIterableAPI/ReactIterableAPI.swift index 798f37850..9849ab035 100644 --- a/ios/RNIterableAPI/ReactIterableAPI.swift +++ b/ios/RNIterableAPI/ReactIterableAPI.swift @@ -33,6 +33,7 @@ import React case receivedIterableInboxChanged case handleAuthSuccessCalled case handleAuthFailureCalled + case handleEmbeddedMessageUpdateCalled } @objc public static var supportedEvents: [String] { @@ -650,6 +651,13 @@ import React } IterableAPI.setDeviceAttribute(name: "reactNativeSDKVersion", value: version) + + // Add embedded update listener if callback is present + if let onEmbeddedMessageUpdatePresent = configDict["onEmbeddedMessageUpdatePresent"] as? Bool, + onEmbeddedMessageUpdatePresent == true + { + IterableAPI.embeddedManager.addUpdateListener(self) + } } } @@ -807,3 +815,20 @@ extension ReactIterableAPI: IterableAuthDelegate { public func onTokenRegistrationFailed(_ reason: String?) { } } + +extension ReactIterableAPI: IterableEmbeddedUpdateDelegate { + public func onMessagesUpdated() { + ITBInfo() + guard shouldEmit else { + return + } + delegate?.sendEvent( + withName: EventName.handleEmbeddedMessageUpdateCalled.rawValue, + body: nil as Any?) + } + + public func onEmbeddedMessagingDisabled() { + ITBInfo() + // This is called when embedded messaging is disabled, we don't need to do anything here for now + } +} diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index d9c98a572..000158d43 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -950,6 +950,9 @@ export class Iterable { RNEventEmitter.removeAllListeners( IterableEventName.handleAuthFailureCalled ); + RNEventEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); } /** @@ -1083,6 +1086,15 @@ export class Iterable { } ); } + + if (Iterable.savedConfig.onEmbeddedMessageUpdate) { + RNEventEmitter.addListener( + IterableEventName.handleEmbeddedMessageUpdateCalled, + () => { + Iterable.savedConfig.onEmbeddedMessageUpdate?.(); + } + ); + } } /** diff --git a/src/core/classes/IterableConfig.ts b/src/core/classes/IterableConfig.ts index aeebfb91e..82850ca91 100644 --- a/src/core/classes/IterableConfig.ts +++ b/src/core/classes/IterableConfig.ts @@ -339,6 +339,24 @@ export class IterableConfig { */ enableEmbeddedMessaging = false; + /** + * A callback function that is called when embedded messages are updated. + * + * This callback is triggered when the local cache of embedded messages changes, + * such as when new messages arrive or existing messages are removed. + * + * @example + * ```typescript + * const config = new IterableConfig(); + * config.onEmbeddedMessageUpdate = () => { + * console.log('Embedded messages updated!'); + * // Refresh your UI to display the latest messages + * }; + * Iterable.initialize('', config); + * ``` + */ + onEmbeddedMessageUpdate?: () => void; + /** * Converts the IterableConfig instance to a dictionary object. * @@ -377,6 +395,13 @@ export class IterableConfig { */ // eslint-disable-next-line eqeqeq authHandlerPresent: this.authHandler != undefined, + /** + * A boolean indicating if an embedded message update callback is present. + * + * TODO: Figure out if this is purposeful + */ + // eslint-disable-next-line eqeqeq + onEmbeddedMessageUpdatePresent: this.onEmbeddedMessageUpdate != undefined, /** The log level for the SDK. */ logLevel: this.logLevel, expiringAuthTokenRefreshPeriod: this.expiringAuthTokenRefreshPeriod, diff --git a/src/core/enums/IterableEventName.ts b/src/core/enums/IterableEventName.ts index 4a44cbb40..8dd3a9992 100644 --- a/src/core/enums/IterableEventName.ts +++ b/src/core/enums/IterableEventName.ts @@ -19,4 +19,6 @@ export enum IterableEventName { handleAuthSuccessCalled = 'handleAuthSuccessCalled', /** Event that fires when authentication with Iterable fails */ handleAuthFailureCalled = 'handleAuthFailureCalled', + /** Event that fires when embedded messages are updated */ + handleEmbeddedMessageUpdateCalled = 'handleEmbeddedMessageUpdateCalled', } From 66937c6aba9ea7f0f6eb5ebe250af6b7d63895e6 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 13 Jan 2026 12:22:15 -0800 Subject: [PATCH 2/5] feat: declare IterableEmbeddedUpdateDelegate protocol for embedded message updates --- ios/RNIterableAPI/RNIterableAPI.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/RNIterableAPI/RNIterableAPI.mm b/ios/RNIterableAPI/RNIterableAPI.mm index 131719043..2c6edda6a 100644 --- a/ios/RNIterableAPI/RNIterableAPI.mm +++ b/ios/RNIterableAPI/RNIterableAPI.mm @@ -13,6 +13,7 @@ @protocol IterableInAppDelegate; @protocol IterableCustomActionDelegate; @protocol IterableAuthDelegate; @protocol IterableURLDelegate; +@protocol IterableEmbeddedUpdateDelegate; typedef NS_ENUM(NSInteger, InAppShowResponse) { show = 0, skip = 1, From 9c4326a58f4cc24cd14a6253c486672895f75a17 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 13 Jan 2026 12:42:31 -0800 Subject: [PATCH 3/5] feat: add support for embedded messaging disabled callback and event handling --- ios/RNIterableAPI/ReactIterableAPI.swift | 21 ++++++++++++------- src/core/classes/Iterable.ts | 12 +++++++++++ src/core/classes/IterableConfig.ts | 26 ++++++++++++++++++++++++ src/core/enums/IterableEventName.ts | 2 ++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/ios/RNIterableAPI/ReactIterableAPI.swift b/ios/RNIterableAPI/ReactIterableAPI.swift index 9849ab035..bacbe3243 100644 --- a/ios/RNIterableAPI/ReactIterableAPI.swift +++ b/ios/RNIterableAPI/ReactIterableAPI.swift @@ -34,6 +34,7 @@ import React case handleAuthSuccessCalled case handleAuthFailureCalled case handleEmbeddedMessageUpdateCalled + case handleEmbeddedMessagingDisabledCalled } @objc public static var supportedEvents: [String] { @@ -651,11 +652,12 @@ import React } IterableAPI.setDeviceAttribute(name: "reactNativeSDKVersion", value: version) - - // Add embedded update listener if callback is present - if let onEmbeddedMessageUpdatePresent = configDict["onEmbeddedMessageUpdatePresent"] as? Bool, - onEmbeddedMessageUpdatePresent == true - { + + // Add embedded update listener if any callback is present + let onEmbeddedMessageUpdatePresent = configDict["onEmbeddedMessageUpdatePresent"] as? Bool ?? false + let onEmbeddedMessagingDisabledPresent = configDict["onEmbeddedMessagingDisabledPresent"] as? Bool ?? false + + if onEmbeddedMessageUpdatePresent || onEmbeddedMessagingDisabledPresent { IterableAPI.embeddedManager.addUpdateListener(self) } } @@ -826,9 +828,14 @@ extension ReactIterableAPI: IterableEmbeddedUpdateDelegate { withName: EventName.handleEmbeddedMessageUpdateCalled.rawValue, body: nil as Any?) } - + public func onEmbeddedMessagingDisabled() { ITBInfo() - // This is called when embedded messaging is disabled, we don't need to do anything here for now + guard shouldEmit else { + return + } + delegate?.sendEvent( + withName: EventName.handleEmbeddedMessagingDisabledCalled.rawValue, + body: nil as Any?) } } diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index 000158d43..099b43bf6 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -953,6 +953,9 @@ export class Iterable { RNEventEmitter.removeAllListeners( IterableEventName.handleEmbeddedMessageUpdateCalled ); + RNEventEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); } /** @@ -1095,6 +1098,15 @@ export class Iterable { } ); } + + if (Iterable.savedConfig.onEmbeddedMessagingDisabled) { + RNEventEmitter.addListener( + IterableEventName.handleEmbeddedMessagingDisabledCalled, + () => { + Iterable.savedConfig.onEmbeddedMessagingDisabled?.(); + } + ); + } } /** diff --git a/src/core/classes/IterableConfig.ts b/src/core/classes/IterableConfig.ts index 82850ca91..34befbbc8 100644 --- a/src/core/classes/IterableConfig.ts +++ b/src/core/classes/IterableConfig.ts @@ -357,6 +357,24 @@ export class IterableConfig { */ onEmbeddedMessageUpdate?: () => void; + /** + * A callback function that is called when embedded messaging is disabled. + * + * This callback is triggered when embedded messaging becomes unavailable, + * which can happen due to configuration issues or API errors. + * + * @example + * ```typescript + * const config = new IterableConfig(); + * config.onEmbeddedMessagingDisabled = () => { + * console.warn('Embedded messaging has been disabled'); + * // Hide embedded message UI or show error state + * }; + * Iterable.initialize('', config); + * ``` + */ + onEmbeddedMessagingDisabled?: () => void; + /** * Converts the IterableConfig instance to a dictionary object. * @@ -402,6 +420,14 @@ export class IterableConfig { */ // eslint-disable-next-line eqeqeq onEmbeddedMessageUpdatePresent: this.onEmbeddedMessageUpdate != undefined, + /** + * A boolean indicating if an embedded messaging disabled callback is present. + * + * TODO: Figure out if this is purposeful + */ + // eslint-disable-next-line eqeqeq + onEmbeddedMessagingDisabledPresent: + this.onEmbeddedMessagingDisabled != undefined, /** The log level for the SDK. */ logLevel: this.logLevel, expiringAuthTokenRefreshPeriod: this.expiringAuthTokenRefreshPeriod, diff --git a/src/core/enums/IterableEventName.ts b/src/core/enums/IterableEventName.ts index 8dd3a9992..6ea79c754 100644 --- a/src/core/enums/IterableEventName.ts +++ b/src/core/enums/IterableEventName.ts @@ -21,4 +21,6 @@ export enum IterableEventName { handleAuthFailureCalled = 'handleAuthFailureCalled', /** Event that fires when embedded messages are updated */ handleEmbeddedMessageUpdateCalled = 'handleEmbeddedMessageUpdateCalled', + /** Event that fires when embedded messaging is disabled */ + handleEmbeddedMessagingDisabledCalled = 'handleEmbeddedMessagingDisabledCalled', } From f155677f45b8e05d6cb361f40e02f30eba228128 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 13 Jan 2026 12:46:08 -0800 Subject: [PATCH 4/5] test: add unit tests for embedded messaging callbacks and their configuration flags --- src/core/classes/Iterable.test.ts | 226 ++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index b0a789f21..459cd2b8b 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -41,6 +41,12 @@ describe('Iterable', () => { nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); nativeEmitter.removeAllListeners(IterableEventName.handleAuthSuccessCalled); nativeEmitter.removeAllListeners(IterableEventName.handleAuthFailureCalled); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); // Clear any pending timers jest.clearAllTimers(); @@ -1229,4 +1235,224 @@ describe('Iterable', () => { expect(Iterable.embeddedManager.isEnabled).toBe(true); }); }); + + describe('embedded messaging callbacks', () => { + describe('onEmbeddedMessageUpdate', () => { + it('should call onEmbeddedMessageUpdate when handleEmbeddedMessageUpdateCalled event is emitted', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // sets up config file and onEmbeddedMessageUpdate callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + config.onEmbeddedMessageUpdate = jest.fn(); + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessageUpdateCalled event is emitted + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // THEN onEmbeddedMessageUpdate callback is called + expect(config.onEmbeddedMessageUpdate).toHaveBeenCalled(); + expect(config.onEmbeddedMessageUpdate).toHaveBeenCalledTimes(1); + }); + + it('should not set up listener if onEmbeddedMessageUpdate is not provided', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // sets up config without onEmbeddedMessageUpdate callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessageUpdateCalled event is emitted + // THEN no error should occur (no listener was set up) + expect(() => { + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + }).not.toThrow(); + }); + + it('should call onEmbeddedMessageUpdate multiple times when event is emitted multiple times', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // sets up config with callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + config.onEmbeddedMessageUpdate = jest.fn(); + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessageUpdateCalled event is emitted multiple times + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // THEN onEmbeddedMessageUpdate callback is called three times + expect(config.onEmbeddedMessageUpdate).toHaveBeenCalledTimes(3); + }); + + it('should include onEmbeddedMessageUpdatePresent flag in config dict when callback is provided', () => { + // GIVEN a config with onEmbeddedMessageUpdate callback + const config = new IterableConfig(); + config.onEmbeddedMessageUpdate = jest.fn(); + // WHEN toDict is called + const configDict = config.toDict(); + // THEN onEmbeddedMessageUpdatePresent is true + expect(configDict.onEmbeddedMessageUpdatePresent).toBe(true); + }); + + it('should set onEmbeddedMessageUpdatePresent flag to false when callback is not provided', () => { + // GIVEN a config without onEmbeddedMessageUpdate callback + const config = new IterableConfig(); + // WHEN toDict is called + const configDict = config.toDict(); + // THEN onEmbeddedMessageUpdatePresent is false + expect(configDict.onEmbeddedMessageUpdatePresent).toBe(false); + }); + }); + + describe('onEmbeddedMessagingDisabled', () => { + it('should call onEmbeddedMessagingDisabled when handleEmbeddedMessagingDisabledCalled event is emitted', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // sets up config file and onEmbeddedMessagingDisabled callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + config.onEmbeddedMessagingDisabled = jest.fn(); + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessagingDisabledCalled event is emitted + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // THEN onEmbeddedMessagingDisabled callback is called + expect(config.onEmbeddedMessagingDisabled).toHaveBeenCalled(); + expect(config.onEmbeddedMessagingDisabled).toHaveBeenCalledTimes(1); + }); + + it('should not set up listener if onEmbeddedMessagingDisabled is not provided', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // sets up config without onEmbeddedMessagingDisabled callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessagingDisabledCalled event is emitted + // THEN no error should occur (no listener was set up) + expect(() => { + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + }).not.toThrow(); + }); + + it('should call onEmbeddedMessagingDisabled when embedded messaging becomes unavailable', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // sets up config with callback + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + config.onEmbeddedMessagingDisabled = jest.fn(); + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessagingDisabledCalled event is emitted + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // THEN onEmbeddedMessagingDisabled callback is called + expect(config.onEmbeddedMessagingDisabled).toHaveBeenCalled(); + }); + + it('should include onEmbeddedMessagingDisabledPresent flag in config dict when callback is provided', () => { + // GIVEN a config with onEmbeddedMessagingDisabled callback + const config = new IterableConfig(); + config.onEmbeddedMessagingDisabled = jest.fn(); + // WHEN toDict is called + const configDict = config.toDict(); + // THEN onEmbeddedMessagingDisabledPresent is true + expect(configDict.onEmbeddedMessagingDisabledPresent).toBe(true); + }); + + it('should set onEmbeddedMessagingDisabledPresent flag to false when callback is not provided', () => { + // GIVEN a config without onEmbeddedMessagingDisabled callback + const config = new IterableConfig(); + // WHEN toDict is called + const configDict = config.toDict(); + // THEN onEmbeddedMessagingDisabledPresent is false + expect(configDict.onEmbeddedMessagingDisabledPresent).toBe(false); + }); + }); + + describe('both embedded callbacks', () => { + it('should call both callbacks independently when both are provided', () => { + // sets up event emitter + const nativeEmitter = new NativeEventEmitter(); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + nativeEmitter.removeAllListeners( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // sets up config with both callbacks + const config = new IterableConfig(); + config.logReactNativeSdkCalls = false; + config.onEmbeddedMessageUpdate = jest.fn(); + config.onEmbeddedMessagingDisabled = jest.fn(); + // initialize Iterable object + Iterable.initialize('apiKey', config); + // WHEN handleEmbeddedMessageUpdateCalled event is emitted + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessageUpdateCalled + ); + // THEN only onEmbeddedMessageUpdate is called + expect(config.onEmbeddedMessageUpdate).toHaveBeenCalled(); + expect(config.onEmbeddedMessagingDisabled).not.toHaveBeenCalled(); + // Reset mocks + jest.clearAllMocks(); + // WHEN handleEmbeddedMessagingDisabledCalled event is emitted + nativeEmitter.emit( + IterableEventName.handleEmbeddedMessagingDisabledCalled + ); + // THEN only onEmbeddedMessagingDisabled is called + expect(config.onEmbeddedMessagingDisabled).toHaveBeenCalled(); + expect(config.onEmbeddedMessageUpdate).not.toHaveBeenCalled(); + }); + + it('should set both presence flags in config dict when both callbacks are provided', () => { + // GIVEN a config with both callbacks + const config = new IterableConfig(); + config.onEmbeddedMessageUpdate = jest.fn(); + config.onEmbeddedMessagingDisabled = jest.fn(); + // WHEN toDict is called + const configDict = config.toDict(); + // THEN both presence flags are true + expect(configDict.onEmbeddedMessageUpdatePresent).toBe(true); + expect(configDict.onEmbeddedMessagingDisabledPresent).toBe(true); + }); + }); + }); }); From 2f480f0bb7971ec253f5bf3f3cc50be3a02b0292 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 13 Jan 2026 15:10:06 -0800 Subject: [PATCH 5/5] feat: implement embedded messaging update and disabled callbacks in Iterable configuration --- example/src/hooks/useIterableApp.tsx | 8 +++++++ src/core/classes/Iterable.ts | 32 +++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/example/src/hooks/useIterableApp.tsx b/example/src/hooks/useIterableApp.tsx index fdb156c21..ad574cdfb 100644 --- a/example/src/hooks/useIterableApp.tsx +++ b/example/src/hooks/useIterableApp.tsx @@ -200,6 +200,14 @@ export const IterableAppProvider: FunctionComponent< config.enableEmbeddedMessaging = true; + config.onEmbeddedMessageUpdate = () => { + console.log('onEmbeddedMessageUpdate'); + }; + + config.onEmbeddedMessagingDisabled = () => { + console.log('onEmbeddedMessagingDisabled'); + }; + config.inAppHandler = () => IterableInAppShowResponse.show; if ( diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index 099b43bf6..983fab49b 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -1090,22 +1090,24 @@ export class Iterable { ); } - if (Iterable.savedConfig.onEmbeddedMessageUpdate) { - RNEventEmitter.addListener( - IterableEventName.handleEmbeddedMessageUpdateCalled, - () => { - Iterable.savedConfig.onEmbeddedMessageUpdate?.(); - } - ); - } + if (Iterable.savedConfig.enableEmbeddedMessaging) { + if (Iterable.savedConfig.onEmbeddedMessageUpdate) { + RNEventEmitter.addListener( + IterableEventName.handleEmbeddedMessageUpdateCalled, + () => { + Iterable.savedConfig.onEmbeddedMessageUpdate?.(); + } + ); + } - if (Iterable.savedConfig.onEmbeddedMessagingDisabled) { - RNEventEmitter.addListener( - IterableEventName.handleEmbeddedMessagingDisabledCalled, - () => { - Iterable.savedConfig.onEmbeddedMessagingDisabled?.(); - } - ); + if (Iterable.savedConfig.onEmbeddedMessagingDisabled) { + RNEventEmitter.addListener( + IterableEventName.handleEmbeddedMessagingDisabledCalled, + () => { + Iterable.savedConfig.onEmbeddedMessagingDisabled?.(); + } + ); + } } }