[SalesForce] How to clone “EmailMessage Attachments” to a custom object

I'm leveraging 'Send an Email' button for a custom object(comm__c) which has a lookup to the Case object. The users sends email using this button via Related List on the case page layout.

I'm creating a comm__c record every time an outbound email is sent by writing a trigger on EmailMessage object. I would also like to show attachments added on the email underneath the comm__c record.

For this I wrote the below trigger logic on the Attachment object –

public static void cloneOutboundEmailAttachments(List<Attachment> newList){

         Set<Id> Parents = new Set<Id>();
        List<Attachment> newFiles = new List<Attachment>();

        for (attachment a : newList) {
            if(a.ParentId.getSObjectType() == EmailMessage.getSObjectType())
            Parents.add(a.parentId);
        }

        SYSTEM.DEBUG('EmailMessagesSIZE'+Parents.size());

        if(!parents.isEmpty()){

        Map<Id,EmailMessage> emailMap = new Map<ID, EmailMessage>([SELECT RelatedToId FROM EmailMessage WHERE Id in :Parents]); 

            for (Attachment att : newList) {
                if (att.ParentId.getSObjectType() == EmailMessage.SObjectType) {

                    SYSTEM.debug(att);
                    Attachment newFile = att.clone();
                    newFile.ParentId = emailMap.get(att.ParentId).RelatedToId;
                    newFiles.add(newFile);
                }
             }

        SYSTEM.DEBUG('newFilesSIZE'+newFiles.size());
        Insert newFiles;

        }

     }

To my dismay I found that there is a platform bug which doesn't invoke triggers on Attachment object when user sends email via Related List and adds an attachment file – Trigger on Attachment does not fire when attachment is created via Email

How can I circumvent this issue?

Best Answer

Finally, I wrote a batch class which copies the email attachments to the custom object.

global class BatchforOutboundEmailAttachments implements Database.Batchable<sObject>, Schedulable {


    global Database.QueryLocator start(Database.BatchableContext bc){

        return Database.getQueryLocator([SELECT Name, Body, ParentID from Attachment Where Parent.Type = 'EmailMessage']);

    }


    global void execute(Database.BatchableContext bc, Attachment[] scope){

        set<id> parents = new set<id>();
        List<Attachment> newFiles = new List<Attachment>();
        Map<Id,EmailMessage> emailMap = new Map<Id,EmailMessage>();
        List<Attachment> oldFiles = new List<Attachment>();


            for(Attachment att : scope){
                parents.add(att.ParentID);
            }

            if(!parents.isEmpty()){

       emailMap = new Map<ID, EmailMessage>([SELECT RelatedToId FROM EmailMessage WHERE Id in :Parents]); 

            for (Attachment att : scope) {
              if(emailMap.get(att.ParentId) != Null && emailMap.get(att.ParentId).RelatedToId != NULL){
                if (emailMap.get(att.ParentId).RelatedToId.getSObjectType() == Comm__c.SObjectType) {

                    Attachment newFile = att.clone();
                    newFile.ParentId = emailMap.get(att.ParentId).RelatedToId;
                    newFiles.add(newFile);
                    oldFiles.add(att);

                }
             }
            }     


       try{
            insert newFiles;
            delete oldFiles;
          }

           catch(DMLexception de){}

        }

    }

    global void finish(Database.BatchableContext bc){
     }

    global void execute(SchedulableContext sc){

         ID jobId = Database.executeBatch(this,100); 

        }

}
Related Topic