0

I am using the custom email service to receive an email with an attachment. I can create a custom object record and associate the email attachments with it. Since the direction is to move away from attachments, I want to be able to create files with the record instead of attachments. Has anyone done this?

2 Answers 2

7

Salesforce files have superseded attachments. A single attachment can have only one parent and access to attachments is controlled by the parent record. If we want to attach same file on two different records then we would need to upload that attachment to a new record thus consume extra storage and having redundant files. The same two limitations are handled by Salesforce files.

Salesforce files has 2 components

  1. Actual File (ContentVersion)
  2. Its Sharing and Parent records attachability. (ContentDocumentLink)

Thus in your email service, you have to iterate over your email attachments and create contentDocument and ContentDocumentLink

global class MyEmailHandler implements Messaging.InboundEmailHandler {

global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {



    List<ContentVersion>cvList = new List<ContentVersion>();
    List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
    for (Messaging.InboundEmail.BinaryAttachment binAttach : email.binaryAttachments) {
        ContentVersion testContentInsert = new ContentVersion();
        testContentInsert.Title = binAttach.fileName;
        testContentInsert.VersionData = binAttach.body;
        testContentInsert.PathOnClient = '/' + binAttach.fileName ;
        cvList.add(testContentInsert);

    }
    insert cvList;
    cvList = [select id, ContentDocumentId from ContentVersion WHERE Id in :cvList];
    for (ContentVersion cv : cvList) {
            ContentDocumentLink cl = new ContentDocumentLink();
            cl.ContentDocumentId = cv.ContentDocumentId;
            cl.LinkedEntityId = '001123456789632'; //Shared with record ID
            cl.ShareType = 'V';
            cl.Visibility = 'AllUsers';
            cdlList.add(cl);



    }
    insert cdlList;

    }
} 
1
  • Thanks for the help. I am trying to understand the code. On which line, I am passing the caseid(parentid). Also, where do I need to add this code. Just createan apex class in Salesforce?
    – Student
    Apr 2, 2019 at 16:17
0

Thank you! This was awesome. The only change I made was to link the attachment to the email that was created by the inbound email handler. I use a Quick Action to add "ref: recordId" to the email so that SF knows which record to link the email to. I link "Market_Intelligence_Reports__c" (lookup field) to the email so it shows up in a related list.

global with sharing class attachEmailToMIReports implements Messaging.InboundEmailHandler {
//handler overwrite
global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, 
                                                    Messaging.InboundEnvelope env) {
//local variables
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
String myPlainText= '';
myPlainText = email.plainTextBody;
Integer i = myPlainText.indexOf('ref:',0);                                                   
String objectId = myPlainText.substring(i+5, i+20);
System.debug('recordId '+objectId);
     try {
        EmailMessage            createEmail = new EmailMessage(
             Subject                        = email.Subject
            ,Status                         = '2'
            ,FromAddress                    = email.fromAddress
            ,FromName                       = email.fromName
            ,Headers                        = JSON.serialize( email.headers )
            ,HtmlBody                       = email.htmlBody
            ,TextBody                       = email.plainTextBody
            ,Incoming                       = true
            ,MessageDate                    = DateTime.now()
            ,RelatedToId                    = objectId
            ,Market_Intelligence_Reports__c = objectId
        );
        insert createEmail;
        System.debug('Created Email'+createEmail.Id);

        List<ContentVersion>cvList = new List<ContentVersion>();
        List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
        for (Messaging.InboundEmail.BinaryAttachment binAttach : email.binaryAttachments) {
            ContentVersion testContentInsert = new ContentVersion();
            testContentInsert.Title = binAttach.fileName;
            testContentInsert.VersionData = binAttach.body;
            testContentInsert.PathOnClient = '/' + binAttach.fileName ;
            cvList.add(testContentInsert);
            system.debug('Added cvList');

}
        insert cvList;
         cvList = [select id, ContentDocumentId from ContentVersion WHERE Id in :cvList];
        for (ContentVersion cv : cvList) {
           ContentDocumentLink cl = new ContentDocumentLink();
          cl.ContentDocumentId = cv.ContentDocumentId;
          cl.LinkedEntityId = createEmail.Id; //Shared with record ID
          cl.ShareType = 'V';
          cl.Visibility = 'AllUsers';
         cdlList.add(cl);
}
insert cdlList;
         system.debug('insert cdlList'+objectId);
         system.debug('Content Version'+cvlist);
     }
catch (Exception e) {
    System.debug('Email failed ' + e);
}
result.success = true;

return result;
     }

}

This site is temporarily in read-only mode and not accepting new answers.

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