0

I am trying to store the attachments from an incoming email to the ContenDocument, ContentVersion, and ContentDocumentLink objects. Below is the method/function:

@testVisible
    private static void createContentAttachment(String parentRecordId, Messaging.InboundEmail email) {
                
        List<ContentVersion> cvList = new List<ContentVersion>();
        List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
        
        try {
            for (Messaging.Inboundemail.BinaryAttachment binAttach : email.binaryAttachments) {
                ContentVersion conVer = new ContentVersion();
                conVer.Title = binAttach.fileName;
                conVer.PathOnClient = binAttach.fileName;
                conVer.VersionData = binAttach.Body;
                conVer.ContentLocation = 'E'; 
                cvList.add(conVer);
            }
            
            if(cvList.size()>0){
                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 = parentRecordId;
                cl.ShareType = 'V';
                cl.Visibility = 'AllUsers';
                cdlList.add(cl);
            }
            
             if(cdlList.size()>0){
                insert cdlList;
             } 
        } catch (Exception e) {
            System.debug('Exception has occured on createContentAttachment : ' + e.getMessage());
        }
    }

I get the following error when the code is executed:

USER_DEBUG [257]|DEBUG|Exception has occured on createContentAttachment : Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [External Data Source]: [External Data Source]

I don't understand the field 'External Data Source' because I could not find it in any object.

1 Answer 1

1

The values for ContentVersion.ContentLocation are:

  • S — Document is located within Salesforce. Label is Salesforce.
  • E — Document is located outside of Salesforce. Label is External.
  • L — Document is located on a social network and accessed via Social Customer Service. Label is Social Customer Service.

If you use E you must also set the field ExternalDataSourceId and created file will have a size of 0 Kb, it'll be just a link to a file stored outside of Salesforce.
Since you're adding a body, I think you want to store the whole file in Salesforce, so you should change conVer.ContentLocation = 'E'; to conVer.ContentLocation = 'S';

By the way, there is no need to check the size of the list before a dml: running a dml against an empty list will not count against governor limits.

2
  • Thank you for your answer. It worked for me. The only issue I am getting is that when I attach the '.txt' file to an email, it does not create file record in SF. The code does work for png, jpeg, word, xlxs, and pdf.
    – Marjan
    Jun 19, 2023 at 15:52
  • @Marjan png, jpeg, pdf, etc... are binary file, so binaryAttachments property is the right one, but for text attachments InboundEmail class uses textAttachments property. Most likely you need a for-loop over email.textAttachments
    – RubenDG
    Jun 19, 2023 at 17:11

You must log in to answer this question.

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