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
AnnaTAnnaT 

[Urgent] Send Mail Trigger with Apex Data Loader

Please help me...

 

When I insert or update data, the following trigger sends email.

This trigger works when insert or update one data.

But when I try to insert or update multiple data by Apex Data Loader, error occurs.

How can I solve this error?

 

<error>

PDSendEmailtoOC: execution of AfterUpdate
caused by: System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_FIELD_WHEN_USING_TEMPLATE, When a template is specified the plain text body, html body, subject and charset may not be specified : []
Trigger.PDSendEmailtoOC: line 161, column 1
 
trigger PDSendEmailtoOC on RFT_Category__c (after insert,after update) {

  List<RFT_Category__c > pdList= [SELECT Location__c,Object_No__c FROM RFT_Category__c ];
  List<Object_Champion__c> ocList=[SELECT Location__c,Object_No__c,Champion_email__c FROM Object_Champion__c];
  List<AreaCoordinators__c> acList=[SELECT Area__c, Group_Mail_Address__c FROM AreaCoordinators__c];
  String recipient = '';
  List<String> toAddresses= new List<String>();
  List<String> ccAddress = new List<String>();
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  
  for (RFT_Category__c rft : Trigger.new) {
  
    //Rejectの場合、InitiatorにMail
    if(rft.Reject__c==TRUE && rft.E_mail_Address__c<>null){
      //更新前のデータのRejectがFalseの場合のみ送信
      if(trigger.oldMap.get(rft.id).Reject__c==FALSE){
        recipient = rft.E_mail_Address__c;
      
        //一時的にContactを作成。setTargetObjectIdでContactを指定しないとsetWhatIDでCustomObjectを指定できないため。
        Contact tempContact = new Contact(email = recipient , firstName = 'RFT', lastName = 'Temp');
        insert tempContact;

        toAddresses.add(rft.E_mail_Address__c);
        mail.setSenderDisplayName('RFT Auto Mail');
        mail.setTemplateId('00XN0000000DbBw');
        mail.saveAsActivity = false;
        mail.setTargetObjectId(tempContact.id);
        mail.setWhatId(rft.Id); 
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
      
        //Contact削除
        delete tempContact;
      }
    }else if(rft.Location__c<>null && rft.Object_No__c<>null){
    //Rejectでない場合、割り振られたLocationのArea CoordinatorとObjective Champion、InitiatorにMail。変更がない場合はなにもしない。
  
      String [] locationList = rft.Location__c.split(';');
  
      //ObjectNoが異なる場合。
    
      if(Trigger.isUpdate){
        if(trigger.oldMap.get(rft.id).Object_No__c==null || trigger.oldMap.get(rft.id).Object_No__c<>rft.Object_No__c){

          //Set recipients
          for(integer i=0; i<locationList.size(); i++){
        
            //Object Championの宛先設定
            for( Object_Champion__c oc :ocList){
              if( oc.Location__c == locationList[i] && oc.Object_No__c ==rft.Object_No__c ){
                String [] OCMailList = oc.Champion_email__c.split(';');
                for(integer j=0; j< OCMailList.size(); j++){
                  if(i==0&&j==0){
                    recipient=OCMailList[j];
                  }else{
                    toAddresses.add (OCMailList[j]);
                  }
                }
              }             
            }
            //Area Coordinatorの宛先設定
            for(AreaCoordinators__c ac :acList){
              if(ac.Area__c == locationList[i]){
                String [] ACMailList = ac.Group_Mail_Address__c .split(';');
                for(integer m=0; m< ACMailList .size(); m++){
                  toAddresses.add (ACMailList[m]);
                }
              }
            }
          } 
          Contact tempContact = new Contact(email = recipient , firstName = 'RFT', lastName = 'Temp');
          insert tempContact;
          if(rft.E_mail_Address__c<>null){
            ccAddress.add(rft.E_mail_Address__c);
            mail.setCcAddresses(ccAddress);
          }
          mail.setTargetObjectId(tempContact.id);
          mail.setToAddresses(toAddresses);
          mail.setSenderDisplayName('RFT Auto Mail');
          mail.setTemplateId('00XN0000000DbB3');
          mail.saveAsActivity = false;
          mail.setWhatId(rft.Id);
          Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
          delete tempContact;
    
        //ロケーションが異なる場合。
        }else if(trigger.oldMap.get(rft.id).Location__c<>rft.Location__c) {
        
          //古いデータのLocationが空の場合
          if(trigger.oldMap.get(rft.id).Location__c==null){
            for(integer i=0; i<locationList.size();i++){
              for( Object_Champion__c oc :ocList){
                if( oc.Location__c == locationList[i] && oc.Object_No__c ==rft.Object_No__c ){
                  String [] OCMailList = oc.Champion_email__c.split(';');
                  for(integer k=0; k< OCMailList.size(); k++){
                    if(recipient==''){ 
                      recipient=OCMailList[k];
                    }else{
                      toAddresses.add (OCMailList[k]);
                    }
                  }
                }             
              }
              //Area Coordinatorの宛先設定
              for(AreaCoordinators__c ac :acList){
                if(ac.Area__c == locationList[i]){
                  String [] ACMailList = ac.Group_Mail_Address__c .split(';');
                  for(integer m=0; m< ACMailList .size(); m++){
                    toAddresses.add (ACMailList[m]);
                  }
                }
              }
            }
          }else{   //古いデータのLocationが空でない場合
            String [] oldLocationList = trigger.oldMap.get(rft.id).Location__c.split(';');
            for(integer i=0; i<locationList.size();i++){
              integer cnt = 0;
              for(integer j=0; j<oldLocationList .size(); j++){
                if(LocationList[i]==oldLocationList[j]){
                  cnt=cnt+1;
                }
              }
              if(cnt==0){ //locationList[i]の宛先設定
                //Object Championの宛先設定
               for( Object_Champion__c oc :ocList){
                  if( oc.Location__c == locationList[i] && oc.Object_No__c ==rft.Object_No__c ){
                    String [] OCMailList = oc.Champion_email__c.split(';');
                    for(integer k=0; k< OCMailList.size(); k++){
                      if(recipient==''){
                        recipient=OCMailList[k];
                      }else{
                        toAddresses.add (OCMailList[k]);
                      }
                    }
                  }             
                }
                //Area Coordinatorの宛先設定
                for(AreaCoordinators__c ac :acList){
                  if(ac.Area__c == locationList[i]){
                    String [] ACMailList = ac.Group_Mail_Address__c .split(';');
                    for(integer m=0; m< ACMailList .size(); m++){
                      toAddresses.add (ACMailList[m]);
                    }
                  }
                }  
              }       
            }
          } 
          if(recipient<>''){
            Contact tempContact = new Contact(email = recipient , firstName = 'RFT', lastName = 'Temp');
            insert tempContact;
            if(rft.E_mail_Address__c<>null){
              ccAddress.add(rft.E_mail_Address__c);
              mail.setCcAddresses(ccAddress);
            }
            mail.setTargetObjectId(tempContact.id);
            mail.setToAddresses(toAddresses);
            mail.setSenderDisplayName('RFT Auto Mail');
            mail.setTemplateId('00XN0000000DbB3');
            mail.saveAsActivity = false;
            mail.setWhatId(rft.Id);
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
            delete tempContact;     
          }
        }
      }else if(Trigger.isInsert){
        //Set recipients
        for(integer i=0; i<locationList.size(); i++){
        
          //Object Championの宛先設定
          for( Object_Champion__c oc :ocList){
            if( oc.Location__c == locationList[i] && oc.Object_No__c ==rft.Object_No__c ){
              String [] OCMailList = oc.Champion_email__c.split(';');
              for(integer j=0; j< OCMailList.size(); j++){
                if(i==0&&j==0){
                  recipient=OCMailList[j];
                }else{
                  toAddresses.add (OCMailList[j]);
                }
              }
            }             
          }
          //Area Coordinatorの宛先設定
          for(AreaCoordinators__c ac :acList){
            if(ac.Area__c == locationList[i]){
              String [] ACMailList = ac.Group_Mail_Address__c .split(';');
              for(integer m=0; m< ACMailList .size(); m++){
                toAddresses.add (ACMailList[m]);
              }
            }
          }
        } 
        Contact tempContact = new Contact(email = recipient , firstName = 'RFT', lastName = 'Temp');
        insert tempContact;
        if(rft.E_mail_Address__c<>null){
          ccAddress.add(rft.E_mail_Address__c);
          mail.setCcAddresses(ccAddress);
        }
        mail.setTargetObjectId(tempContact.id);
        mail.setToAddresses(toAddresses);
        
        mail.setSenderDisplayName('RFT Auto Mail');
        mail.setTemplateId('00XN0000000DbB3');
        mail.saveAsActivity = false;
        mail.setWhatId(rft.Id);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        delete tempContact;
      } 
    }
  }
}

 

