• Joseph Gay 8
  • NEWBIE
  • 0 Points
  • Member since 2022

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 0
    Replies
I am trying to send transactional emails from Salesforce by using the SendGrid API (via External Services) and Flow Builder.

Here is what I've done so far:
  • Added the SendGrid auth credentials to Salesforce (Setup > Named Credentials)
  • Imported the SendGrid v3 OpenAPI spec to Salesforce (Setup > External Services)
We now have over 300 SendGrid API operations we can conduct from within any Salesforce Flows.

We want to use the 'POST_Mail-Send' Flow Action to send an email, but I don't know how to setup the flow to accept the payload that SendGrid is looking for.

The only parameter I see in the Invokable Action is "Body" and I'm not sure how to pass values to it. The SendGrid API needs a 'from', 'to', 'dynamic_template_data', and 'template_id' according to their docs (https://docs.sendgrid.com/ui/sending-email/how-to-send-an-email-with-dynamic-templates).

How do I construct a payload body to pass to the invokable action within my flow?
I'm trying to update a field with a date on some opportunity records. This date should come from the opportunity's first appointment date.

The appointment sObject has a lookup field to opportunity. An opportunity can have many appointments.

I have a parent-child query that gets all opportunities that have related appointment records. I then sort those related appointment records by date in ascending order.

I need to grab the first appointment's date after the sort and set the opportunity's first_appointment__c field to the date of its first appointment (Appointment__c.date_of_appointment__c).

I don't have any compile errors but when I run the below code in the dev console, it executes and I get a debug log but none of my records have changed.

Here is the code:
public class UpdateOppFirstAppt {
    
    public static void updateOppFirstAppt() {
        // get 100 opps (and their related appts) where first appointment field is null and store in list
        List<Opportunity> oppList = [SELECT Id, First_Appointment__c, (SELECT Id, Date_of_Appointment__c 
                                                                       FROM Appointments__r 
                                                                       WHERE Date_of_Appointment__c != Null 
                                                                       ORDER BY Date_of_Appointment__c ASC
                                                                       LIMIT 1)
                                     FROM Opportunity
                                     WHERE First_Appointment__c = Null
                                     LIMIT 100];
        
        // the new list to add the updated opps
        List<Opportunity> oppToBeUpdated = new List<Opportunity>();
        
        // for each opp in the list, set its first appointment field with its first appt date
        if (!oppList.isEmpty()) {
            for (Opportunity opp : oppList) {
                for (Appointment__c appt : opp.Appointments__r) {
                    opp.First_Appointment__c = appt.Date_of_Appointment__c;
                }
                oppToBeUpdated.add(opp);
            } 
        }
        
        // update the opps in the list
        if (!oppToBeUpdated.isEmpty()) {
            update oppToBeUpdated;
        }
    }
}
I suspect I need an index of some sort to grab the first appointment maybe? Something like this within the for loop:
opp.First_Appointment__c = appt.Date_of_Appointment__c[0];
But I get a 'Expression must be a list type: Datetime' error when trying to do that.

Some opportunity records have more than 1 appointment in their appointment related list so I need to figure out how to just grab the first one and update the opportunity field with that first appointment's date.
I am creating a new Lightning Web Runtime app. I chose the Single Page App & TypeScript support options when using the CLI to initially create the app with the npm init lwr command.

I was able to add the lightning-base-components npm package and it's working just fine. But when I try to add SLDS, the styles do not show up for me.

I first installed both @salesforce-ux/design-system and @lwc/synthetic-shadow since SLDS requires synthetic shadow as a dependency when being used off-platform.

I then created my index.html file, linking to the SLDS stylesheet in the head tag:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My LWR App</title>
  <link rel="stylesheet" href="$sldsDir/styles/salesforce-lightning-design-system.min.css" />
</head>
<body>
  <!-- triple braces prevents HTML escaping -->
  {{{body}}} {{{lwr_resources}}}
</body>
</html>
Finally, I updated my LWR.config.json file:
{
    "lwc": { "modules": [
        { "dir": "$rootDir/src/modules" }, 
        { "npm": "lightning-base-components" }
    ] },
    "bundleConfig": { "exclude": [
        "lwc", 
        "lwr/navigation", 
        "@lwc/synthetic-shadow"
    ] },
    "layoutsDir": "$rootDir/src/modules",
    "assets": [
        {
            "alias": "sldsDir",
            "dir": "$rootDir/node_modules/@salesforce-ux/design-system/assets",
            "urlPath": "/slds"
        }
    ],
    "routes": [
        {
            "id": "example",
            "path": "/",
            "rootComponent": "example/app",
            "layoutTemplate": "$layoutsDir/index.html"
        }
    ]
}
At this point, everything works except SLDS. I have some SLDS classes on a few base components in my app module, but when the module loads, the styles do not show up because synthetic-shadow is still disabled. I can see from 'view source' in the browser that shadow-root is still open.

I'm at a loss as there is no index.js to use the import '@lwc/synthetic-shadow'; statement and the SLDS docs don't even mention LWR.

How do I force LWR to use the synthetic shadow DOM instead of the native DOM provided by the browser so that my global styles will be applied?