send email in apex salesforce

Salesforce provides method to send emails from apex. We can create a instance of that method, set all the required parameters and then send the emails.

We can set the email addresses to which the email be sent in "setToAddresses", we can give emails seperated by comma. Simialrly bcc,cc email addresses can be seperated by comma . We can specify the body as text or HTMl as desired.

Following is a example wherein emails will be sent to specified addresses upon clicking the button.

Visualforce page
<apex:page controller="SendemailController">
 <apex:form >
   <apex:commandButton value="Send Email" action="{!sendEmailFunction}"/>
 </apex:form>
</apex:page>


Controller
Public with sharing class SendemailController{
   Public SendemailController(){
   }
  
 Public void sendEmailFunction(){
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAddresses = new String[] {'testreceipient1@mail.com','testreceipient1@mail.com'}; 
   String[] ccAddresses = new String[] {'testcc1@mail.com','testcc1@mail.com'};
   mail.setToAddresses(toAddresses);
   mail.setCcAddresses(ccAddresses);
   mail.setReplyTo('myemail@mail.com');
   mail.setSenderDisplayName('My Name');
   mail.setSubject('Testing email through apex');
   mail.setBccSender(false);
   mail.setUseSignature(false);
   mail.setPlainTextBody('This is test email body. This mail is being sent from apex code');
   //mail.setHtmlBody('<b> This is HTML body </b>' );
   Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 } 

}

You need to specify the existing correct addresses in the lines marked red in abive code.

Can you send email in batch apex ?

Yes, you can send email using batch apex, just the way you would do in any other apex code. The best use case where we normally send mail in batch apex is the finish method (to indicate that the batch apex processing is completed). Monitoring batch apex job can be a time consuming job as you dont know when it will complete. At times the jobs takes longer than expected, it all depends on the salesforce resources. Thus if a admin is needed to check when the job completes, the best solution would be to have a email triggered once the job completes (that is the finish method of batch apex class). Below is the code that sends an email once the batch job execution completes, a email notification that helps to know that the processing is done.

global class batchjobexample implements database.batchable<sobject>{
Public string soqlquery;
global String [] email = new String[] {'yoganand252358@gmail.com'};
 Public standardExpJob (){
    this.soqlquery = 'Select name from account limit 10'; 
 }
 global database.querylocator start(database.batchableContext bc){
    return database.getquerylocator(soqlquery);
 }

 global void execute(database.batchablecontext bd, list<sObject> sc){
   //Some processing here
 }

 Public void finish(database.batchableContext bc){
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setToAddresses(email);
      mail.setReplyTo('batchprocessingsupport@cf4u.com'); // Add here your email address
      mail.setSenderDisplayName('Batch Processing user');
      mail.setSubject('Batch Execution Completed');
      mail.setPlainTextBody('This email marks the completion of batch job');
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});   
 }
}

Next lets see if we can send an email from execution method. Well, we can send an email from execution method as wel but you need ti be more careful while this. This can be sued to send email that indicates batch apex status. It depends on the use case though, but yes you can send email during execution.Below code sends email in execution method. It send same email 10 times as the execute method will execute 10 times and there is no check in place.


global class standardExpJob implements database.batchable<sobject>{
Public string soqlquery;
global String [] email = new String[] {'yoganand252358@gmail.com'};
 Public standardExpJob (){
    this.soqlquery = 'Select name from account limit 10'; 
 }
 global database.querylocator start(database.batchableContext bc){
    return database.getquerylocator(soqlquery);
 }

 global void execute(database.batchablecontext bd, list<sObject> sc){
   //trying to send email from execute method
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setToAddresses(email);
      mail.setReplyTo('batchprocessingsupport@cf4u.com'); // Add here your email address
      mail.setSenderDisplayName('Batch Processing user');
      mail.setSubject('Batch Execution in process');
      mail.setPlainTextBody('This email is sent from execution method');
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail}); 
 }

 Public void finish(database.batchableContext bc){
      
 }
}

how to send mass email through apex in salesforce.

You can MassEmailMessage for sending mass email apex, but remember these can be sent only to org internal users (contact, lead, person accounts and users)
lets see an example for Sending mass emails in apex.

public Set<Id> contactIdSet = new Set<Id>();
for(contact con : [select id from contact limit 80]){
   contactIdSet.add(con.Id);
}
Messaging.MassEmailMessage massmail = new Messaging.MassEmailMessage();
mail.setTargetObjectIds(contactIdSet);
mail.setTemplateID('set template id here');
Messaging.sendEmail(new Messaging.MassEmailMessage[] {massmail});

In above example the code sends email to 80 contacts. <As of today the number of receipients can be not more than 250 for this. Also, remember you should use setTargetObjectIds and not setTargetObjectId while using Messaging.MassEmailMessage> 

