Skip to main content

#Apex58 人正在讨论

Short gist to put above the question

One thing I would not include yet

Don't state “Amazon Connect caused the incident.” We haven't proved that. Phrase it as a lead under investigation, which will make the Trailhead question much more credible and technically precise.

 

 

#Salesforce Developer  #Salesforce  #Apex  #Trailhead

1 个回答
  1. Eric Burté (DEVOTEAM) Forum Ambassador
    昨天,00:13

    Hello @Rahul Rawat is it a question ?  I am not sure to understand if you are looking for help on this duplicate issue ; could you please give a bit more details ? Eric

0/9000

  #Trailhead Challenges #Salesforce Admin #Flow #Apex What are the most important Salesforce debugging skills a fresher should learn? For example, Debug Logs, Flow Debug, Apex errors, or permission-related troubleshooting? 

2 个回答
  1. 10月9日 14:35

    Hi @ROHIT PIPPERA

     

    As a fresher, you don't need to be an expert in debugging, but you should know how to identify and troubleshoot common Salesforce errors. 

     

    Focus on these key areas:

    1. Debug Logs: Learn how to check logs and identify errors.
    2. Flow Debug: Practice debugging Screen Flows and Record-Triggered Flows.
    3. Apex Debugging: Understand System.debug(), exceptions, and common DML errors.
    4. Permission Issues: Learn how to troubleshoot Profiles, Permission Sets, OWD, and Field-Level Security.
    5. Validation Rules: Understand why records fail to save and how to identify the issue.
    6. SOQL Errors: Practice identifying query errors and governor limit exceptions.

    My suggestion: Create a few errors intentionally in your practice org and try to fix them yourself.

    In interviews, don't just explain what Debug Logs are. Be ready to explain how you identified and resolved an issue. 

     

    Practical troubleshooting skills will definitely help you stand out as a fresher. 

     

    All the best!

0/9000

Environment: [Developer Edition demo org / your actual org type], My Domain https://co1791181560741.my.salesforce.com

Setup completed and verified:

  • External Client App "ERP_Agent" — OAuth enabled, Enable Token Exchange Flow checked, Issue JWT-based access tokens for named users checked, scopes api + openid, Permitted Users = "Admin approved users are pre-authorized" with Permission Set assigned, IP Relaxation = "Relax IP restrictions". Rebuilt from scratch once to rule out a corrupted app object — same result both times.
  • Apex class SalesErpExchangeHandler extends Auth.Oauth2TokenExchangeHandler — compiles cleanly; validateIncomingToken/getUserForTokenSubject logic independently verified correct via Execute Anonymous against a real token.
  • OauthTokenExchangeHandler metadata record — deployed, confirmed via Setup → Token Exchange Handlers page showing it linked and enabled for ERP_Agent, with apexExecutionUser set to a valid, active integration user (confirmed exact Username match).
  • A separate External Client App ("Sales_Agent_Broker") using Client Credentials Flow works correctly and reliably issues valid JWTs — ruling out broader org-level OAuth/My Domain issues.

Symptom: POST to /services/oauth2/token with grant_type=urn:ietf:params:oauth:grant-type:token-exchange consistently returns:

json

{"error":"access_denied","error_description":"end-user denied authorization"}

Tried both subject_token_type values (jwt and access_token)

  • Tried with and without explicit scope and token_handler parameters
  • Verbose curl (-v) shows no additional detail — no WWW-Authenticate header, just the generic JSON body
  • An Apex-Class-level trace flag (CLASS_TRACING, confirmed present via Tooling API query on TraceFlag) on SalesErpExchangeHandler captures zero log entries across every attempt — strong evidence the handler is never being invoked, meaning the rejection happens before Salesforce reaches the Apex layer at all.

Question:

What pre-Apex check is this failing, and is there an org-level enablement for Token Exchange Flow beyond the per-app checkbox that isn't exposed in Setup? 

 

#OAuth 2.0  #Apex

4 个回答
  1. 10月9日 02:46

    Hi Ranjith, 

    I don't think there's a hidden org-level switch for this. Your setup looks right, so I'd check the request side, since that's what gets rejected before Apex runs: 

    1. Make sure client_id is ERP_Agent's consumer key, not Sales_Agent_Broker's. If "Require Secret for Token Exchange Flow" is on, send client_secret too.
    2. Confirm Enable Token Exchange Flow is ticked in the OAuth settings and also on the policies side, then save.
    3. Call your My Domain URL, never login.salesforce.com. You're already doing that.
    4. If you pass token_handler, use the DeveloperName of the OauthTokenExchangeHandler record, not the Apex class name. If you leave it out, check that the handler is the one Salesforce falls back to.
    5. Don't read the empty class trace as proof Apex isn't reached. Add a USER_DEBUG trace flag on the apexExecutionUser and the mapped user. You can also throw a custom exception on the first line of validateIncomingToken. If the error text changes, you're hitting Apex.

     

    If all of that checks out and it's still a bare access_denied, open a Support case with the exact timestamp and your My Domain. They can see server-side logs we can't. 

      

    Hope that helps!

