Account data submitted in Salesforce → Sent to External API → Account created in the external system → External System ID stored in Salesforce.
Friday, 21 February 2025
Monday, 3 February 2025
How to Debug: Console, HRA, and Apex Debug Logs Salesforce
Explanation of Log Content:
Console.log:
Used for frontend debugging in JavaScript or Lightning Web Components (LWC).
Logs messages, variables, and errors to the browser console.
HRA.log:
A custom log file for a Human Resources Application.
Tracks application events, warnings, and errors for auditing and debugging purposes.
Apexdebug.log:
Generated by Salesforce for debugging Apex code.
Captures execution details, SOQL queries, debug statements, and exceptions.
These logs are essential for troubleshooting, monitoring, and improving applications. The content and structure will vary depending on the specific use case and the system being debugged.
Understanding Logs: Console.log, HRA.log, and Apex Debug.log
Monday, 28 October 2024
Multi-step Contact Form In LWC
Caption: "Please enter your basic personal details, including your first and last name."
Screen 2
Title: "Contact Details"
Caption: "Provide your primary contact information, including email and phone number."
Screen 3
Title: "Review & Submit"
Caption: "Review the information provided, then click Submit to save your details."
Tuesday, 8 October 2024
Triggering Change Data Capture (CDC) for Automated Sync of Salesforce Accounts with External System on Create/Update Events
When an Account is created, fields like Document_Name__c, Account Name, and AnnualRevenue should be automatically populated (or updated) in an external system.
These fields should also be automatically populated in Salesforce, and this should happen when the account is first created.
Updated Requirements
Document_Name__c: Automatically generated when an Account is created.
Account Name and AnnualRevenue: Sent to the external system when the account is created, and potentially populated with specific data from the external system as well.
Trigger
trigger AccountChangeEventTrigger on AccountChangeEvent (after insert) {
List<String> insertIds = new List<String>();
List<String> updateIds = new List<String>();
for (AccountChangeEvent event : Trigger.New) {
if (event.ChangeEventHeader.getChangeType() == 'CREATE') {
insertIds.add(event.ChangeEventHeader.getRecordIds()[0]);
} else if (event.ChangeEventHeader.getChangeType() == 'UPDATE') {
updateIds.add(event.ChangeEventHeader.getRecordIds()[0]);
}
}
if (!insertIds.isEmpty()) {
List<Account> newAccounts = [SELECT Id, Name, AnnualRevenue, Document_Name__c FROM Account WHERE Id IN :insertIds];
for (Account acc : newAccounts) {
ExternalService.sendAccount(acc.Document_Name__c, acc.Name, acc.AnnualRevenue);
}
}
if (!updateIds.isEmpty()) {
List<Account> updatedAccounts = [SELECT Id, Name, AnnualRevenue, Document_Name__c FROM Account WHERE Id IN :updateIds];
for (Account acc : updatedAccounts) {
ExternalService.sendAccount(acc.Document_Name__c, acc.Name, acc.AnnualRevenue);
}
}
}
Apex Class
public class ExternalService {
@future(callout=true)
public static void sendAccount(String documentId, String accountName, Decimal annualRevenue) {
try {
List<FirestoreConfig__mdt> configs = [SELECT API_Key__c, Endpoint_URL__c FROM FirestoreConfig__mdt LIMIT 1];
if (configs.isEmpty()) {
return;
}
String apiKey = configs[0].API_Key__c;
String endpoint = configs[0].Endpoint_URL__c;
HttpRequest req = new HttpRequest();
Http http = new Http();
String finalEndpoint = endpoint + documentId + '?key=' + apiKey;
req.setMethod('PATCH');
req.setEndpoint(finalEndpoint);
req.setHeader('Content-Type', 'application/json');
String body = '{' +
'"fields": {' +
'"accountName": {"stringValue": "' + accountName + '"},' +
'"annualRevenue": {"doubleValue": ' + annualRevenue + '}' +
'}' +
'}';
req.setBody(body);
HttpResponse res = http.send(req);
if (res.getStatusCode() == 200 || res.getStatusCode() == 201) {
} else {
System.debug('Error updating account in ExternalSystem: ' + res.getStatusCode() + ' - ' + res.getBody());
}
} catch (Exception e) {
System.debug('Exception: ' + e.getMessage());
}
}
}
Sunday, 6 October 2024
Triggering Platform Events for Contact Creation and Sending Data to External Systems
how to publish a Platform Event when a Contact record is created and send this contact data to External Systems using a Salesforce custom Apex class with a callout.
Steps:
Trigger on Contact Creation: This trigger publishes a platform event when a Contact record is inserted.
Platform Event Trigger: This trigger listens to the Platform Event and sends the data to External Systems using an Apex class.
Apex Class for External Systems Integration: A class that performs a callout to the External Systems API to send the contact data.
Custom Metadata Type (for External Systems Configuration): The External Systems API key and endpoint URL are stored in custom metadata to allow flexibility and security.
trigger ContactTrigger on Contact (after insert) {
List<ContactCreationEvent__e> events = new List<ContactCreationEvent__e>();
for (Contact contact : Trigger.New) {
String fullName = contact.FirstName + ' ' + contact.LastName;
ContactCreationEvent__e event = new ContactCreationEvent__e(
Name__c = fullName,
Age__c = contact.Age__c // Ensure Age__c is a custom field on Contact
);
// Add the event to the list
events.add(event);
}
if (!events.isEmpty()) {
EventBus.publish(events);
}
}
2. Platform Event Trigger to Handle the Event and Call External Systems
trigger ContactCreationEventTriggers on ContactCreationEvent__e (after insert) {
for (ContactCreationEvent__e event : Trigger.New) {
ExternalService.sendContactToExternal(event.Name__c, event.Age__c);
}
}
3. Apex Class to Integrate with ExternalSystem
public class ExternalService {
@future(callout=true)
public static void sendContactToExternal(String contactName, Decimal age) {
try {
List<FirestoreConfig__mdt> configs = [SELECT API_Key__c, Endpoint_URL__c FROM FirestoreConfig__mdt LIMIT 1];
if (configs.isEmpty()) {
return;
}
String apiKey = configs[0].API_Key__c;
String endpoint = configs[0].Endpoint_URL__c;
HttpRequest req = new HttpRequest();
Http http = new Http();
String finalEndpoint = endpoint + '?key=' + apiKey;
req.setMethod('POST');
req.setEndpoint(finalEndpoint);
req.setHeader('Content-Type', 'application/json');
String body = '{' +
'"fields": {' +
'"name": {"stringValue": "' + contactName + '"},' +
'"age": {"integerValue": ' + age + '}' +
'}' +
'}';
req.setBody(body);
HttpResponse res = http.send(req);
if (res.getStatusCode() == 200 || res.getStatusCode() == 201) {
} else {
System.debug('Error sending contact to Firestore: ' + res.getStatusCode() + ' - ' + res.getBody());
}
} catch (Exception e) {
System.debug('Exception: ' + e.getMessage());
}
}
}
Friday, 6 September 2024
RestAPI To Display Nifty 50 Historical Data
Apex Class QuandlApiService
public class QuandlApiService {
@AuraEnabled(cacheable=true)
public static String fetchNifty50Data() {
try {
// Fetch custom metadata for API configuration
API_Configuration__mdt config = [SELECT API_Endpoint__c, API_Key__c FROM API_Configuration__mdt WHERE DeveloperName = 'Quandl_Nifty50' LIMIT 1];
// Create an HTTP request
HttpRequest req = new HttpRequest();
Http http = new Http();
// Set the endpoint URL with the API key from metadata
String url = config.API_Endpoint__c + '?api_key=' + config.API_Key__c;
req.setEndpoint(url);
req.setMethod('GET');
// Send the request and get the response
HttpResponse res = http.send(req);
// Check the status code for success
if (res.getStatusCode() == 200) {
// Parse the JSON response
Map<String, Object> responseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
Map<String, Object> dataset = (Map<String, Object>) responseMap.get('dataset');
// Debug the response structure
System.debug('Full Response: ' + responseMap);
// Get the list of column names
List<Object> columnNames = (List<Object>) dataset.get('column_names');
// Get the actual data
Object rawData = dataset.get('data');
// Debug the raw data
System.debug('Raw Data: ' + rawData);
// Initialize the result
String result = 'Nifty50 Data:\n';
// Handle different data structures
if (rawData instanceof List<List<Object>>) {
// Handle List of Lists
List<List<Object>> data = (List<List<Object>>) rawData;
for (List<Object> row : data) {
for (Integer i = 0; i < columnNames.size(); i++) {
result += (String) columnNames[i] + ': ' + String.valueOf(row[i]) + ', ';
}
result += '\n';
}
} else if (rawData instanceof List<Object>) {
// Handle Flat List
List<Object> data = (List<Object>) rawData;
for (Integer i = 0; i < columnNames.size(); i++) {
result += (String) columnNames[i] + ': ' + String.valueOf(data[i]) + '\n';
}
} else {
result += 'Unexpected data format';
}
return result;
} else {
return 'Failed to fetch data. Status code: ' + res.getStatusCode();
}
} catch (Exception e) {
System.debug('Error occurred: ' + e.getMessage());
return 'Error occurred: ' + e.getMessage();
}
}
}
Nifty50Card Js Code
import { LightningElement,wire,track } from 'lwc';
import fetchNifty50Data from '@salesforce/apex/QuandlApiService.fetchNifty50Data';
export default class Nifty50Data extends LightningElement {
@track data;
@track error;
@wire(fetchNifty50Data)
wiredNifty50Data({ error, data }) {
if (data) {
this.data = data;
this.error = undefined;
} else if (error) {
this.data = undefined;
this.error = error.body.message;
}
}
}
Nifty50Card Html Code
<template>
<lightning-card title="Nifty50 Data">
<template if:true={data}>
<pre>{data}</pre>
</template>
<template if:true={error}>
<p class="slds-text-color_error">{error}</p>
</template>
</lightning-card>
</template>
Please Click Link Output Result
1. User Submits Account Form
The user enters Name, Email, and Phone in a Lightning Web Component (LWC).
Clicking Submit triggers a call to an Apex method (sendAccountData).
2. Data Sent to External API
The Apex method sends account details to an external system via an API request.
The external system creates a new account and returns a unique External System ID.
3. Account Created in Salesforce
A new Account record is inserted in Salesforce.
The response from the external system is processed:
If an id is received, it is stored in the External_Id__c field on the Salesforce Account.
If no ID is returned, an appropriate message is stored.
4. Two-Way Synchronization Achieved
Salesforce and the external system are now linked via the External System ID.
Future updates can be synchronized based on this ID for real-time integration.