import { NativeEventEmitter, NativeModules, Platform, TurboModuleRegistry, } from 'react-native'; /* #region React Native setup */ const LINKING_ERROR = `The package '@devrev/sdk-react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n'; const DevRevNativeModule = (TurboModuleRegistry.get && TurboModuleRegistry.get('DevRevSDK')) || NativeModules.DevRevSDK; if (!DevRevNativeModule) { throw new Error(LINKING_ERROR); } const DevRev = DevRevNativeModule; /** * @deprecated The symbol `DevRevSDK` has been deprecated. Use `DevRev` instead. */ export const DevRevSDK = DevRev; const eventEmitter = new NativeEventEmitter(DevRev); /* #endregion */ /* #region Configuration */ import type { ArticleSearchFilter, ArticleSearchFilterOperand, ArticleSearchFilterOperandValue, ArticleSearchFilters, ConversationPageOptions, FeatureConfiguration, FilterOperator, FilterValueType, Identity, SupportWidgetTheme, UserTraits, OrganizationTraits, AccountTraits, } from './types'; export type { ArticleSearchFilter, ArticleSearchFilterOperand, ArticleSearchFilterOperandValue, ArticleSearchFilters, ConversationPageOptions, FeatureConfiguration, FilterOperator, FilterValueType, Identity, SupportWidgetTheme, UserTraits, OrganizationTraits, AccountTraits, }; let packageVersion = ''; try { packageVersion = require('../package.json').version; } catch { packageVersion = ''; } /** * Configures the SDK with the app ID and optional feature configuration. * * This is a mandatory method before using any other features. * * @param appID An identifier unique to your app. * @param featureConfiguration Optional feature configuration for the SDK. * * @category Configuration */ export function configure( appID: string, featureConfiguration?: FeatureConfiguration ): void { DevRev.configure(appID, packageVersion, featureConfiguration); } /** * Updates the feature configuration for the SDK. * * This method can be called after the SDK has been configured to update * the feature configuration. Pass a full feature configuration object. * * @param featureConfiguration The full feature configuration to apply. * * @category Configuration */ export function updateFeatureConfiguration( featureConfiguration: FeatureConfiguration ): void { DevRev.updateFeatureConfiguration(featureConfiguration); } /* #endregion */ /* #region Identification */ /** * Identifies a non-verified user after the SDK has been configured. * * The identification method should be called when you receive a callback or you have your user's data ready. * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @param userID - A string used to identify the user (can be an email). * @param organizationID - An optional unique identifier of the organization the user belongs to. * * @category Identification */ export function identifyUnverifiedUser( userID: string, organizationID?: string ) { DevRev.identifyUnverifiedUser(userID, organizationID); } /** * Identifies a verified user after the SDK has been configured. * * The verification process is done between your and DevRev's backend. * The identification method should be called when you receive a callback or you have your user's data ready. * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @param userID - A string used to identify the user (can be an email). * @param sessionToken - A session token generated by your backend. * * @category Identification */ export function identifyVerifiedUser(userID: string, sessionToken: string) { DevRev.identifyVerifiedUser(userID, sessionToken); } /** * Identifies an anonymous user after the SDK has been configured. * * The identification method should be called when you receive a callback or you have your user's data ready. * * @deprecated Use {@link identifyUnverifiedUser} instead: * ```ts * identifyUnverifiedUser(userId); * ``` * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @param userID - A string used to identify the user (can be an email). * * @category Identification */ export function identifyAnonymousUser(userID: string) { DevRev.identifyAnonymousUser(userID); } /** * Updates the user information with the provided identity. * * This method should be called to update the user's information after the SDK has been configured. * * @remarks * Make sure that you have called the `configure(appID)` method before. * The `userID` property can *not* be updated. * * @param identity - An object containing the user's identity information. * * @category Identification */ export function updateUser(identity: Identity) { DevRev.updateUser(identity); } /** * Logs out the current identified user and resets the session. * The process will also unregister the user's device from receiving push notifications, and stop any ongoing * session recording. * * @param deviceID - A unique device ID. This should be either an identifier **unique** to your system, or the app vendor * identifier i.e. Android ID (`Settings.Secure.ANDROID_ID`) for Android and IDFV (`UIDevice.identifierForVendor`) for iOS, * or Firebase installation ID. * * @see {@link https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor/ UIDevice.identifierForVendor} * @see {@link https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID Settings.Secure.ANDROID_ID} * @see {@link https://firebase.google.com/docs/projects/manage-installations#monitor-id-lifecycle Firebase installation ID} * * @category Identification */ export function logout(deviceID: string) { DevRev.logout(deviceID); } /* #endregion */ /* #region Support */ /** * Presents the support feature modally. * * @category Support */ export function showSupport() { DevRev.showSupport(); } /** * Creates a new support conversation and presents it modally. * * @param prefillMessage - An optional message to pre-fill in the conversation input. * * @category Support */ export function createSupportConversation(prefillMessage?: string) { DevRev.createSupportConversation(prefillMessage); } /* #endregion */ /* #region Analytics */ /** * Tracks an event with the given name and properties. * * This method should be called to log custom events in the application. * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @param name - The name of the event to be tracked. * @param properties - An object containing additional properties for the event. * * @category Analytics */ export function trackEvent( name: string, properties?: { [key: string]: string } ) { DevRev.trackEvent(name, properties); } /* #endregion */ /* #region Session recording */ /** * Starts a user session recording. * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @category Session recording */ export function startRecording() { DevRev.startRecording(); } /** * Stops an ongoing user recording sessions and uploads the session to the portal. * * @category Session recording */ export function stopRecording() { DevRev.stopRecording(); } /** * Pauses the ongoing user recording session. * * @category Session recording */ export function pauseRecording() { DevRev.pauseRecording(); } /** * Resumes a paused recording session. * * @category Session recording */ export function resumeRecording() { DevRev.resumeRecording(); } /** * Pauses user interaction tracking. * * @category Session recording */ export function pauseUserInteractionTracking() { DevRev.pauseUserInteractionTracking(); } /** * Resumes user interaction tracking. * * @category Session recording */ export function resumeUserInteractionTracking() { DevRev.resumeUserInteractionTracking(); } /* #endregion */ /* #region Session properties */ /** * Adds properties to the session. The properties will be sent along any analytic events. * * Any new properties in the map will be added to the session properties. If a property already exists, the * new value takes precedence and will override the existing value. * * @remarks * - Any date that would be a part of the properties map **should** be sent in the `YYYY/MM/DD` format. * - In cases when you want to clear out the stored session properties, you can call the `clearSessionProperties()` method. * * @param properties - A map of custom session properties. * * @category Session properties */ export function addSessionProperties(properties: { [key: string]: string }) { DevRev.addSessionProperties(properties); } /** * Clears the session properties. * * @category Session properties */ export function clearSessionProperties() { DevRev.clearSessionProperties(); } /* #endregion */ /* #region Sensitive field masking */ /** * Mark the passed view tags as sensitive. * * The views will be shown as masked in the portal playbacks. * * @param tags - An array of tags that should be masked. * * @category Sensitive field masking */ export function markSensitiveViews(tags: any[]) { DevRev.markSensitiveViews(tags); } /** * Unmark the passed view tags as being sensitive. * * They will no longer be shown as masked in the portal playbacks, unless they are auto masked. * * @param tags - An array of views you want to stop masking. * * @category Sensitive field masking */ export function unmarkSensitiveViews(tags: any[]) { DevRev.unmarkSensitiveViews(tags); } /* #endregion */ /* #region Timer control */ /** * Starts a timer at any point in the app in order to measure time metrics for events such as load or response time. * * This method needs to be balanced with an `endTimer(name, properties)` method call. * * @param name - A timer name. The timer name can have up to 250 characters. * @param properties - A property map. * * @category Timer control */ export function startTimer( name: string, properties: { [key: string]: string } ) { DevRev.startTimer(name, properties); } /** * Ends a previously started timer. * * This method will calculate the complete time from the start of the event. The method acts as a balanced call to * `startTimer(name, properties)`. * * @param name - A timer name. The timer name can have up to 250 characters. * @param properties - A property map. * * @category Timer control */ export function endTimer(name: string, properties: { [key: string]: string }) { DevRev.endTimer(name, properties); } /* #endregion */ /* #region Monitoring */ /** * Sets a flag that resumes the session monitoring. * * The main purpose of this method is to get the consent (opt-in) of the end-user that their session will be monitored * and data might be collected. * * @remarks * - The monitoring flag is **opt-in** by default. In case you want to opt-out of the automatic monitoring, * it is your responsibility to call the `stopAllMonitoring()` method at the place of your convenience. * - This method will only store a monitoring permission flag, it will **not** provide any UI or dialog. * The responsibility of implementing a UI is yours as a developer integrating the SDK. * * @see `stopAllMonitoring()` * * @category Monitoring */ export function resumeAllMonitoring() { DevRev.resumeAllMonitoring(); } /** * Sets a flag that stops all session monitoring. * * The method will revoke the consent given by the end-users for monitoring their sessions. * * @remarks * - The monitoring flag is **opt-in** by default. In case you want to opt-out of the automatic monitoring, * it is your responsibility to call the `stopAllMonitoring()` method at the place of your convenience. * - This method will only store a monitoring permission flag, it will **not** provide any UI or dialog. * The responsibility of implementing a UI is yours as a developer integrating the SDK. * * @see `resumeAllMonitoring()` * * @category Monitoring */ export function stopAllMonitoring() { DevRev.stopAllMonitoring(); } /* #endregion */ /* #region In-app link handling */ /** * Sets a flag that controls whether the modals should be dismissed after an in-app link is opened. * * @param value - A flag controling whether modals are dismissed when opening a link. * * @category In-app link handling */ export function setShouldDismissModalsOnOpenLink(value: boolean) { DevRev.setShouldDismissModalsOnOpenLink(value); } /* #endregion */ /* #region Dynamic theme configuration */ /** * Sets a flag uses the default theme for the support feature. * * @param value - A flag to enforce the preferred theme for the DevRev UI, overriding system theme when enabled. * * @category Dynamic theme configuration */ export function setPrefersSystemTheme(value: boolean) { DevRev.setPrefersSystemTheme(value); } /* #endregion */ /* #region Screen tracking */ /** * Manually tracks a screen name for identification. * * While view controllers are automatically defined as screens by the DevRev SDK, there might be cases when you need * to manually track certain screens. * This function allows you to manually track the screens that will be missed during the auto-capture process. * * @param name - A string value of the screen name. * * @deprecated This method is deprecated. Use `trackScreenName()` instead. * * @category Screen tracking */ export function trackScreen(name: string) { trackScreenName(name); } /** * Manually tracks a screen name for identification. * * While view controllers are automatically defined as screens by the DevRev SDK, there might be cases when you need * to manually track certain screens. * This function allows you to manually track the screens that will be missed during the auto-capture process. * * @param screenName - A string value of the screen name. * * @category Screen tracking */ export function trackScreenName(screenName: string) { DevRev.trackScreenName(screenName); } /* #endregion */ /* #region Push notifications */ /** * Registers the device token provided by the native platform for receiving push notifications from DevRev. * * @param deviceToken - The device token as provided by the native platform. * @param deviceID - A unique device ID. This should be either an identifier **unique** to your system, or the app vendor * identifier i.e. Android ID (`Settings.Secure.ANDROID_ID`) for Android and IDFV (`UIDevice.identifierForVendor`) for iOS, or Firebase installation ID. * * @see {@link https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor/ UIDevice.identifierForVendor} * @see {@link https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID Settings.Secure.ANDROID_ID} * @see {@link https://firebase.google.com/docs/projects/manage-installations#monitor-id-lifecycle Firebase installation ID} * * @category Push notifications */ export function registerDeviceToken(deviceToken: string, deviceID: string) { DevRev.registerDeviceToken(deviceToken, deviceID); } /** * Unregisters the device from receiving push notifications from DevRev. * * @param deviceID - A unique device ID. This should be either an identifier **unique** to your system, or the app vendor * identifier i.e. Android ID (`Settings.Secure.ANDROID_ID`) for Android and IDFV (`UIDevice.identifierForVendor`) for iOS, or Firebase installation ID. * * @see {@link https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor/ UIDevice.identifierForVendor} * @see {@link https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID Settings.Secure.ANDROID_ID} * @see {@link https://firebase.google.com/docs/projects/manage-installations#monitor-id-lifecycle Firebase installation ID} * * @category Push notifications */ export function unregisterDevice(deviceID: string) { DevRev.unregisterDevice(deviceID); } /** * Processes the push notification and performs the necessary actions. * * @param payload - The push notification JSON payload. * * @category Push notifications */ export function processPushNotification(payload: string) { DevRev.processPushNotification(payload); } /* #endregion */ /* #region Error capture */ /** * Captures an error with automatic stack trace extraction. * This is the recommended method for capturing errors - simply pass the error object and tag. * * The function automatically: * - Extracts the error message from Error objects or uses the string directly * - Extracts the stack trace from Error objects * - Passes everything to the native SDK which handles stack trace processing * * @param error - The error object (Error instance) or error message string * @param tag - Tag to categorize the exception (e.g., 'login-failure', 'api-error') * * @remarks * Make sure that you have called the `configure(appID)` method before. * * @category Error capture */ export function captureError(error: Error | string, tag: string) { const errorMessage = error instanceof Error ? error.message : String(error); const stackTrace = error instanceof Error ? error.stack : undefined; DevRev.captureError(errorMessage, tag, stackTrace); } /* #endregion */ /** * An optional in app links handler for external URLs, deeplinks, etc. in the PLuG support widget. * * @param handler: callback that receives URL */ export function setInAppLinkHandler(handler: (url: string) => void) { if (Platform.OS === 'android') { const subscription = eventEmitter.addListener( 'inAppLinkReceived', (event: { url: string }) => { handler(event.url); } ); DevRev.setInAppLinkHandler(); return () => { subscription.remove(); }; } console.warn('This function is not supported on iOS!'); return null; } /* #endregion */ /* #region Screen transition */ /** * Marks the beginning of a screen transition. * * This method should be called when a screen transition starts. It helps track UI navigation events * and ensures that relevant actions are delayed until the transition is complete. * * @remarks * - It is the developer's responsibility to call this method at the appropriate time in the navigation flow. * * @category Screen transition * * @deprecated This method is deprecated. Use `setInScreenTransitioning(true)` instead. */ export function startScreenTransition(): void { if (Platform.OS === 'android') { DevRev.setInScreenTransitioning(true); return; } console.warn('This function is not supported on iOS!'); } /** * Marks the end of a screen transition. * * This method should be called when a screen transition completes. It ensures that the application * can resume any actions that were delayed due to the transition. * * @remarks * - It is the developer's responsibility to call this method at the appropriate time in the navigation flow. * * @category Screen transition * * @deprecated This method is deprecated. Use `setInScreenTransitioning(false)` instead. */ export function endScreenTransition(): void { if (Platform.OS === 'android') { DevRev.setInScreenTransitioning(false); return; } console.warn('This function is not supported on iOS!'); } /** * Sets the screen transition state of the application. * * This method marks whether the application is currently undergoing a screen transition, * allowing event tracking and UI updates to be managed accordingly. * * @param inScreenTransitioning A boolean flag indicating if the screen is in transition. * * @category Screen Transition */ export function setInScreenTransitioning(value: boolean) { if (Platform.OS === 'android') { DevRev.setInScreenTransitioning(value); return; } console.warn('This function is not supported on iOS!'); } /* #endregion */ /* #region Session upload */ /** * Processes all on-demand sessions. * * This method triggers the processing of all on-demand sessions, ensuring that any recorded data * is handled appropriately. It is typically used when sessions need to be uploaded. * * @remarks * - It is the developer's responsibility to call this method at the appropriate time in the app's lifecycle. * * @category Session Upload */ export function processAllOnDemandSessions(): void { DevRev.processAllOnDemandSessions(); } /* #endregion */