Sunday, August 20, 2023

Open Standard Email composer from LWC Component - Global Email Quick Action

As we all know that we can create Email Actions in Salesforce but capability to invoke Email Action from LWC components was not present. After Winter' 23, Salesforce allowed to invoke global email action from custom components (from Aura and LWC both).

In this blog, I am going to explain how to invoke email action from LWC component. You can launch email composer from custom button. 

We have to use the lightning-navigation and lightning-page-reference-utils components to create a QuickAction (Global) Send Email action, which opens an email draft with pre-populated field values.

We will create simple LWC component which will have button. Once we click on this button, email composer will open. Below is sample code for reference:

<template>
<lightning-card title="Launch Standard Email Composer in LWC">
<div style="background-color:#E6E6FA;border-style: solid;height:200px;margin:5%;padding:2%;">
<lightning-button variant="neutral" label="Send an Email" onclick={onButtonClick}></lightning-button>
</div>
</lightning-card>
</template>
import { LightningElement , api, track} from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import { encodeDefaultFieldValues } from 'lightning/pageReferenceUtils';
import findEmailInfo from '@salesforce/apex/skStandardEmailComposerController.findEmailInfo';
export default class SkStandardEmailComposer extends NavigationMixin(LightningElement) {
@api emailInfo;
@api error;
connectedCallback(){
this.findEmailInformation();
}
findEmailInformation(){
findEmailInfo()
.then((result) => {
this.emailInfo = result;
console.log('***email details-'+JSON.stringify(this.emailInfo));
})
.catch((error) => {
this.error = error;
});
}
onButtonClick(){
console.log('***onButtonClick-recordRelatedToId:'+this.emailInfo.recordRelatedToId);
var pageRef = {
type: "standard__quickAction",
attributes: {
apiName: "Global.SendEmail"
},
state: {
recordId: this.emailInfo.recordRelatedToId,
defaultFieldValues:
encodeDefaultFieldValues({
HtmlBody : "Pre-populated text for the email body.",
Subject : "Pre-populated Subject of the Email",
CcAddress : this.emailInfo.ccAddress.join(','),
ToAddress : this.emailInfo.toAddress.join(','),
ValidatedFromAddress : this.emailInfo.fromAddress,
})
}
};
this[NavigationMixin.Navigate](pageRef);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>58.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
public class skStandardEmailComposerController {
@AuraEnabled
public static emailWrapper findEmailInfo(){
emailWrapper returnValue= new emailWrapper();
//you can implement your own logic to
returnValue.ccAddress.add('sk111111demo@gmail.com');
returnValue.ccAddress.add('sk22222demo@gmail.com');
returnValue.toAddress.add('skemailtocaseEmail1@gmail.com');
returnValue.fromAddress='skcurrentUser@gmail.com';//make sure it is some user address or org wide address
returnValue.recordRelatedToId=[select id from Account Limit 1].Id;
return returnValue;
}
//in wrapper you can define define ccAddress,toAddress,from address, emailBody,EmailSubject
public class emailWrapper{
@auraEnabled
public string recordRelatedToId;
@AuraEnabled
public List<string> ccAddress;
@AuraEnabled
public List<string> toAddress;
@AuraEnabled
public string fromAddress;
public emailWrapper(){
ccAddress = new List<String>();
toAddress = new List<String>();
}
}
}


Note:

  • You can default email properties like subject, body, ccAddress, toAddress and fromEmailAddress.
  • You always need to provide record. Whenever you click on send button after composing email, system will create an emailmessage record with relatedToId as specified recordId.
  • encodeDefaultFieldValues is being provide to specify all default values.

Snapshots for reference:




Hope this will help!!






Thursday, August 3, 2023

Automatically Remove Special Characters from Filename while Uploading Files in Salesforce

 As we all know that we can perform URL hack to download all files related to parent record from salesforce. We have observed that sometime downloaded file name is changed to contentversion recordId by salesforce instead of actual file name. 

It is my observation that if file name contains special characters, then when we perform download All, file name is changed to "068xxxxxxxxxxxxxx.pdf".

I have added 2 files to account record for reference:



Now I can generate download URL if I have contentversionId of these 2 files. In my case the download URL will be:

https://xxxx/sfc/servlet.shepherd/version/download/0680K00000kLSdbQAG/0680K00000kLSfwQAG

where xxxx is you org domain URL.

You can use below script to generate download all files URL if you know the parent record Id.

string parentRecordId='0012800001IrqlyAAB';
string orgbaseUrl=URL.getSalesforceBaseUrl().toExternalForm();
string downloadAllFileUrl=orgbaseUrl+'/sfc/servlet.shepherd/version/download';
List<string> contentVersionIdList = new List<string>();
for(ContentDocumentLink cdl:[SELECT ContentDocumentId,ContentDocument.title,ContentDocument.LatestPublishedVersionId FROM ContentDocumentLink where LinkedEntityId =:parentRecordId]){
contentVersionIdList.add(string.valueof(cdl.ContentDocument.LatestPublishedVersionId));
}
downloadAllFileUrl = downloadAllFileUrl +'/'+string.join(contentVersionIdList,'/');
system.debug('***downloadAllFileUrl:'+downloadAllFileUrl);

If I open this URL, I will zip file which will contain both files and when I will extract it, it will appear as shown below:


As my observation, if any special character is present in file name then salesforce changes the file name. If "-" character is present, then salesforce won't change file name.

For this kind of scenarios, I recommend to have script in place which will remove all special characters from file name whenever file is being uploaded. You can write trigger on contentVersion object to remove special characters from file name. Below is code snippet which can help:



//purpose- remove special characters from file names when uploaded in salesforce
trigger SK_ContentVersionTrigger on ContentVersion (before insert) {
for(ContentVersion cv: trigger.new){
if(string.isNotBlank(cv.Title)){
cv.Title= cv.Title.replaceAll('[^-a-zA-Z0-9\\s+]', '');
System.debug('***updated Title '+cv.Title);
}
}
}
Hope this will help!!!!