Governors limit in apex email

When you use apex for sending email, you need to be extra carefull so that you dont hit the governors limit associated with this. lets see what all limits we have in sending single and mass email in apex.
- while setting to field in SingleEmailMessage the maximum number of address can be 100 max.
- bcc and cc receipients can be upto 25 for each SingleEmailMessage.
-  a total 10 sendEmail  methods are allowed per transaction
- you can send single emailsusing apex to a maximum of 5000 external email address per day (same limti applies to sending mass email in paex too)
- there is no day limit for sending email to org internal users (so as to make sure you are sending the email to org internal user , you need to set setTargetObjectId) this actually means you send emails to user, contact, lead , person account or users directly from account, opportunity, lead, contact, case, campaign or custok object.
- both single email and mass email dont take unique address into count. That means a email "mytestemai@cf4" if included 20 times than it will count as 200 rather that one.


Can you Send email in trigger ?

Yes, you can send an eamil alert from salesforce apex trigger. But you need to be very careful in doing this as there are good chances that you will hi daily limit for apex email if your code does not have proper checks in place. You can try below code to learn how to send email alert using apex trigger.

trigger beforeupdateOnLead on Lead (before update) {

    Set<String> emailSet  = new Map<String,String>();
    for(lead lea : trigger.new){
if(lea.sendemailalert__c == true){
   emailSet.add(lea.Email); 
}
}
    
  List<Messaging.SingleEmailMessage> trgrmails =  new List<Messaging.SingleEmailMessage>();
  
  for (Lead leadRec : Trigger.new) {
if (leadRec.Email != null) {      
  Messaging.SingleEmailMessage tgmail =  new Messaging.SingleEmailMessage();        
  List<String> sendToList = new List<String>();      
  if(emailSet){
  sendToList.add(emailSet);
  tgmail.setSenderDisplayName('Sender Name');
  tgmail.setSubject('Sendin a mail from trigger');
  tgmail.setToAddresses(sendToList);
  tgmail.setReplyTo('supportcf4@cf4u.com');                  
  String body = 'This is email body sent from trigger';          
  tgmail.setHtmlBody(body);
  trgrmails.add(tgmail);
  }
}
  }

  Messaging.sendEmail(trgrmails);
}

How to send email using template in apex

We can set up body for the email that we send in apex, but if you have a email template already defined and you want to use it in the email that you are sending. Lets see how we can use template while sending email in apex. You need ti use setTargetObjectId if you want to use email template while sening the mail in apex. Below example uses eamil template.
setTargetObjectId basically is the id of contact, lead, person account or user. Email of the record is then set as to addressa and you cannot set mail.setToAddresses done in our previous examples above. So this means you cannot send email to addresses that arent on your objects.

List<Messaging.SingleEmailMessage> tmpltmails =  new List<Messaging.SingleEmailMessage>();
for(contact con : conList){
Messaging.SingleEmailMessage templmail =  new Messaging.SingleEmailMessage();   
templmail.setSenderDisplayName('Senders Name');
templmail.setSubject('Sendin a mail using email template');
templmail.setTargetObjectId(con.Id);
templmail.setReplyTo('supportcf4@cf4u.com');                  
templmail.setTemplateId('Your Email Template Id');
templmail.setSaveAsActivity(false);
tmpltmails.add(templmail);
}
Messaging.sendEmail(tmpltmails);


So is there any way you can send email alert to a email address not on any of records? well, theres a way to do this by creating a dummy record. In below example i am creating a dummy contact and then deleting it after the use. This however is not a recommended way of doing it and you need to be extremely careful about it.


Contact conrec = new Contact();
conrec.FirstName = 'connnmae';
conrec.LastName = 'conlastname';
conrec.Email = 'useremail@test.com';
insert conrec;

Messaging.SingleEmailMessage templmail =  new Messaging.SingleEmailMessage();   
templmail.setSenderDisplayName('Senders Name');
templmail.setSubject('Sendin a mail using email template');
templmail.setTargetObjectId(conrec.Id);
templmail.setReplyTo('supportcf4@cf4u.com');                  
templmail.setTemplateId('Your Email Template Id');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { templmail });
//delete the contact afet mail is sent

delete conrec;

3 comments:

  1. Excellent post!!!. The strategy you have posted on this technology helped me to get into the next level and had lot of information in it.
    salesforce training in chennai | salesforce training institute in chennai

    ReplyDelete
  2. what will be the code for sending the email through apex and take the value of email through vf page

    ReplyDelete
  3. what will be the code for sending mail using apex and taking value of mail through vf page

    ReplyDelete