function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JNicJNic 

Email-to-Case trigger to identify the ToAddress used

Hey all,

 

Our org uses a number of Email-to-Case processes, and we want to identify the ToAddresses used for the generated cases to leverage the workflow capacities. We are designing a IsInsert trigger that will automatically populate a custom field with the value of the ToAddress used.

 

The idea is very similar to the Web Email (SuppliedEmail) default page that associates a case with a originator's email address. In this trigger, we are doing a query for the originator's emailmessage and its information.

 

I'm not sure how to do the following:

1) Locate the email message that created the case. Would the code below locate the email that I'm loolking for?

         list<EmailMessage> email = [
         select
         id, ParentId, ToAddress
         from EmailMessage
         where ParentId = c.id  Limit 1];

2) Locate the ToAddress field. ToAddress in above query should be the Email-to-Case address for the created case c. Is that correct?

 

 

Thanks,

 

vhanson222vhanson222

1) A minor change is that the code you referenced is missing the colon (:) in front of "c.id".  The code below should work:

 

 

list<EmailMessage> email = [
         select
         id, ParentId, ToAddress
         from EmailMessage
         where ParentId = :c.id  Limit 1];

 

 

2) that is correct.  So at this point, if you wanted to put that email address in a custom field called 'OriginAddress'  you would just do something like:

 

c.OriginAddress__c = email.ToAddress;

Have you thought about using the value in the 'Web Email' field to populate your custom field?   This method seems like it would be easier and save you a SOQL query... or is there some 'gotcha' i'm not aware of?  code example below:

 

 

c.OriginAddress__c = c.SuppliedEmail;

 

 

 

JNicJNic

My goal is after Insert of a Email-to-Case case (After Insert) update a custom field called SuppliedToEmail__c with the ToAddress in the original email. Currently the default SuppliedEmail is populated with the FromAddress, so my SuppliedToEmail__c address will map the ToAddress.

 

The key is to correctly query for the email message that created the case. I'm not sure if I'm doing it right though.

 

1) I corrected the select query and consolidated it to account for part 2) per below:

    for (Case c : trigger.new){
        if(c.SuppliedEmail != null){
            
            c.SuppliedToEmail__c = [SELECT ParentId FROM EmailMessage WHERE ParentId=:c.id].ToAddress;
        }
    }

 

But now, I'm getting List has no rows for assignment to SObject error.

 

vhanson222vhanson222

I think the problem is that the EmailMessage is not associated to the newly created Case at the time that the trigger is fired (after insert).  What you really need to do is create a trigger that runs After Update on the EmailMessage object.

 

Think of it like this:

Email Message Comes in (parentId=null because the case that it's tied to does not contain an ID yet) -> Creates Case(case gets id assigned to it after it is inserted) -> EmailMessage is updated to contain a parentId that is equal to the Case Id.

 

What you need to do is have an EmailMessage trigger that fires after update and looks for a 'ParentId' field that was null but now contains a value.

 

 

 

 

trigger EmailMessageAfterUpdate on EmailMessage (after update) {
    for (EmailMessage newEmail : trigger.new){
        // get the email message before it was updated
        EmailMessage oldEmail = System.Trigger.oldMap.get(e.Id);
        // check to see if it now has a ParentId
        if(oldEmail.ParentId == null && newEmail.ParentId != null){
            Case c = [SELECT id, SuppliedToEmail__c FROM Case WHERE Id = :newEmail.ParentId];
            c.SuppliedToEmail__c = newEmail.ToAddress;
update c;
        }
    }
}

 

 

JNicJNic

When you created the oldEmail, did you mean "EmailMessage oldEmail = System.Trigger.oldMap.get(newEmail.Id);"?

 

An error was generated when I used e as it was not defined.

 

I now understand why we an After Update trigger on the Email messages is needed. When I used the code above, however, Case c was NOT updated with the SuppliedToAddress.

 

Also, how should I ensure that the email message with the ParentId created the case? Multiple emails are sent to a case. Wouldn't the above code update the SuppliedToAddress__c on the case with every new email associated with that case?

 

Or, how should I narrow the criteria to trigger only for newly created cases? (IsNew in Salesforce workflow would be handy here).

 

Thanks Victor,

vhanson222vhanson222

 

Yes i meant to put newEmail in place of that e.  

 

 

hm, that's a good point about the fact that there will be many emails associated with a case...

 

Could you ensure that the ToAddress is the same as the email address associated with Email-to-case?

 

i.e.: your email to case email address is  help@1-2gfz0yktggjfsqxv9smxfhh5l.ab3ammaa.f.case.salesforce.com

trigger EmailMessageAfterUpdate on EmailMessage (after update) {
    for (EmailMessage newEmail : trigger.new){
        // get the email message before it was updated
        EmailMessage oldEmail = System.Trigger.oldMap.get(newEmail.Id);
        // check to see if it now has a ParentId
        if(oldEmail.ParentId == null && newEmail.ParentId != null){
            Case c = [SELECT id, SuppliedToEmail__c FROM Case WHERE Id = :newEmail.ParentId];
            // only update the case with the new email if the email was sent to the Email-to-case address
            if (newEmail.ToAddress == 'help@1-2gfz0yktggjfsqxv9smxfhh5l.ab3ammaa.f.case.salesforce.com')
            {
                c.SuppliedToEmail__c = newEmail.ToAddress;
	        update c;
            }
        }
    }
}

 

Assuming this solves the issue with only the initial SuppliedToAddress being populated, i am not sure why Case c would not be updating...  You should try adding some System.debug statements in the trigger and watch the debug log while you test it to see why the case is not updating.

JNicJNic

EmailMessageAfterUpdate is not being invoked.

 

I ran a few test scenarios and monitored the debug log, but the whole trigger is not being invoked. I think EmailMessage is not being used as part of the Email-to-Case feature.

 

I wonder if I need to use the Email Services and its functions here. Something like:

    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();

 

 

 

vhanson222vhanson222

Have you tried changing the trigger to execute 'After Insert' before going down another route?

JNicJNic

Yeah, I tried that too.I also tried doing both at the same time but no luck.

 

I received the error below:

Attempt to de-reference a null object
Vanessa BarrosVanessa Barros

Hi.. i have a question about emailMessage and Case.

When the first email is sent to SF, i want to see if the ccAdress is filled in and do not create if is filled in.

i have tests with this EmailMessage object and cant get any information :(

vhanson222vhanson222

have you used the CcAddress field in your trigger?

 

such as:

 

 

trigger EmailMessageAfterUpdate on EmailMessage (after insert) {
    
    // create a list of cases so that we don't perform too many DML operations in our 'for' loop
    List<Case> cases = new List<Case>();
    for (Integer i = 0; i < Trigger.new.size(); i++ )
    {
    System.debug('******Entering EmailAfterUpdate******');

        EmailMessage newEmail = Trigger.new[i];
        List<Case> c = [SELECT id, Description, caseNumber FROM Case WHERE Id = :newEmail.ParentId];
        if (c.size() > 0 && newEmail.CcAddress == null){
            System.debug('******Entering EmailAfterUpdate\n'+c[0].CaseNumber+'******');
        c[0].Description = newEmail.ToAddress;
            System.debug('******Entering EmailAfterUpdate\n'+c[0].Description+'******');
             //update c;
             cases.add(c);
        }
    }
    update cases;
}

 

hope that helps.

 

Vanessa BarrosVanessa Barros

Yes it helps -  you give me a tip :D