Skip to main content

#Experience Cloud50 discussing

Hi Community Members,   

I'm currently setting up a Salesforce Experience Cloud site and have configured the Login Discovery Page as the login page type. My goal is to allow users to log in using either mobile number or email, and receive an OTP instead of being redirected to enter a password.

However, I'm running into an issue:

  • When I enter a mobile number (e.g., 7972101144, 07972101144, or +917972101144), it redirects me to the password entry page instead of triggering OTP verification.
  • I want the system to send an OTP whether the user logs in with email or mobile number.

Additionally, I'm seeing the following error:  'Check your entry. If you still can't log in, contact your BankServices administrator.' in  AutocreatedDiscLoginHandler1747659242240 code:-  // This auto-generated class contains the default logic for login discovery by SMS or email.   // You can customize the code to ensure it meets your needs. The requestAttributes parameter   // provides additional information you can use in the discovery logic. Attributes include CommunityUrl,   // IpAddress, UserAgent, and location information (such as Country and City).     global class AutocreatedDiscLoginHandler1747659242240 implements Auth.LoginDiscoveryHandler {    global PageReference login(String identifier, String startUrl, Map<String, String> requestAttributes) {    if (identifier != null && isValidEmail(identifier)) {      // Search for user by email       List<User> users = [SELECT Id FROM User WHERE Email = :identifier AND IsActive = TRUE];      if (!users.isEmpty() && users.size() == 1) {        // User must have verified email before using this verification method. We cannot send messages to unverified emails.         // You can check if the user has email verified bit on and add the password verification method as fallback.        List<TwoFactorMethodsInfo> verifiedInfo = [SELECT HasUserVerifiedEmailAddress FROM TwoFactorMethodsInfo WHERE UserId = :users[0].Id];        if (!verifiedInfo.isEmpty() && verifiedInfo[0].HasUserVerifiedEmailAddress == true) {          // Use email verification method if the user's email is verified.          return discoveryResult(users[0], Auth.VerificationMethod.EMAIL, startUrl, requestAttributes);        } else {          // Use password verification method as fallback if the user's email is unverified.          return discoveryResult(users[0], Auth.VerificationMethod.PASSWORD, startUrl, requestAttributes);        }      } else {        throw new Auth.LoginDiscoveryException('No unique user found. User count=' + users.size());      }    }    if (identifier != null) {      String formattedSms = getFormattedSms(identifier);      if (formattedSms != null) {        // Search for user by SMS         List<User> users = [SELECT Id FROM User WHERE MobilePhone = :formattedSms AND IsActive = TRUE];        if (!users.isEmpty() && users.size() == 1) {          // User must have verified SMS before using this verification method. We cannot send messages to unverified mobile numbers.           // You can check if the user has mobile verified bit on or add the password verification method as fallback.          List<TwoFactorMethodsInfo> verifiedInfo = [SELECT HasUserVerifiedMobileNumber FROM TwoFactorMethodsInfo WHERE UserId = :users[0].Id];          if (!verifiedInfo.isEmpty() && verifiedInfo[0].HasUserVerifiedMobileNumber == true) {            // Use SMS verification method if the user's mobile number is verified.            return discoveryResult(users[0], Auth.VerificationMethod.SMS, startUrl, requestAttributes);          } else {            // Use password verification method as fallback if the user's mobile number is unverified.            return discoveryResult(users[0], Auth.VerificationMethod.PASSWORD, startUrl, requestAttributes);          }        } else {          throw new Auth.LoginDiscoveryException('No unique user found. User count=' + users.size());        }      }    }    if (identifier != null) {      // You can customize the code to find user via other attributes, such as SSN or Federation ID    }    throw new Auth.LoginDiscoveryException('Invalid Identifier');  }      private boolean isValidEmail(String identifier) {      String emailRegex = '^[a-zA-Z0-9._|\\\\%#~`=?&/$^*!}{+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$';      // source: http://www.regular-expressions.info/email.html       Pattern EmailPattern = Pattern.compile(emailRegex);      Matcher EmailMatcher = EmailPattern.matcher(identifier);      if (EmailMatcher.matches()) { return true; }      else { return false; }    }      private String getFormattedSms(String identifier) {      // Accept SMS input formats with 1 or 2 digits country code, 3 digits area code and 7 digits number      // You can customize the SMS regex to allow different formats      String smsRegex = '^(\\+?\\d{1,2}?[\\s-])?(\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4})$';      Pattern smsPattern = Pattern.compile(smsRegex);      Matcher smsMatcher = SmsPattern.matcher(identifier);      if (smsMatcher.matches()) {        try {          // Format user input into the verified SMS format '+xx xxxxxxxxxx' before DB lookup          // Append US country code +1 by default if no country code is provided          String countryCode = smsMatcher.group(1) == null ? '+1' : smsMatcher.group(1);          return System.UserManagement.formatPhoneNumber(countryCode, smsMatcher.group(2));        } catch(System.InvalidParameterValueException e) {          return null;        }      } else { return null; }    }    private PageReference getSsoRedirect(User user, String startUrl, Map<String, String> requestAttributes) {    // You can look up if the user should log in with SAML or an Auth Provider and return the URL to initialize SSO.    return null;  }    private PageReference discoveryResult(User user, Auth.VerificationMethod method, String startUrl, Map<String, String> requestAttributes) {    //Only external users with an External Identity or community license can login using Site.passwordlessLogin    //Use getSsoRedirect to enable internal user login for a community    PageReference ssoRedirect = getSsoRedirect(user, startUrl, requestAttributes);    if (ssoRedirect != null) {      return ssoRedirect;    } else {      if (method != null) {        List<Auth.VerificationMethod> methods = new List<Auth.VerificationMethod>();        methods.add(method);        PageReference pwdlessRedirect = Site.passwordlessLogin(user.Id, methods, startUrl);        if (pwdlessRedirect != null) {          return pwdlessRedirect;        } else {          throw new Auth.LoginDiscoveryException('No Passwordless Login redirect URL returned for verification method: ' + method);        }      } else {        throw new Auth.LoginDiscoveryException('No method found');      }    }  }  }   

