diff --git a/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java b/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java index b2114bd4..09d2af3e 100644 --- a/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java +++ b/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java @@ -10,6 +10,7 @@ public class IntercomErrorCodes { public static final String SET_LOG_LEVEL = "107"; public static final String GET_UNREAD_CONVERSATION = "108"; public static final String SET_USER_JWT = "109"; + public static final String INITIALIZE_ERROR = "110"; public static final String DISPLAY_MESSENGER = "201"; public static final String DISPLAY_MESSENGER_COMPOSER = "202"; public static final String DISPLAY_CONTENT = "203"; diff --git a/android/src/main/java/com/intercom/reactnative/IntercomModule.java b/android/src/main/java/com/intercom/reactnative/IntercomModule.java index a18736b5..252d0530 100644 --- a/android/src/main/java/com/intercom/reactnative/IntercomModule.java +++ b/android/src/main/java/com/intercom/reactnative/IntercomModule.java @@ -526,6 +526,24 @@ public void setUserJwt(String jwt, Promise promise) { } } + @ReactMethod + public void initialize(String apiKey, String appId, Promise promise) { + try { + Activity activity = getCurrentActivity(); + if (activity != null) { + Intercom.initialize(activity.getApplication(), apiKey, appId); + promise.resolve(true); + Log.d(NAME, "Intercom initialized with API key and App ID"); + } else { + promise.reject(IntercomErrorCodes.INITIALIZE_ERROR, "Activity is null"); + } + } catch (Exception err) { + Log.e(NAME, "initialize error:"); + Log.e(NAME, err.toString()); + promise.reject(IntercomErrorCodes.INITIALIZE_ERROR, err.toString()); + } + } + public static synchronized void initialize(Application application, String apiKey, String appId) { String sdkVersion = BuildConfig.INTERCOM_VERSION_NAME; ReactNativeHeaderInterceptor.setReactNativeVersion(application.getApplicationContext(), sdkVersion); diff --git a/ios/IntercomModule.m b/ios/IntercomModule.m index 49adc545..17d6c77b 100644 --- a/ios/IntercomModule.m +++ b/ios/IntercomModule.m @@ -16,6 +16,7 @@ @implementation IntercomModule NSString *LOG_EVENT = @"105"; NSString *UNREAD_CONVERSATION_COUNT = @"107"; NSString *SET_USER_JWT = @"109"; +NSString *INITIALIZE_ERROR = @"110"; NSString *SEND_TOKEN_TO_INTERCOM = @"302"; NSString *FETCH_HELP_CENTER_COLLECTIONS = @"901"; NSString *FETCH_HELP_CENTER_COLLECTION = @"902"; @@ -27,6 +28,20 @@ - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } +RCT_EXPORT_METHOD(initialize:(NSString *)apiKey + withAppId:(NSString *)appId + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { + @try { + [IntercomModule initialize:apiKey withAppId:appId]; + resolve(@(YES)); + NSLog(@"Intercom initialized with API key and App ID"); + } @catch (NSException *exception) { + NSLog(@"initialize error: %@", exception.reason); + reject(INITIALIZE_ERROR, @"Failed to initialize Intercom", nil); + } +} + + (void)initialize:(nonnull NSString *)apiKey withAppId:(nonnull NSString *)appId { NSString *version = @"0"; diff --git a/src/expo-plugins/@types.ts b/src/expo-plugins/@types.ts index cfdda924..849994c9 100644 --- a/src/expo-plugins/@types.ts +++ b/src/expo-plugins/@types.ts @@ -5,4 +5,5 @@ export type IntercomPluginProps = { androidApiKey: string; appId: string; intercomRegion?: IntercomRegion; + useManualInit?: boolean; }; diff --git a/src/expo-plugins/index.ts b/src/expo-plugins/index.ts index 4678818a..d1cb796b 100644 --- a/src/expo-plugins/index.ts +++ b/src/expo-plugins/index.ts @@ -37,13 +37,16 @@ const mainApplication: ConfigPlugin = (_config, props) => '' ); - stringContents = appendContentsInsideDeclarationBlock( - stringContents, - 'onCreate', - `IntercomModule.initialize(this, "${props.androidApiKey}", "${ - props.appId - }")${config.modResults.language === 'java' ? ';' : ''}\n` - ); + // Only auto-initialize if useManualInit is not true + if (!props.useManualInit) { + stringContents = appendContentsInsideDeclarationBlock( + stringContents, + 'onCreate', + `IntercomModule.initialize(this, "${props.androidApiKey}", "${ + props.appId + }")${config.modResults.language === 'java' ? ';' : ''}\n` + ); + } config.modResults.contents = stringContents; return config; @@ -116,19 +119,22 @@ const appDelegate: ConfigPlugin = (_config, props) => ) .replace(/\s*IntercomModule\.initialize\((.*), withAppId: (.*)\)/g, ''); - stringContents = isSwift - ? insertContentsInsideSwiftFunctionBlock( - stringContents, - 'application(_:didFinishLaunchingWithOptions:)', - `IntercomModule.initialize("${props.iosApiKey}", withAppId: "${props.appId}")`, - { position: 'tailBeforeLastReturn' } - ) - : insertContentsInsideObjcFunctionBlock( - stringContents, - 'application didFinishLaunchingWithOptions:', - `[IntercomModule initialize:@"${props.iosApiKey}" withAppId:@"${props.appId}"];`, - { position: 'tailBeforeLastReturn' } - ); + // Only auto-initialize if useManualInit is not true + if (!props.useManualInit) { + stringContents = isSwift + ? insertContentsInsideSwiftFunctionBlock( + stringContents, + 'application(_:didFinishLaunchingWithOptions:)', + `IntercomModule.initialize("${props.iosApiKey}", withAppId: "${props.appId}")`, + { position: 'tailBeforeLastReturn' } + ) + : insertContentsInsideObjcFunctionBlock( + stringContents, + 'application didFinishLaunchingWithOptions:', + `[IntercomModule initialize:@"${props.iosApiKey}" withAppId:@"${props.appId}"];`, + { position: 'tailBeforeLastReturn' } + ); + } config.modResults.contents = stringContents; return config; diff --git a/src/index.tsx b/src/index.tsx index 9b304c21..0fc3aa55 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -105,6 +105,16 @@ export enum Space { } export type IntercomType = { + /** + * Initialize Intercom SDK with API key and App ID. + * This allows manual initialization from React Native instead of requiring native code setup. + * + * @param apiKey Your Intercom API key + * @param appId Your Intercom App ID + * @return {Promise} A promise that resolves to true if initialization succeeds + */ + initialize: (apiKey: string, appId: string) => Promise; + /** * Login a unidentified user. * This is a user that doesn't have any identifiable information such as a `userId` or `email`. @@ -312,6 +322,7 @@ export type IntercomType = { }; const Intercom: IntercomType = { + initialize: (apiKey, appId) => IntercomModule.initialize(apiKey, appId), loginUnidentifiedUser: () => IntercomModule.loginUnidentifiedUser(), loginUserWithUserAttributes: (userAttributes) => IntercomModule.loginUserWithUserAttributes(userAttributes),