In Salesforce, you can send emails programmatically using Apex code. When you need to include attachments in your emails, the Messaging.EmailFileAttachment class allows you to attach files seamlessly. This example demonstrates how to send an email with an attachment using EmailFileAttachment.

Sending Email attachment by using Apex

How to send email attachment by using Apex? By using EmailFileAttachment class we can send an attachment. We can use this SingleEMailMesSage to send attachments.

Below are the methods in EmailFileAttachment class.

  • setBody(Blob) : To set the attachment.
  • setContentType(String) : To set content type of the attachment.
  • setFileName(String) : To set the attachment file name.
  • setInline(Boolean) : Used to specify content description.

See the below example to understand EmailFileAttachment:

bookdetails vf page

We will send the below Visualforce page as an attachment.

<apex:page standardController="Books__c" renderAs="pdf">
<apex:pageBlock >
<apex:pageBlockSection columns="1">
<apex:outputField Value="{!Books__c.Name}"/>
<apex:outputField Value="{!Books__c.Title__c}"/>
<apex:outputField Value="{!Books__c.price__c}"/>
<apex:outputField Value="{!Books__c.Publisher__c}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>

attachmentExample

This controller is having logic to send attachment in an email.

public class attachmentExample{
	Books__c book;
	
	public attachmentExample() 	{
		book = [select id,name from Books__c where Id = :ApexPages.currentPage().getParameters().get('id')];
	}
	
	public pagereference sendAttach() {
		Messaging.SingleEmailMessage semail = new Messaging.SingleEmailMessage();
		Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
		PageReference pref = page.bookdetails;
		pref.getParameters().put('id',(String)book.id);
		pref.setRedirect(true);
		Blob b = pref.getContent();
		attach.setFileName('BookDetails.pdf');
		attach.setBody(b);
		semail.setSubject('Book details');
		String[] sendTo = new String[]{'XXXXXXXXX@gmail.com'};
		semail.setToAddresses(sendTo);
		semail.setPlainTextBody('Please find the attached book details');
		semail.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});
		Messaging.sendEmail(new Messaging.SingleEmailMessage[]{semail});
		return null;
	}
}

To test sending an email with an attachment, create detail button to execute above logic in object & add that button in detail page.

Sending Email attachment Scenario

Suppose you need to send a PDF invoice to a customer via email. The PDF file is stored in Salesforce as a ContentVersion record. You want to retrieve this file and attach it to an email sent to the customer.

Step-by-Step Example

1. Retrieve the File to Attach

First, query the ContentVersion object to retrieve the file you want to attach. Replace '068XXXXXXXXXXXXXXX' with the actual ContentVersion Id of your file.

// Query the ContentVersion record
ContentVersion cv = [
    SELECT Id, Title, VersionData, ContentDocumentId
    FROM ContentVersion
    WHERE Id = '068XXXXXXXXXXXXXXX'
    LIMIT 1
];
  • VersionData: Contains the binary data of the file.
  • Title: The name of the file.

2. Create the Email Attachment

Use the Messaging.EmailFileAttachment class to create the attachment.

// Create a new EmailFileAttachment instance
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();

// Set the binary content of the attachment
attachment.setBody(cv.VersionData);

// Set the filename (optional: add file extension if needed)
attachment.setFileName(cv.Title + '.pdf');

// Set the MIME type of the attachment
attachment.setContentType('application/pdf');

// Specify whether the attachment is inline or not
attachment.setInline(false);

3. Prepare the Email Message

Create an instance of Messaging.SingleEmailMessage and set the necessary properties.

// Create a new SingleEmailMessage instance
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

// Set the recipient's email address
email.setToAddresses(new String[] { 'customer@example.com' });

// Set the email subject
email.setSubject('Your Invoice from Our Company');

// Set the email body (plain text or HTML)
email.setPlainTextBody('Dear Customer,\n\nPlease find attached your invoice.\n\nBest regards,\nCompany Name');

4. Attach the File to the Email

Add the attachment to the email message.

// Add the attachment to the email
email.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment });

5. Send the Email

Use the Messaging.sendEmail method to send the email.

// Send the email
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });

Complete Apex Class Example

public class EmailWithAttachmentSender {
    public static void sendInvoiceEmail(String recipientEmail, Id contentVersionId) {
        // Step 1: Retrieve the file to attach
        ContentVersion cv = [
            SELECT Id, Title, VersionData, ContentDocumentId
            FROM ContentVersion
            WHERE Id = :contentVersionId
            LIMIT 1
        ];

        // Step 2: Create the email attachment
        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
        attachment.setBody(cv.VersionData);
        attachment.setFileName(cv.Title + '.pdf');
        attachment.setContentType('application/pdf');
        attachment.setInline(false);

        // Step 3: Prepare the email message
        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
        email.setToAddresses(new String[] { recipientEmail });
        email.setSubject('Your Invoice from Our Company');
        email.setPlainTextBody('Dear Customer,\n\nPlease find attached your invoice.\n\nBest regards,\nCompany Name');

        // Step 4: Attach the file to the email
        email.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment });

        // Step 5: Send the email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });
    }
}

Usage:

// Replace with the recipient's email and the ContentVersion Id of the file
EmailWithAttachmentSender.sendInvoiceEmail('customer@example.com', '068XXXXXXXXXXXXXXX');

Explanation

  • Retrieving the File: The ContentVersion object is used to store files in Salesforce. By querying this object, you can retrieve the file’s binary data (VersionData) and metadata.
  • Creating the Attachment: An instance of Messaging.EmailFileAttachment is created, and its properties are set:
  • setBody(Blob body): Sets the binary content of the attachment.
  • setFileName(String fileName): Sets the name of the attachment file.
  • setContentType(String contentType): Sets the MIME type of the attachment (e.g., application/pdf for PDF files).
  • setInline(Boolean inline): Determines if the attachment is displayed inline with the email body.
  • Preparing the Email: A Messaging.SingleEmailMessage object is created to represent the email. Essential properties like recipients, subject, and body are set.
  • Attaching the File: The attachment is added to the email using the setFileAttachments method, which accepts a list of EmailFileAttachment objects.
  • Sending the Email: The Messaging.sendEmail method sends the email. It accepts a list of email messages to send.

Important Considerations

  • Permissions: Ensure that the running user has access to the ContentVersion record and the necessary permissions to send emails.
  • Governor Limits: Be aware of Salesforce governor limits, especially if sending emails inside loops or triggers. The maximum number of sendEmail methods allowed per transaction is 10, each with up to 100 recipients.
  • Error Handling: Include try-catch blocks to handle exceptions that may occur during the email sending process.
  • File Size Limitations: The maximum size of email attachments is 3 MB per file and 25 MB total for all attachments on a single email.

Alternative: Using Attachments from the Attachment Object

If your file is stored as an Attachment object rather than a ContentVersion, you can modify the code as follows:

// Query the Attachment record
Attachment att = [
    SELECT Id, Name, Body
    FROM Attachment
    WHERE Id = :attachmentId
    LIMIT 1
];

// Create the email attachment
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
attachment.setBody(att.Body);
attachment.setFileName(att.Name);
attachment.setContentType('application/pdf');
attachment.setInline(false);

Conclusion

By leveraging the Messaging.EmailFileAttachment class in Apex, you can programmatically send emails with attachments in Salesforce. This approach is useful for automating communication with customers, sending reports, invoices, or any files stored within your Salesforce organization.