I'm a beginner in Experience Cloud, and haven’t found any helpful videos or documentation online explaining how to achieve this. I'm attaching a screenshot of the error and mentioning the auto-generated login code here for reference.

Could someone please guide me step-by-step on how to solve this issue and implement OTP login for both email and mobile number through the Login Discovery Page?

Thanks in advance for your help!  

 

@* Experience Cloud *  @* Salesforce Developers * 

3 answers
  1. Aug 18, 6:00 PM

    Hi Any luck in finding out the solution?  

    Got stuck on the same issue while implementing Login Discovery in my domain.

0/9000

Hi there! We recently made out Knowledge base articles public so they can be indexed by Google and other search engines. Are there any best practices that you all can recommend to improve SEO performance? Also, has anyone been able to get Google to create Featured Snippets from your Experience Cloud site and Knowledge base?

4 answers
  1. Aug 15, 4:37 PM

    A few things I’d focus on:

    • Use clear, search-intent-focused titles and headings.
    • Give concise, direct answers that can work well for featured snippets.
    • Add relevant internal links between Knowledge articles.
    • Make sure pages are crawlable/indexable with unique meta titles and descriptions.
    • Keep content updated and genuinely useful.

    For Experience Cloud, Google Search Console is also very useful for finding queries where your articles are already getting impressions and improving them.

    Featured Snippets can’t be guaranteed, but good structure + clear answers can improve your chances.

    I work in SEO & local search as well local SEO Agency

0/9000

