0

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?

3
  • Well if the trigger is not fired on attachment, then you don't have an option there. But even if let's say your Task was still created after sometime, are you not able to fetch the sent emails in that flow and then create attachments there? Even though there's a time lag, but it should still work. – Jayant Das Aug 16 '18 at 18:50
  • Not quite sure, haven't really tried it out. But because you mentioned you at least get to have the Task trigger fired and create the record, so that may be an option. – Jayant Das Aug 16 '18 at 19:14
  • The order of execution is 1) comm__c gets inserted 2) Task gets inserted then 3) EmailMessage. So I'm getting 0 records for the query [SELECT id from EmailMessage WHERE ActivityID in: emailTasks] – Jarvis Aug 17 '18 at 12:44
0

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

        }

}

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.