0/9000

Basically I need to build a Bulk email functionality. Need to send a single message to multiple emails through AWS ses. But completely clueless from where to begin and how to achieve this. 

 

Is there anyone who has done it or know a little about it. do help me out. 

Any help would be appreciated. 

 

Progress so far:- 

 

I've found this documentation. I thik this is something i need to follow. 

 

https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html

 

 

And most probably I need to write batch apex so how can I handle it through batch that also I would like to know from the community. Thanks. 

 

 

 

#AWS  #Apex  #Experience Cloud  #Salesforce Developer  #Lightning Aura Components

1 个回答
  1. 10月7日 11:58

    Hi @Kushagra Rajput,

    Your direction is right. Here is a simple way to build it.

    1. Set up AWS SES first

    • Verify your sender email or domain in SES.
    • If your SES account is in sandbox mode, you can only send to verified emails, so request production access.
    • Create an email template in SES. SendBulkEmail needs a template, even for a simple message.

    2. Authentication from Salesforce

     

    Use a

    Named Credential with an External Credential of type AWS Signature Version 4. It signs the request for you, so you do not need to write the signing code in Apex.

    3. The API call

     

    Send a POST request to /v2/email/outbound-bulk-emails (SES v2). One call accepts

    up to 50 destinations, so split your email list into groups of 50.

    4. Use Batch Apex

    • Implement Database.Batchable<SObject> and Database.AllowsCallouts. Without AllowsCallouts, the callout fails.
    • Run it with a scope of 50, so each execute makes one SES call.

    apex

    public class BulkEmailBatch implements Database.Batchable<SObject>, Database.AllowsCallouts {

    public Database.QueryLocator start(Database.BatchableContext bc) {

    return Database.getQueryLocator('SELECT Email FROM Contact WHERE Email != null');

    }

    public void execute(Database.BatchableContext bc, List<Contact> scope) {

    List<Object> entries = new List<Object>();

    for (Contact c : scope) {

    entries.add(new Map<String, Object>{

    'Destination' => new Map<String, Object>{ 'ToAddresses' => new List<String>{ c.Email } }

    });

    }

    Map<String, Object> body = new Map<String, Object>{

    'FromEmailAddress' => 'sender@yourdomain.com',

    'DefaultContent' => new Map<String, Object>{

    'Template' => new Map<String, Object>{ 'TemplateName' => 'YourTemplate', 'TemplateData' => '{}' }

    },

    'BulkEmailEntries' => entries

    };

    HttpRequest req = new HttpRequest();

    req.setEndpoint('callout:AWS_SES/v2/email/outbound-bulk-emails');

    req.setMethod('POST');

    req.setHeader('Content-Type', 'application/json');

    req.setBody(JSON.serialize(body));

    HttpResponse res = new Http().send(req);

    // check res.getStatusCode() and log failures

    }

    public void finish(Database.BatchableContext bc) {}

    }

    Run it with Database.executeBatch(new BulkEmailBatch(), 50);

    5. Things to remember

    • Check the response for each entry (the API returns a status per email), and log failures.
    • Respect your SES sending rate limit.
    • Handle bounces and unsubscribes (SES configuration sets with SNS can help).

    Hope this helps. Share where you get stuck and I can help further.

0/9000

we have a dependent picklist in LWC and we get the value from standard getPicklistValue method, but when user language is non-english and we have a translation for the picklist vlaue, the picklist value won't shown in the front end.  

But if the translated value is same as English, it will be shown in the front end.  

 

Dependent picklist not shown in LWC page when user has a non-English language.

 

I also asked AI and it say:  