Thanks in advance for your help!!

 

Anna

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox
This is why you should always query for a record ID instead of using a string. You can use SELECT Id FROM EmailTemplate WHERE DeveloperName = "some_name" to query for a specific email template's ID.

All Answers

sfdcfoxsfdcfox

I think you're running into another error related to sending emails. Your code is not bulkified, and that will cause all sorts of issues. At the least, you should design your code like this:

 

1) Determine all contacts to be created, placing them into a list.

2) Insert all of them at once.

3) Generate a list of all emails to be sent.

4) Send all of them at once.

 

You don't seem to be violating the actual message's conditions, but without bulkification, it's hard to tell what the root cause may be. Try fixing your code so it works with bulk first.

AnnaTAnnaT
Thank you for your reply!!
I'll try to modify my code.

Regarding your advice 1) and 2),
do you mean that first I need to create all recipients as contact,
and then insert them into "toAddresses" at once?

Thank you,
Anna
AnnaTAnnaT

As my trigger is long, I tried the following short trigger.

And I modified like this,

3) Generate a list of all emails to be sent.

4) Send all of them at once.

 

trigger PDTEMP on RFT_Category__c (after insert,after update) {

  List<RFT_Category__c > pdList= [SELECT Location__c,Object_No__c FROM RFT_Category__c ];
  List<Object_Champion__c> ocList=[SELECT Location__c,Object_No__c,Champion_email__c FROM Object_Champion__c];
  List<AreaCoordinators__c> acList=[SELECT Area__c, Group_Mail_Address__c FROM AreaCoordinators__c];
  
  public Messaging.SingleEmailMessage [] singleEmails = new List<Messaging.SingleEmailMessage>();
    public Messaging.Email[] allEmails = new List<Messaging.Email>();
  
  String recipient = '';
  Contact tempContact = null;
  List<String> toAddresses= new List<String>();
  List<String> ccAddress = new List<String>();
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  
  for (RFT_Category__c rft : Trigger.new) {
if(rft.Location__c<>null && rft.Object_No__c<>null){ //Mail to allocated Area Coordinator, Objective Champion and Initiator
String [] locationList = rft.Location__c.split(';'); if(Trigger.isInsert){ //Set recipients for(integer i=0; i<locationList.size(); i++){ //Set address of Object Champion for( Object_Champion__c oc :ocList){ if( oc.Location__c == locationList[i] && oc.Object_No__c ==rft.Object_No__c ){ String [] OCMailList = oc.Champion_email__c.split(';'); for(integer j=0; j< OCMailList.size(); j++){ if(i==0&&j==0){ recipient=OCMailList[j]; }else{ toAddresses.add (OCMailList[j]); } } } } //Set address of Area Coordinator for(AreaCoordinators__c ac :acList){ if(ac.Area__c == locationList[i]){ String [] ACMailList = ac.Group_Mail_Address__c .split(';'); for(integer m=0; m< ACMailList .size(); m++){ toAddresses.add (ACMailList[m]); } } } } tempContact = new Contact(email = recipient , firstName = 'RFT', lastName = 'Temp'); insert tempContact; if(rft.E_mail_Address__c<>null){ ccAddress.add(rft.E_mail_Address__c); mail.setCcAddresses(ccAddress); } mail.setTargetObjectId(tempContact.id); mail.setToAddresses(toAddresses); mail.setSenderDisplayName('RFT Auto Mail'); mail.setTemplateId('00XN0000000DbB3'); mail.saveAsActivity = false; mail.setWhatId(rft.Id); singleEmails.add(mail); } for( Integer i = 0; i < singleEmails.size(); i++ ) { allEmails.add(singleEmails.get(i)); } if (allEmails.size() > 0) { Messaging.sendEmail( allEmails ); delete tempContact; } } } }

 But still same error occurrs.

 

AnnaTAnnaT

When I run this trigger in Production Environment, the following error occurrs.

This error doesn't occurred in Sandbox Environment.

How can I solve this??

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger PDSendEmailtoOC caused an unexpected exception, contact your administrator: PDSendEmailtoOC: execution of AfterInsert caused by: System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []: Trigger.PDSendEmailtoOC: line 205, column 1

 

 

Thanks in advance for your help...

Anna

AnnaTAnnaT
It was just because the Email Template ID was wrong...
sfdcfoxsfdcfox
This is why you should always query for a record ID instead of using a string. You can use SELECT Id FROM EmailTemplate WHERE DeveloperName = "some_name" to query for a specific email template's ID.
This was selected as the best answer
AnnaTAnnaT
Hi sfdfox,
I'm sorry for my late reply.
I modified the trigger to get template ID from query.
Thank you so much for your kind support !!