2

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?

Thanks!

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;
    }
}

1 Answer 1

0

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);
                if(String.isNotBlank(headerValue)){
                    inlineAttachments.put(headerValue, toAttachment(em.Id, bAttachment));
                }
                else{
                    attachments.add(toAttachment(em.Id, bAttachment));
                }
            }
        }

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

        System.debug(inlineAttachments.keySet());

        //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);
    }



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


@TestVisible
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;
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .