I have put together an Apex class for a Salesforce Email Service. This is taking the email that is sent to the address, taking the subject and email body and creating a record for a custom object I created. I have this functioning almost exactly how I want it to. The only issue I am up against is if I send an email with inline images, it won't display the images inline, it attaches them in the attachments section. Which is fine. Is there a way for the Apex Class, when parsing the email body, to see where an image tag is, and place it with text that says "See [image file name] in attachments below". Or is there a way to get the images to display inline in the rich text field?


Here is my class:

global class createAnnouncement implements
Messaging.InboundEmailHandler {

    // Creates new announcement object  

    Announcements__c[] myAnnouncement = new Announcements__c[0];

    global Messaging.InboundEmailResult handleInboundEmail(
        Messaging.InboundEmail email,
        Messaging.InboundEnvelope envelope) {
        Messaging.InboundEmailResult result =
            new Messaging.InboundEmailresult();

        // Records the senders email address

        String SendersEmail = envelope.fromAddress;

        String AnnouncementName = email.subject;

        // Retrieves and parses content from the email.

        // Takes email body and puts it into a variable to place it into the body field of the new record 

        String AnnouncementBody = email.HtmlBody;

        // Creates a new announcement from the information
        // retrieved from the inbound email  

        try {
            myAnnouncement.add(new Announcements__c(
                Senders_Email__c = SendersEmail,
                Name = AnnouncementName,
                Body__c = AnnouncementBody));

            insert myAnnouncement;
        } catch (System.DmlException e) {
            System.debug('ERROR: Not able to create announcement' + e);

        // Searches the email for binary attachments and
        // associates them with the new announcement record

        if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) {
            for (integer i = 0; i < email.binaryAttachments.size(); i++) {
                Attachment a = new Attachment(
                    ParentId = myAnnouncement[0].Id,
                    Name = email.binaryAttachments[i].filename,
                    Body = email.binaryAttachments[i].body);
                insert a;

        return result;

You can include the below addition in your Email Handler class to achieve inline image rendering by handling the inbound email header:

private static void handleAttachments(EmailMessage em, Messaging.InboundEmail email) {
        Map<String, Attachment> inlineAttachments = new Map< String, Attachment >();
        List<Attachment> attachments = new List<Attachment>();
        if(email.textAttachments!=null && email.textAttachments.size() >0) {
            for (Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments) {
                attachments.add(toAttachment(em.Id, tAttachment));
        if(email.binaryAttachments!=null && email.binaryAttachments.size() >0) {
            for (Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {
                String headerValue = getImageReference(bAttachment.headers);
                    inlineAttachments.put(headerValue, toAttachment(em.Id, bAttachment));
                    attachments.add(toAttachment(em.Id, bAttachment));

        Database.insert(attachments, false);
        Database.insert(inlineAttachments.values(), false);


        //Process inline images and update the HTML Body
        for(String headerValue : inlineAttachments.keySet()) {
            //Reference Link
            String refLink = '/servlet/servlet.FileDownload?file=' + inlineAttachments.get(headerValue).Id;
            em.HtmlBody = em.HtmlBody.replaceAll('cid:' + headerValue, refLink);

        Database.update(em , false);

    private static Attachment toAttachment(String parentId, Messaging.Inboundemail.BinaryAttachment bAttachment){
        return new Attachment(
            Name = bAttachment.fileName,
            body = bAttachment.body,
            ParentId = parentId,
            ContentType = bAttachment.mimeTypeSubType

private static String getImageReference(List<Messaging.InboundEmail.Header> headers){
    for(Messaging.InboundEmail.Header header: headers){
        if(header.name.startsWith('Content-ID') || header.name.startsWith('X-Attachment-Id') || (header.value.startsWith('ii') || header.value.startsWith('< image'))){
            return header.value.replaceAll('<', '').replaceAll('>', '');
    return null;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.