Below is what I am trying to do -

  1. migrating users from one org to another
  2. as a part of this "email to case" will be migrated as well
  3. open cases from "old org" will be migrated to "new org" with case id from old org saved as "external id" field on new org case object
  4. After the migration, if customer replies to the email that corresponds to open case and has thread id (ref:_00Dxxxxx._500xxxxxxxx:ref) from the old org, i need to associate such email messages to corresponding migrated case in the new org

I have before insert trigger on EmailMessage which is looking for incoming emails and associating these emailmessage to existing case in the new org. Within the trigger, I am updating "ParentId" and "ReleatedToId" field on EmailMessage, if incoming email thread id is from old org.

Actual Result:

I see that email message is correctly being related to existing case BUT I also see a new case created. When Before insert trigger hits, I already see "ParentId" and "RelatedToId" field on the EmailMessage populated with newly created case id, before I update these IDs in my trigger code

Why salesforce is creating new case ? is it possible to prevent creating of new case ?

Below is the code as requested, below is my trigger handler on EmailMessage

public class EmailMessageTriggerHandler {

 public static void handle(List<EmailMessage> newEmailMessageList,
                          Map<Id, EmailMessage> newEmailMessageMap,
                          List<EmailMessage> oldEmailMessageList,
                          Map<Id, EmailMessage> oldEmailMessageMap,
                          Boolean isBefore,
                          Boolean isAfter,
                          Boolean isInsert,
                          Boolean isUpdate,                              
                          Boolean isDelete)
             for(EmailMessage msg: newEmailMessageList)
                //at this point for incoming emailmessage with thread id not associated with org in which trigger is running,
                // parent id and relatedtoId is already populated with Id of the newly created case
                 system.debug('msg is incoming - ' + msg.Incoming);
                 system.debug('msg thread id - ' + msg.ThreadIdentifier);
                 system.debug('msg status - ' + msg.Status);
                 system.debug('msg subject - ' + msg.Subject);
                 system.debug('msg parent id - ' + msg.ParentId);
                 system.debug('msg related to id - ' + msg.RelatedToId);
                 system.debug('msg body - ' + msg.TextBody);

             ProcessMessageForOldCases(newEmailMessageList, newEmailMessageMap);


public static void ProcessMessageForOldCases(List<EmailMessage> newEmailMessageList, Map<Id, EmailMessage> newEmailMessageMap)
    Map<Id, String> oldCaseMessageToThreadMap = new Map<Id, String>();

    RecordType rt = [SELECT Id,DeveloperName FROM RecordType WHERE SobjectType='Case' AND DeveloperName='My_Record_type' LIMIT 1];

    //Legacy_Case_Id__c is external id - containts 15 digit case id from old org

    List<Case> oldCases = [select Id, Legacy_Case_Id_Short__c from Case where RecordTypeId =:rt.Id AND Legacy_Case_Id__c LIKE '500%'];

    for(EmailMessage msg: newEmailMessageList)
            //get thread id
            string emailthreadid = getThreadId(msg.Subject);                
                    //check if email message thread is from this org and case from this org
                    Id caseid = Cases.getCaseIdFromEmailThreadId(emailthreadid);                        
            catch(Exception exp)
                //if exception, incoming email contains thread id that corresponds to old org

                string oldcaseshortidfromEmail = '';

                string[] parts = emailthreadid.split('._');
                if(parts != null && parts.size() > 1)
                    if(String.isNotBlank(parts[parts.size() - 1]) )
                        oldcaseshortidfromEmail = parts[parts.size() - 1];

                //find it in existing cases
                for(Case oldcase: oldCases)
                    //do case sensitive comparison
                    //Legacy_Case_Id_Short__c is formula field which converts 15 digit Legacy_Case_Id__c to format that is in thread id - 500xxxxxxxx
                    String oldcaseshortid = oldcase.Legacy_Case_Id_Short__c;                        
                        system.debug('match found');                            
                        //associate to new case
                        system.debug('updating case association');
                        system.debug('new id = ' + oldcase.Id);
                        msg.ParentId = oldcase.Id;    
                        msg.RelatedToId = oldcase.Id;
                        system.debug('no match found');

            } //end of catch

        }//end of if
    }//end of for                


public static String getThreadId(String subject)
    //return string is in format - _00Dxxxxx._500xxxxxxxx

    String[] parts = subject.split('ref:');
    if(parts!= null)
        //get the last string
        if(parts[parts.size() - 1] != null)
            string[] moreparts = parts[parts.size() - 1].split(':ref');
            if(moreparts != null && String.isNotBlank(moreparts[0]))
                return moreparts[0];

    return '';


  • @SantanuBoral , in my case, incoming email already has thread id in subject and body but that thread id belongs to old org and doesn't belong to org where this trigger is executing. Within the trigger, I am trying to associate it to existing case – apn Sep 17 '17 at 4:29
  • 1
    I think, because of old org, salesforce is creating new cases. Salesforce tries to attach the replies into same cases if matching threadId is found. You can try creating InboundEmailHandler to attach the email in same case – Santanu Boral Sep 17 '17 at 4:29
  • You've not shown your code, but it sounds as though you need to be doing an update to the related case or some kind of upsert operation rather than just an insert operation on the email. Would help immensely if you posted code. Also, since you're specifying a ParentId, that' would seem to be a likely cause of creation of new case. – crmprogdev Sep 17 '17 at 4:47
  • @crmprogdev only updating parentld will not solve the issue. Salesforce internally maps through Email header information I think. – Santanu Boral Sep 17 '17 at 4:57
  • @SantanuBoral More than anything, it would seem he may need to start with the related case is where I was coming from and updating it with the new email attachment, but that's speculation on my part. Is difficult when you migrate data from one org to another. – crmprogdev Sep 17 '17 at 5:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.