diff --git a/README.md b/README.md index 7a80c73d..39dd3d79 100644 --- a/README.md +++ b/README.md @@ -383,7 +383,7 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau Intercom.setApiKey("", forAppId: "") .... } - + ``` #### iOS: Permissions @@ -1206,6 +1206,39 @@ This should be called before any user login takes place. --- +### `Intercom.setAuthTokens(authTokens)` + +Provide Intercom with your auth tokens which can be used for functionality such as Custom Actions with Data Connectors. You can provide multiple +tokens at once. To create tokens: +1. Go to Settings > Integrations > Authentication in your Intercom workspace +2. Create a new token with "User" type +3. Configure the token prefix and header as needed + +Learn more: https://www.intercom.com/help/en/articles/6615543-setting-up-data-connectors-authentication + +This should be called after any user login takes place. + +**Note:** This is separate from `setUserJwt()` which is for Messenger Security. `setAuthTokens()` passes JWT tokens to +Data Connectors (e.g., Fin Actions), which use these in `Authorization: Bearer ` headers for API requests. + +### Options + +| Name | Type | Required | Description | +| ---------- | ------------------------------- | -------- | --------------------------------------------------- | +| authTokens | `{ [key: string]: string }` | yes | An object with token names as keys and JWT strings as values | + +### Example + +```typescript +Intercom.setAuthTokens({ security_token: "jwt_here" }); +``` + +### Returns + +`Promise` + +--- + ## Author 👤 **Intercom (https://www.intercom.com/)** diff --git a/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java b/android/src/main/java/com/intercom/reactnative/IntercomErrorCodes.java index d5ae0a3d..831b0987 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 SET_AUTH_TOKENS = "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/IntercomHelpers.java b/android/src/main/java/com/intercom/reactnative/IntercomHelpers.java index 584754df..b40fa86f 100644 --- a/android/src/main/java/com/intercom/reactnative/IntercomHelpers.java +++ b/android/src/main/java/com/intercom/reactnative/IntercomHelpers.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; +import io.intercom.android.sdk.AuthToken; import io.intercom.android.sdk.Company; import io.intercom.android.sdk.Intercom; import io.intercom.android.sdk.UserAttributes; @@ -255,4 +256,23 @@ public static WritableMap deconstructRegistration(Registration registration) { } return registrationMap; } + + public static List buildAuthTokensList(ReadableMap readableMap) { + List authTokens = new ArrayList<>(); + ReadableMapKeySetIterator iterator = readableMap.keySetIterator(); + + while (iterator.hasNextKey()) { + String key = iterator.nextKey(); + ReadableType type = readableMap.getType(key); + + if (type == ReadableType.String) { + String value = readableMap.getString(key); + if (key != null && value != null && !key.isEmpty() && !value.isEmpty()) { + authTokens.add(new AuthToken(key, value)); + } + } + } + + return authTokens; + } } diff --git a/android/src/newarch/IntercomModule.java b/android/src/newarch/IntercomModule.java index 8b0edebb..6784ead3 100644 --- a/android/src/newarch/IntercomModule.java +++ b/android/src/newarch/IntercomModule.java @@ -603,6 +603,29 @@ public void setUserJwt(String jwt, Promise promise) { } } + @ReactMethod + public void setAuthTokens(ReadableMap authTokens, Promise promise) { + try { + List authTokensList = IntercomHelpers.buildAuthTokensList(authTokens); + Intercom.client().setAuthTokens(authTokensList, new IntercomStatusCallback() { + @Override + public void onSuccess() { + promise.resolve(true); + } + + @Override + public void onFailure(@NonNull IntercomError intercomError) { + Log.e("ERROR", intercomError.getErrorMessage()); + promise.reject(String.valueOf(intercomError.getErrorCode()), intercomError.getErrorMessage()); + } + }); + } catch (Exception err) { + Log.e(NAME, "setAuthTokens error:"); + Log.e(NAME, err.toString()); + promise.reject(IntercomErrorCodes.SET_AUTH_TOKENS, err.toString()); + } + } + @ReactMethod public void setNeedsStatusBarAppearanceUpdate(Promise promise) { // iOS-only method, no-op on Android diff --git a/android/src/oldarch/IntercomModule.java b/android/src/oldarch/IntercomModule.java index d36831c5..871b4ff8 100644 --- a/android/src/oldarch/IntercomModule.java +++ b/android/src/oldarch/IntercomModule.java @@ -580,6 +580,29 @@ public void setUserJwt(String jwt, Promise promise) { } } + @ReactMethod + public void setAuthTokens(ReadableMap authTokens, Promise promise) { + try { + List authTokensList = IntercomHelpers.buildAuthTokensList(authTokens); + Intercom.client().setAuthTokens(authTokensList, new IntercomStatusCallback() { + @Override + public void onSuccess() { + promise.resolve(true); + } + + @Override + public void onFailure(@NonNull IntercomError intercomError) { + Log.e("ERROR", intercomError.getErrorMessage()); + promise.reject(String.valueOf(intercomError.getErrorCode()), intercomError.getErrorMessage()); + } + }); + } catch (Exception err) { + Log.e(NAME, "setAuthTokens error:"); + Log.e(NAME, err.toString()); + promise.reject(IntercomErrorCodes.SET_AUTH_TOKENS, 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 6c5b0ab1..da8ba910 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 *SET_AUTH_TOKENS = @"110"; NSString *SEND_TOKEN_TO_INTERCOM = @"302"; NSString *FETCH_HELP_CENTER_COLLECTIONS = @"901"; NSString *FETCH_HELP_CENTER_COLLECTION = @"902"; @@ -331,6 +332,22 @@ - (NSData *)dataFromHexString:(NSString *)string { } }; +RCT_EXPORT_METHOD(setAuthTokens:(NSDictionary *)authTokens + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { + @try { + [Intercom setAuthTokens:authTokens + success:^{ + resolve(@(YES)); + } + failure:^(NSError * _Nonnull error) { + reject(SET_AUTH_TOKENS, @"Error in setAuthTokens", [self removeNullUnderlyingError:error]); + }]; + } @catch (NSException *exception) { + reject(SET_AUTH_TOKENS, @"Error in setAuthTokens", [self exceptionToError:exception :SET_AUTH_TOKENS :@"setAuthTokens"]); + } +}; + RCT_EXPORT_METHOD(setInAppMessageVisibility:(NSString *)visibility resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { diff --git a/src/NativeIntercomSpec.ts b/src/NativeIntercomSpec.ts index dcd6b799..22babe5f 100644 --- a/src/NativeIntercomSpec.ts +++ b/src/NativeIntercomSpec.ts @@ -84,6 +84,7 @@ export interface Spec extends TurboModule { setLogLevel(logLevel: string): Promise; setThemeMode(themeMode: string): Promise; setUserJwt(jwt: string): Promise; + setAuthTokens(authTokens: Object): Promise; } export default TurboModuleRegistry.getEnforcing('IntercomModule'); diff --git a/src/index.tsx b/src/index.tsx index a8d00f77..d74e62ec 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -277,6 +277,21 @@ export type IntercomType = { */ setUserJwt(jwt: string): Promise; + /** + * Provide Intercom with your auth tokens which can be used for functionality + * such as Custom Actions with Data Connectors. You can provide multiple tokens at once. To create tokens: + * 1. Go to Settings > Integrations > Authentication in your Intercom workspace + * 2. Create a new token with "User" type + * 3. Configure the token prefix and header as needed + * Learn more: https://www.intercom.com/help/en/articles/6615543-setting-up-data-connectors-authentication + * + * This should be called after any user login takes place. + * + * @param authTokens An object containing auth token names and values (e.g., { security_token: "jwt_here" }) + * @return {Promise} A promise that resolves to true on success. + */ + setAuthTokens(authTokens: { [key: string]: string }): Promise; + /** * [Android Only] Bootstrap event listeners for Android. Call this before setting up your own NativeEventEmitter * @@ -332,6 +347,7 @@ const Intercom: IntercomType = { setLogLevel: (logLevel) => IntercomModule.setLogLevel(logLevel), setThemeMode: (themeMode) => IntercomModule.setThemeMode(themeMode), setUserJwt: (jwt) => IntercomModule.setUserJwt(jwt), + setAuthTokens: (authTokens) => IntercomModule.setAuthTokens(authTokens), bootstrapEventListeners: () => { if (Platform.OS === 'android' && IntercomEventEmitter?.startEventListener) {