Skip to main content

Installing SCC-AC in Your Salesforce Organization

  1. Installing managed package:

    1. Search for Partner Telephony Setup in Quick Find. Choose No. 6 (Set Up More Amazon Connect Features), Choose Install button in Install Managed Package section, and then Install for all users.

      Note: Install for all users is required to make sure all user profiles have access to SCCAC Apex classes.

      Note: To upgrade the SCC-AC package to a newer version in the future, see Updating SCC-AC.

  2. To clone permission sets:

    1. In Salesforce Setup, search for Permission Sets in Quick Find.
    2. Clone SCC Administrator Placeholder and rename Label to SCC Administrator and API Name to SCC_Administrator. Choose Save. Configure SCC_Administrator access to all SCCAC Apex classes by following Salesforce guidance if Install for all users was not selected in the Installing managed package step above.
    3. Clone SCC Agent Placeholder, and rename Label to SCC Agent and API Name to SCC_Agent. Choose Save. Configure SCC_Agent access to the following Apex classes by following Salesforce guidance if Install for all users was not selected in the Installing managed package step above.

    1. Note: If you are using profile which is less privileged than Salesforce provided “Standard User” profile, follow this step to insure user has required permissions. For each of the newly cloned permission sets, go to System Permissions. Enable the API Enabled, Create Public Links, Customize Application, Lightning Experience User, Manage Custom Permissions, View Roles and Role Hierarchy, and View Setup and Configuration permissions.
  3. To assign an SCC-AC related permission set to a user:

    1. Go to Users, choose a user’s name, hover over Permission Set Assignments and choose Edit Assignments. Select required permission set in the Available Permission Sets column, and choose the right arrow Add to move it to the Enabled Permission Sets column. Choose Save.
      1. For SCCAC Administrator the permission set is SCC Administrator.
      2. For SCCAC Agent the permission set is SCC Agent.
  4. To create the connected app or external client app:

    Note: Use Option A (External Client App) for all new installations on Salesforce orgs running Spring '24 or later (API v59.0+). Use Option B (Connected App) only if you have an existing Connected App installation that you have not yet migrated to an External Client App. To move an existing Connected App installation to an External Client App, see Migrating to External Client App (ECA).


    Option A — External Client App (recommended for new installations, Spring '24+)

    1. Log in as SCCAC Administrator user.
    2. Run the following code in an Anonymous window (Developer Console → Debug → Open Execute Anonymous Window). Be sure to replace email@email.com with your email address.
      String generateUniqueConsumerKey(Integer length) {
      String charset =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
      'abcdefghijklmnopqrstuvwxyz0123456789';
      String timestamp = String.valueOf(System.currentTimeMillis());

      Integer remainingLength = length - timestamp.length();

      if (remainingLength <= 0) {
      return timestamp.substring(0, length);
      }

      String randomPart = '';
      for (Integer i = 0; i < remainingLength; i++) {
      Integer randomIndex =
      (Integer)Math.floor(Math.random() * charset.length());
      randomPart += charset.substring(randomIndex, randomIndex + 1);
      }

      return timestamp + randomPart;
      }

      String createCertificate() {
      awsac.SCCMetaDataService.MetadataPort service =
      new awsac.SCCMetaDataService.MetadataPort();
      service.SessionHeader =
      new awsac.SCCMetaDataService.SessionHeader_element();
      service.SessionHeader.sessionId = UserInfo.getSessionId();
      awsac.SCCMetaDataService.SaveResult createMetaDataResult =
      new awsac.SCCMetaDataService.SaveResult();
      awsac.SCCMetaDataService.Certificate certificate =
      new awsac.SCCMetaDataService.Certificate();
      certificate.fullName =
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL;
      certificate.caSigned = false;
      certificate.encryptedWithPlatformEncryption = false;
      certificate.keySize = 2048;
      certificate.masterLabel =
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL;
      certificate.privateKeyExportable = true;
      createMetaDataResult = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{certificate})
      .get(0);
      if (!createMetaDataResult.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error :
      createMetaDataResult.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(errorMessage);
      }
      awsac.SCCMetaDataService.IReadResult readMetaDataResult = null;
      readMetaDataResult = service.readMetadata('Certificate',
      new String[] {
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL
      });
      awsac.SCCMetaDataService.Certificate cert =
      (awsac.SCCMetaDataService.Certificate) readMetaDataResult
      .getRecords()[0];
      Blob certificateBlob = EncodingUtil.base64Decode(cert.content);
      return certificateBlob.toString();
      }

      void createExternalClientApp(String adminEmail) {
      awsac.SCCMetaDataService.MetadataPort service =
      new awsac.SCCMetaDataService.MetadataPort();
      service.SessionHeader =
      new awsac.SCCMetaDataService.SessionHeader_element();
      service.SessionHeader.sessionId = UserInfo.getSessionId();
      awsac.SCCMetaDataService.SaveResult result =
      new awsac.SCCMetaDataService.SaveResult();
      String ecaFullName = awsac.SCCConstants.GLOBAL_EXTERNAL_CLIENT_APP_FULL_NAME;

      // Step 1: Create the External Client Application header record
      awsac.SCCACECAMetaDataService.ExternalClientApplication eca =
      new awsac.SCCACECAMetaDataService.ExternalClientApplication();
      eca.fullName = ecaFullName;
      eca.label = awsac.SCCConstants.GLOBAL_EXTERNAL_CLIENT_APP_LABEL;
      eca.description = 'External Client App to access Interaction Service APIs';
      eca.contactEmail = adminEmail;
      result = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{eca}).get(0);
      if (!result.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error : result.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(
      'Failed to create External Client Application: ' + errorMessage);
      }

      // Step 2: Create OAuth functional settings — scopes and callback URL
      awsac.SCCACECAMetaDataService.ExtlClntAppOauthSettings oauthSettings =
      new awsac.SCCACECAMetaDataService.ExtlClntAppOauthSettings();
      oauthSettings.fullName = ecaFullName;
      oauthSettings.externalClientApplication = ecaFullName;
      oauthSettings.commaSeparatedOauthScopes = 'Api,Basic,RefreshToken,Interaction';
      result = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{oauthSettings}).get(0);
      if (!result.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error : result.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(
      'Failed to create ECA OAuth settings: ' + errorMessage);
      }

      // Step 3: Create OAuth global settings — consumer key and secret
      awsac.SCCACECAMetaDataService.ExtlClntAppGlobalOauthSettings oauthGlobalSettings =
      new awsac.SCCACECAMetaDataService.ExtlClntAppGlobalOauthSettings();
      oauthGlobalSettings.fullName = ecaFullName;
      oauthGlobalSettings.externalClientApplication = ecaFullName;
      oauthGlobalSettings.callbackUrl = 'https://salesforce.com';
      oauthGlobalSettings.certificate = createCertificate();
      oauthGlobalSettings.consumerKey = generateUniqueConsumerKey(64);
      oauthGlobalSettings.isClientCredentialsFlowEnabled = true;
      oauthGlobalSettings.isCodeCredFlowEnabled = false;
      oauthGlobalSettings.isCodeCredPostOnly = false;
      oauthGlobalSettings.isConsumerSecretOptional = false;
      oauthGlobalSettings.isIntrospectAllTokens = false;
      oauthGlobalSettings.isNamedUserJwtEnabled = false;
      oauthGlobalSettings.isPkceRequired = true;
      oauthGlobalSettings.isRefreshTokenRotationEnabled = false;
      oauthGlobalSettings.isSecretRequiredForRefreshToken = true;
      oauthGlobalSettings.isSecretRequiredForTokenExchange = false;
      oauthGlobalSettings.isTokenExchangeEnabled = false;
      result = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{oauthGlobalSettings}).get(0);
      if (!result.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error : result.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(
      'Failed to create ECA OAuth global settings: ' + errorMessage);
      }

      // Step 4: Create OAuth policies (fullName = same as ECA fullName)
      awsac.SCCACECAMetaDataService.ExtlClntAppOauthConfigurablePolicies oauthPolicies =
      new awsac.SCCACECAMetaDataService.ExtlClntAppOauthConfigurablePolicies();
      oauthPolicies.fullName = ecaFullName;
      oauthPolicies.externalClientApplication = ecaFullName;
      oauthPolicies.clientCredentialsFlowUser = adminEmail;
      oauthPolicies.commaSeparatedPermissionSet = 'SCC_Administrator,SCC_Agent';
      oauthPolicies.commaSeparatedProfile = 'System Administrator';
      oauthPolicies.ipRelaxationPolicyType = 'Enforce';
      oauthPolicies.isTokenExchangeFlowEnabled = false;
      oauthPolicies.permittedUsersPolicyType = 'AdminApprovedPreAuthorized';
      oauthPolicies.refreshTokenPolicyType = 'Infinite';
      result = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{oauthPolicies}).get(0);
      if (!result.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error : result.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(
      'Failed to create ECA OAuth policies: ' + errorMessage);
      }
      }

      createExternalClientApp('email@email.com');
    3. Afterwards, confirm that you see SCC_PLACE_HOLDER_CERTIFICATE in Certificate and Key Management, and the external client app awsscc GLOBAL_EXTERNAL_CLIENT_APP under Setup > External Client Apps.
    4. In Setup > External Client Apps, find awsscc GLOBAL_EXTERNAL_CLIENT_APP, choose the dropdown arrow, and select View. On the details screen, choose Manage Consumer Details. This will send a verification code to your email address. Use the code, and then copy the Consumer Key and Consumer Secret to Notepad for later use.
    5. Go to Setup > External Client Apps, find awsscc GLOBAL_EXTERNAL_CLIENT_APP, choose the dropdown arrow, and select Edit Policies. The Policies page has two sections:
      1. Under App Policies > Select Permission Sets, verify that SCC Administrator and SCC Agent appear in the Selected Permission Sets column. If not, move them from Available Permission Sets using the arrow button.
      2. Under OAuth Policies > Plugin Policies, confirm Permitted Users is set to Admin approved users are pre-authorized.
      3. Under OAuth Policies > OAuth Flows and External Client App Enhancements, check Enable Client Credentials Flow. A Run As field will appear — select your system admin user.

        Note: If your organization prefers to use a dedicated Client Credentials Flow "Run As" user with minimum permissions instead, see Appendix E — Minimum Permissions for SCCAC Salesforce Users.

      4. Choose Save.

    Option B — Connected App (existing installations only)

    Note: Salesforce no longer allows new Connected Apps to be created. Existing Connected App installations continue to work for now; we recommend migrating to an External Client App. See Migrating to External Client App (ECA).

    Note: If you're not able to enable creation of Connected Apps in Salesforce, contact Salesforce Customer Support to have this re-enabled. This can be done by creating a Salesforce Support case.

    1. Log in as SCCAC Administrator user.
    2. Run the following code in an Anonymous window (Developer Console → Debug → Open Execute Anonymous Window). Be sure to replace email@email.com with your email address.
      String generateUniqueConsumerKey(Integer length) {
      String charset =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
      'abcdefghijklmnopqrstuvwxyz0123456789';
      String timestamp = String.valueOf(System.currentTimeMillis());

      // Calculate the length needed for the random part of the key
      Integer remainingLength = length - timestamp.length();

      // Ensure remaining length is positive; otherwise, adjust
      if (remainingLength <= 0) {
      return timestamp.substring(0, length);
      }

      // Generate the random part of the key inline
      String randomPart = '';
      for (Integer i = 0; i < remainingLength; i++) {
      // Generate a random index and cast the result to Integer
      Integer randomIndex =
      (Integer)Math.floor(Math.random() * charset.length());
      // Append the character at the random index to the result string
      randomPart += charset.substring(randomIndex, randomIndex + 1);
      }

      // Combine timestamp and random part
      return timestamp + randomPart;
      }

      String createCertificate() {
      awsac.SCCMetaDataService.MetadataPort service =
      new awsac.SCCMetaDataService.MetadataPort();
      service.SessionHeader =
      new awsac.SCCMetaDataService.SessionHeader_element();
      service.SessionHeader.sessionId = UserInfo.getSessionId();
      awsac.SCCMetaDataService.SaveResult createMetaDataResult =
      new awsac.SCCMetaDataService.SaveResult();
      awsac.SCCMetaDataService.Certificate certificate =
      new awsac.SCCMetaDataService.Certificate();
      certificate.fullName =
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL;
      certificate.caSigned = false;
      certificate.encryptedWithPlatformEncryption = false;
      certificate.keySize = 2048;
      certificate.masterLabel =
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL;
      certificate.privateKeyExportable = true;
      createMetaDataResult = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{certificate})
      .get(0);
      if (!createMetaDataResult.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error :
      createMetaDataResult.errors) {
      errorMessage = errorMessage + error.message;
      }
      throw new awsac.MetaDataApiException(errorMessage);
      }
      awsac.SCCMetaDataService.IReadResult readMetaDataResult = null;
      readMetaDataResult = service.readMetadata('Certificate',
      new String[] {
      awsac.SCCConstants.PLACE_HOLDER_CERTIFICATE_LABEL
      });
      awsac.SCCMetaDataService.Certificate cert =
      (awsac.SCCMetaDataService.Certificate) readMetaDataResult
      .getRecords()[0];
      Blob certificateBlob = EncodingUtil.base64Decode(cert.content);
      return certificateBlob.toString();
      }

      void createConnectedApp(String adminEmail) {
      awsac.SCCMetaDataService.MetadataPort service =
      new awsac.SCCMetaDataService.MetadataPort();
      service.SessionHeader =
      new awsac.SCCMetaDataService.SessionHeader_element();
      service.SessionHeader.sessionId = UserInfo.getSessionId();
      awsac.SCCMetaDataService.SaveResult createMetaDataResult =
      new awsac.SCCMetaDataService.SaveResult();
      awsac.SCCMetaDataService.ConnectedApp app =
      new awsac.SCCMetaDataService.ConnectedApp();
      app.fullName = awsac.SCCConstants.GLOBAL_CONNECTED_APP_FULL_NAME;
      app.label = awsac.SCCConstants.GLOBAL_CONNECTED_APP_LABEL;
      app.description = 'ConnectedApp to access Interaction Service APIs';
      app.contactEmail = adminEmail;

      awsac.SCCMetaDataService.ConnectedAppOauthConfig connectedAppConfig=
      new awsac.SCCMetaDataService.ConnectedAppOauthConfig();
      connectedAppConfig.callbackUrl = 'https://salesforce.com';
      connectedAppConfig.scopes =
      new String[]{ 'Api', 'Basic', 'RefreshToken', 'Interaction'};
      app.oauthConfig = connectedAppConfig;
      app.oauthConfig.certificate = createCertificate();
      app.oauthConfig.consumerKey = generateUniqueConsumerKey(64);
      app.oauthConfig.isAdminApproved = true;
      app.oauthConfig.isClientCredentialEnabled = true;
      app.oauthConfig.isCodeCredentialEnabled = false;
      app.oauthConfig.isCodeCredentialPostOnly = false;
      app.oauthConfig.isConsumerSecretOptional = false;
      app.oauthConfig.isIntrospectAllTokens = false;
      app.oauthConfig.isNamedUserJwtEnabled = false;
      app.oauthConfig.isPkceRequired = true;
      app.oauthConfig.isRefreshTokenRotationEnabled = false;
      app.oauthConfig.isSecretRequiredForRefreshToken = true;
      app.oauthConfig.isSecretRequiredForTokenExchange = false;
      app.oauthConfig.isTokenExchangeEnabled = false;

      awsac.SCCMetaDataService.ConnectedAppOauthPolicy connectedAppPolicy=
      new awsac.SCCMetaDataService.ConnectedAppOauthPolicy();
      connectedAppPolicy.ipRelaxation = 'ENFORCE';
      connectedAppPolicy.isTokenExchangeFlowEnabled = false;
      connectedAppPolicy.refreshTokenPolicy = 'infinite';
      app.oauthPolicy = connectedAppPolicy;

      app.profileName = new String[]{'System Administrator'};
      app.permissionSetName =
      new String[]{'SCC Administrator', 'SCC Agent'};
      createMetaDataResult = service.createMetadata(
      new List<awsac.SCCMetaDataService.Metadata>{app}).get(0);
      if (!createMetaDataResult.success) {
      String errorMessage = '';
      for (awsac.SCCMetaDataService.Error error :
      createMetaDataResult.errors) {
      errorMessage = errorMessage + error.message;
      }
      if (errorMessage.contains('permission set')) {
      errorMessage = errorMessage +
      ' Please verify creation of permission set : \"' +
      awsac.SCCConstants.SCC_ADMINISTRATOR_PERMISSION_SET_LABEL +
      '\" & \"' +
      awsac.SCCConstants.SCC_AGENT_PERMISSION_SET_LABEL +
      '\".';
      }
      throw new awsac.MetaDataApiException(errorMessage);
      }
      }

      createConnectedApp('email@email.com');
    3. Afterwards, confirm that you see SCC_PLACE_HOLDER_CERTIFICATE in Certificate and Key Management, and the connected app awsscc GLOBAL_CONNECTED_APP in App Manager.
    4. In App Manager, find the connected app awsscc GLOBAL_CONNECTED_APP and choose the arrow in the rightmost column, then select View. On this screen, choose Manage Consumer Details. This will send a verification code to your email address. Use the code, and then copy the consumer key and consumer secret to Notepad for later use.
    5. Go to Setup > App Manager > awsscc GLOBAL_CONNECTED_APP > Manage and choose Edit Policies
      1. For Permitted Users, select Admin approved users are pre-authorized.
      2. For Client Credentials Flow > Run As, select your system admin user. Choose Save.

        Note: If your organization prefers to use a dedicated Client Credentials Flow "Run As" user with minimum permissions instead, see Appendix E — Minimum Permissions for SCCAC Salesforce Users.

      3. In the Profiles section, choose Manage Profiles and check the box for System Administrator, then choose Save.
      4. In the Permission Sets section, choose Manage Permission Sets. Check the boxes next to SCC Administrator and SCC Agent, and then choose Save.
  5. Allocate capacity for sccac cache partition:

    1. Go to Setup > Custom Code > Platform Cache > Select sccac under Name

    platform-cache

    1. Select Edit
    2. Under Org Cache Allocation, allocate 1 for Provider Free or Organization.
    3. Select Save.
  6. Create a Lightning App for SCC-AC. To create a new Lightning App with Console navigation style:

    1. Go to Apps, App Manager, and then choose New Lightning App.
    2. Enter whatever name you like, choose Next.
    3. Under Navigation Style, select Console navigation, and choose Next.
    4. Choose Add Utility Item and then Omni-Channel.
    5. Choose Add Utility Item, Amazon Connect for Salesforce, and check the Start automatically check box. Choose Next.
    6. If you will be handling chats, search for Messaging Sessions, then choose the right arrow to move it to the Selected Items column. If you handle voice contacts, search for Voice Calls and add them as well. Choose Next and Next again.
    7. Select System Administrator and Standard User or any profile you are using for agents/users and choose the right arrow button to add them to Selected Profiles.
    8. Choose Save and then Finish.
  7. Go to the SCC Agent and SCC Administrator permission sets you cloned and choose Assigned Apps. Hit Edit, and then find the Lightning app you created. Choose the right arrow to add it to the list of Enabled Apps.