I am trying to modify an application form LWC, I have the source code for XML, HTML, JS, and APEX. I don't know how to upload and institute the changed files. Can anyone walk me through the process? Trying to learn stuff I didn't know I needed to know when the developers were around. :(

2 answers
  1. Aug 14, 9:14 AM

    Hey, don't stress, this is more mechanical than it looks. Here's the quick version: 

     

    Traditional route (VS Code): 

    1. Install VS Code + Salesforce Extension Pack + Salesforce CLI
    2. Authorize your org (SFDX: Authorize an Org)
    3. Place your LWC files in force-app/main/default/lwc/yourComponentName/ (HTML, JS, XML together) and Apex in force-app/main/default/classes/
    4. Right-click the folder → SFDX: Deploy Source to Org
    5. Check the Output panel for errors, then test in your org

     

    Easier option:

     

    If setting all that up feels like overkill for one change,

    BOFC's Dev Studio

    lets you edit and deploy Apex, LWC, and Aura directly inside Salesforce, no VS Code, no CLI, no auth setup. You'd just open the component in the org, paste your changes, and deploy right there. 

     

0/9000

Understanding that entering/selecting into the Action Launcher search field only display recently used actions to the user, and we are limited to 10 quick-action buttons, is there a solution for showing all available actions to a user? 

3 answers
  1. Aug 13, 4:52 PM

    Hey Corbitt, 

     

    For your two scenarios, here's what actually works: 

     

    For "I don't remember the name" — a custom LWC that queries and renders all actions the deployment exposes (grouped by category/object) would be the real fix, since there's no native browse-all UI. This means building it yourself, not a config toggle. 

     

    For the platform migration use case — that's less about Action Launcher and more about documentation. A lot of teams handle "what's available on new vs old" with a simple reference doc or an FAQ/help page, since even a custom action browser wouldn't clearly communicate "this exists but only works on Classic still." 

     

    If building the custom component route, you'd query the same action definitions the Action Launcher deployment uses, that's documented on the deployment/config side, so it's feasible, just not out-of-the-box. 

     

    Reference:

    https://help.salesforce.com/s/articleView?id=ind.action_launcher_deployment_experience_cloud.htm&language=en_US&type=5

0/9000

Hi all,

I’ve set up a CMS Workspace in Salesforce and I’m trying to build a custom component to search for documents.

I’m able to search documents by title, but is it possible to search for text inside a PDF document as well? I know some external tools provide this capability out of the box.

I’ve tried using the Salesforce APIs (e.g. the content-search-api), but they don’t seem to search the actual content of the documents as expected.

Has anyone had a similar requirement and found an OOTB Salesforce solution for searching inside PDF content?

1 answer
  1. Aug 12, 5:12 AM

    Hi Andrea — you've hit a real boundary. Short version: Salesforce CMS does not full-text-index the text inside a PDF's binary. The CMS content search / content-search-api indexes the content item's fields (title, metadata, body/content nodes), not the bytes inside an attached PDF — which is exactly why your title search works but a content search comes back empty. There's no OOTB CMS setting to flip for "search inside PDF content." 

     

    Where Salesforce does search inside PDFs OOTB: Salesforce Files (ContentVersion). Global / SOSL search extracts and indexes the text content of uploaded files, including PDFs (within size limits), so a SOSL query over ContentVersion matches on text inside the PDF. So the native "search inside a PDF" capability exists — it just lives on Files, not on CMS content. 

     

    Practical options for your custom component: 

    1. Store or expose the PDFs as Salesforce Files (ContentVersion) and have your component run SOSL against ContentVersion — you get inside-the-PDF matching for free (subject to the documented file-content index limits). Least-effort native route. 

    2. Extract the text at ingest and make it searchable: run the PDF through a text-extraction/OCR step (an Apex PDF library, or a Flow/Apex HTTP callout to an extraction or OCR service) when the document is added, and store the extracted text in a searchable field — on the CMS content or a related custom object your component queries. This is the usual pattern when the file must stay in CMS but you still need full-text search. 

    3. If you're on an Industries cloud, look at Smart Content Search — it is designed to search within document content, but it's license/cloud-specific, so confirm it applies to your org. 

     

    Net: no OOTB CMS "search inside PDF," but Files + SOSL gives you native in-PDF search, and text-extraction-on-ingest is the standard workaround when the content needs to stay in CMS. 

     

    Ref: How search indexes and finds text (including within files):

    https://help.salesforce.com/s/articleView?id=sf.search_index.htm&type=5

0/9000

Hi everyone,

I'm facing an issue with an OmniScript File Upload on an Experience Cloud site.

The file uploads successfully and a ContentVersion record is created. However, the Experience Site (guest/external) user is unable to retrieve or access the returned ContentVersion Id (vId) after the upload completes. In some cases, the upload appears successful, but the vId is blank or unavailable for subsequent steps in the OmniScript.

Our goal is to use the returned ContentVersion/ContentDocument information later in the flow to associate the uploaded document with a Case record.

Has anyone encountered this issue with OmniStudio File Upload components on Experience Sites? Are there any known limitations, sharing settings, guest user restrictions, or permissions required for external users to access the generated ContentVersion Id after upload?

Any guidance would be greatly appreciated.

Thanks! 

 

#Omnistudio  #Upload Files  #Experience Cloud  #Guest User

7 answers
0/9000

Hi all , 

 

I wanted to check...

 

On a quotation, an email received by John is visible to other users who have access to the record. However, users such as Mick can only view the email and do not see the Reply or Forward

 buttons. Even as a System Administrator, I cannot see these actions. 

 

When I log in as John , the Reply and Forward buttons are available.

Could this be standard Salesforce behavior, where the Reply and Forward

 actions are tied to the mailbox owner/recipient rather than to users who simply have access to the Email Message record? Or is this something that can be configured or customized from a development perspective? 

 

Let me explain the below image:

  • From shows the sender's email address.
  • To shows John's email address, which means the email was sent to John.
  • Mick then clicks View All to open the full email record and dnt see Forward, reply, reply all button on right side only see delete button 

Reply/Forward Buttons Visible Only to Email Recipient

 

image.png

 

Thank you  

 

#Trailhead Challenges #Salesforce Developer #Salesforce Admin #Experience Cloud

4 answers
  1. Aug 5, 7:53 AM

    Hi @Roopa Sharma -  This isn't possible with Flow alone. The Reply, Reply All, and Forward actions are part of Salesforce's email integration and are only available to the connected mailbox owner. Flow can't invoke these standard email actions or impersonate another user's mailbox. If you need similar functionality for other users, it would require a custom solution (typically using Apex and/or a custom Lightning component) or a third-party email integration. 

0/9000

Hi Everyone    i am working on a usecase where   Partner Community (Experience Cloud) user is unable to create a ContentVersion record using the Salesforce REST API.     i have a LWC Component and a button named preview, which upon click   

A callout is made to an external system to generate the preview document.

After receiving the document, the application sends a POST request to the Salesforce REST API (/services/data/vXX.X/sobjects/ContentVersion) to create a ContentVersion record.      

The REST API request fails with the following error:

    

Troubleshooting Performed

  • The user has a Partner Community license.
  • API Enabled permission has been granted to the user.
  • Authentication is successful, and the REST API request reaches Salesforce.
  • The user is the owner of the parent record (FirstPublishLocationId).
  • Organization-Wide Defaults (OWD) have been changed to Public Read/Write for testing.
  • The issue persists even after these changes.

  is this salesforce Limitataion or i am missingsomething.  Please guide.    

 

@* Salesforce Developers * @* Experience Cloud * 

1 answer
0/9000

HI All, 

 

What should be the approval setting when a user goes on holiday? 

 

Suppose User A goes on holiday and does not want to receive any approval emails during that period.

Approval Delegation During User Holiday Absence

 

In this case, 

User B

 should act as the approver on User A’s behalf. Could you please advise what the correct approval settings should be to ensure that approval requests are both emailed to User B and visible in Salesforce during User A’s absence? 

 

image.png

Thank YOu !! 

5 answers
  1. Aug 4, 8:11 AM

    Hey @Roopa Sharma

     

     

    If user A wants

    ONLY

    emails they are the approver for on holiday, set it to "Only if I am an approver"  

     

    If user A wants ALL emails whether they are an approver or a delegated approver, set it to "If I am an approver or delegated approver" 

0/9000

Hi! With the last announcement about Chatter (Chatter is Turned Off by Default on New Orgs | Salesforce Help

), we have doubts regarding how this will affect to Feed and Direct messaging features of Experience Cloud. 

 

Is there any roadmap about this? Should we expect a migration to Slack? Or is it safe we plan a Experience site roadmap base on current communication features of Chatter? 

 

Thank you!

2 answers
  1. Aug 3, 7:32 PM

    Thank you for the response @ENIO ANSELMO DE SOUZA

     

     

    As mentioned, we are not retiring Chatter, but instead are encouraging orgs to use Slack's Salesforce Channels for record collaboration in place of Chatter.  Experience Cloud specifically has some unique usage of Chatter, such as the forum's use case where an unauthenticated user is able to read Chatter posts, and it is unknown if or when Slack would support this use case, so we plan to continue supporting Chatter. 

     

    Also mentioned, if you're looking into building an integration with Chatter, you may consider if a Slack may be a better fit, or else build in a way which could enable moving to Slack at a later date if desired.

0/9000