When assembling picklist value sets in the UAT sandbox (Winter '27) using the UI-API in a non-default language, values with translated entries are incorrectly discarded—this is a platform regression, not a data or configuration issue. Production is currently running an older version and is therefore safe, but the issue will inevitably reoccur the moment production is upgraded to Winter '27. 

 

So I want to know if this is a salesforce Known issue or not?  

 

 

#Trailhead Challenges  #Salesforce Developer  #TrailblazerCommunity  #Apex

2 个回答
  1. 9月22日 11:14

    Hi @Bruce Wang

    -  Its  likely due to translated labels being used for dependency mapping.  

    Use the picklist API value for controllerValues matching, and use label only for displaying the value.  

    controllerValue === index
0/9000

Hi All,

I am getting error:

"Method does not exist or incorrect signature: void returnAverageSum(List<Opportunity>) from the type PracticeApex" . Kindly help me in resolving above error.

Here is my code

public class PracticeApex{

    public static void retrunAverageSum(List<Opportunity> ol){

        Integer avg=0;

        Integer sum=0;

        Integer size= ol.size();

        for(Opportunity o: ol){

           sum=sum+o.Amount.IntValue();           

        }

        avg=sum/size;

    System.debug(avg);

    }

    }

from Dev Console:

PracticeApex pa=new PracticeApex();

List<Opportunity> opp=[Select Id, Amount from Opportunity];

pa.returnAverageSum(opp);
2 个回答
  1. 2023年10月9日 06:16

    Hi Vishal,

    1. Typo Mistake : Your method name is retrunAverageSum and you are calling returnAverageSum in Dev Console.

    2. Remove static keyword from method.

    Hope this will help.

    Thanks!
0/9000

Hi everyone,

I need an architectural sanity check on a security requirement. I want to avoid hitting platform limits down the road and would appreciate some feedback on whether this can be safely achieved using Schedule-Triggered Flows or whether Scheduled Batch Apex would be required.

Context

  • We are changing the Organization-Wide Defaults (OWD) of the standard Quote object from Controlled by Parent to Private.
  • We receive an integration feed from an external system that creates or updates up to approximately 80 Quotes per Account per day. Quotes can also be created manually in Salesforce.
  • Quotes contain two custom Account lookups: Sold-To and Bill-To.
  • We have both Quotes with and without Opportunities.

Requirement

  • The Account Owner of the Sold-To Account and the Account Owner of the Bill-To Account must have Read-Only access to the related Quote.
  • When the Account Owner changes, access to the related Quotes must be updated accordingly, including removing the previous owner's access and granting access to the new owner.
  • The required access is managed through QuoteShare records with RowCause = Manual.

Architectural Question

Given the expected Quote volume and the need to automate the insertion and cleanup of QuoteShare records following Account ownership changes:

  • Is this approach feasible using a standard Schedule-Triggered Flow, or would Scheduled Batch Apex be required to ensure scalability and avoid governor limits?
  • What would be the cleanest architectural pattern for handling the cleanup and creation of Manual QuoteShare records when Account ownership changes?

Thanks for your guidance!

 

 

@Salesforce Administrators & Developers, @Salesforce Administrators and Developers, @APAC Architects, @Data Quality & Management

 

 

#Trailhead Challenges  #Salesforce Developer  #Salesforce Admin  #Salesforce  #Flow  #Apex

3 个回答
  1. 9月26日 20:40

    @sakshi nagpal

    , would you still recommend using APEX instead flow if the volume of quotes is of up to 80 per day approx. in general and not per account?. 

    @Debarshi Bagchi, sorry if I ask you, I would appreciate any guidance in this sense,

0/9000
Hi All, 

I have tried to delete the record from VoiceCallRecording in the execute anonymous to test this functionality so that later on I can put the same in Apex class.

I am the owner of voicecall record.

Here is the below code snippet.

List<VoiceCallRecording> vcr = [SELECT Id, Name, VoiceCallId FROM VoiceCallRecording where VoiceCallId = 'SomeIdOfVoiceCall'];

delete vcr.get(0);

and when I execute this, I get error like DML operation Delete not allowed on VoiceCallRecording

As per documentation of the VoiceCallRecording says that the delete() is allowed. Could anyone pls guide me through this, is there any permission set that needs to be enabled or anything that I am missing

url of the documentation Link (https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_voicecallrecording.htm)
2 个回答
0/9000

 I need to automatically create a Chatter post on a Case whenever its pending approval request is reassigned to another user using the standard Reassign action. Since triggers and record-triggered flows aren't supported on ProcessInstanceWorkitem, and the Case itself doesn't change, I'm not sure how to capture this event. Has anyone solved this, whether with scheduled polling, a custom reassign component, or another approach? Any suggestions or sample code would be appreciated.  

 

#Trailhead  #Salesforce Developer  #Salesforce Admin  #Salesforce  #TrailblazerCommunity  #Sales Cloud  #Apex  #Salesforcecommunity  #Salesforce_developer

2 个回答
  1. 9月25日 08:00

    You’re correct that there isn’t a direct trigger point here. ProcessInstanceWorkitem doesn’t support Apex triggers or record-triggered flows, and reassigning the approval doesn’t update the Case itself. 

     

    If you need to keep the standard Reassign action, I’d handle it with scheduled Apex:

    1.  Run a scheduled job every few minutes. 
    2.  Query new ProcessInstanceStep records where StepStatus = 'Reassigned'. 
    3.  Use ProcessInstance.TargetObjectId to identify the related Case. 
    4.  Query the pending ProcessInstanceWorkitem for that process instance to get the newly assigned ActorId. 
    5.  Insert a FeedItem with the Case ID as ParentId. 
    6.  Store the processed ProcessInstanceStep.Id in a small custom log object with a unique/external-ID field. 
    7.  Skip any step already in that log so rerunning the job can’t create duplicate Chatter posts. 

    I’d also test it by reassigning the same approval twice and then running the job twice. The expected result should be two Chatter posts total, with no additional posts from the second job run. 

     

    If real-time posting is absolutely required, the other option is to replace the standard Reassign experience with a custom Flow/LWC backed by Apex. That custom action would update ProcessInstanceWorkitem.ActorId and create the Case FeedItem in the same transaction. But the existing standard Reassign action can’t be intercepted directly.

0/9000

Hi everyone,

I have a question regarding the “Create Quotes without Opportunities” feature and a potential future requirement involving Orders.

 

After enabling the “Create Quotes without Opportunities” feature, Salesforce automatically provides the QuoteAccountId field on the Quote object. For Quotes created without an Opportunity, the Account relationship is stored in QuoteAccountId, while the standard AccountId is not populated.

 

Would it be technically possible to populate the standard AccountId field with the value from QuoteAccountId

for Quotes created without an Opportunity?. 

 

The reason for considering this is that Orders will be used in the future, and the standard Account relationship may be required for the Order process.

Would populating AccountId = QuoteAccountId be a supported and recommended approach, or are there any Salesforce limitations or implications we should consider when working with Quotes without Opportunities? or any workaround?.

Thanks for your guidance! 

 

@Salesforce Administrators & Developers, @Salesforce Administrators and Developers, @APAC Architects, @Data Quality & Management

 

 

#Trailhead Challenges  #Trailhead  #Salesforce Developer  #Salesforce Admin  #Salesforce  #Flow  #Data Management  #Apex  #Sales Cloud

2 个回答
  1. 9月24日 15:17

     

    Short answer: you generally cannot (and do not need to) write QuoteAccountId into the standard Quote.AccountId field. On the Quote object, AccountId is a system-derived, read-only reference that Salesforce fills from the related Opportunity's Account. It is not createable/updateable through the UI, Flow, Apex or the API, so an update like AccountId = QuoteAccountId will be rejected or ignored. For quotes created without an Opportunity, QuoteAccountId (label "Account for Quote") is the field Salesforce intends you to use as the account relationship. 

     

    For your future Order process this is already covered: Salesforce's documentation for quotes without opportunities says associating the quote to an account is optional but recommended, because an account is required to convert the quote to an order. When you create an Order from such a quote, the account comes from the quote's account (QuoteAccountId), so you don't need Quote.AccountId populated. 

     

    Practical recommendations: 

    1. Make QuoteAccountId required (validation rule, e.g. ISBLANK(OpportunityId) && ISBLANK(QuoteAccountId)) so every quote can be turned into an Order. 

    2. After enabling the feature, open Object Manager > Quote > Fields > Account for Quote and grant field-level security to your profiles/permission sets. It is hidden by default, which is why it often looks unavailable in Flow, reports and Apex. 

    3. In reports, flows, sharing logic and Apex, use one source of truth, for example a formula field BLANKVALUE(QuoteAccountId, Opportunity.AccountId), so logic works for quotes with and without an Opportunity. 

    4. If you create Orders yourself via Flow/Apex (rather than the standard Create Order action), set Order.AccountId = Quote.QuoteAccountId and Order.QuoteId = Quote.Id. 

     

    References: 

    Enable Quote Creation Without a Related Opportunity:

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

     

    Release note, Create Quotes Without a Related Opportunity:

    https://help.salesforce.com/s/articleView?id=release-notes.rn_sales_quotes_without_opportunities.htm&release=244&type=5

     

    Quote object reference:

    https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_quote.htm

     

     

    Assumption: the statement that Quote.AccountId is read-only is based on the Quote object reference field properties and commonly reported org behaviour; please confirm in a sandbox (e.g. attempt the update in a Flow or Developer Console) before designing around it.

0/9000