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
CBNCBN 

Not sending mails please review batch apex

Hi all

if campaign member status is responded then sent a mail to campaign member contact email adress

Here is my code
 
global class CampaignMassMailbatch implements Database.batchable<sobject>, Database.Stateful {
    
    public string query;
     global Database.QueryLocator start(Database.BatchableContext bc) {
     
     query = 'Select Id, contact.email from CampaignMember where CampaignMember.Status=Responded' ;
     
     system.debug(Database.getQueryLocator(query));
      
     return Database.getQueryLocator(query);
      
      }
      
     global void execute(Database.BatchableContext bc,  List<Campaignmember> Scope){
      system.debug('campaign batch');
      List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
     for(CampaignMember cm : Scope){
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;
        EmailTemplate  et=[Select id from EmailTemplate where developername = 'Email to Campaign Members' limit 1];
     system.debug(et.id);
   
          String[] toAddresses = new String[] {cm.Email} ;
          mail.setToAddresses(toAddresses) ;
          //  mail.setHtmlBody('body');
          mail.setTemplateId(et.id);
          mails.add(mail);          
        }
          
        Messaging.SendEmailResult[] results = Messaging.sendEmail(mails);
        if (results[0].success) {
        System.debug('The email was sent successfully.');
        } else {
        System.debug('The email failed to send: '
              + results[0].errors[0].message);
       }  
       }
      
      
      global void finish(Database.BatchableContext bc){
       
      }    


}

 
JayantJayant
What's the error ?

Several issues -
1. I doubt the query in Start() would succeed - SOQL syntax is wrong, Responded needs to be in single quotes
2. I doubt the query in execute() would succeed either - usually developer names do not contain spaces
3. The query on EmailTemplate is inside for loop, if its the same template to be used for all emails, query before for loop begins
4. Using setToAddresses counts against the daily governor limit of 1000 distinct email addresses, use setTargetObjectId instead which can take the contact id as parameter and doesn't count against any limits
5. Campaign Member doesn't need to be a Contact always, it can be a Lead too.
6. You are querying all Campaign Members with the status responded, this will process all members everytime batch runs. Put some filters to restrict only to members that actually need to receive an email. 
Ajay K DubediAjay K Dubedi
Hi CBN,
Try this code:
global class CampaignMassMailbatch implements Database.batchable<sobject>, Database.Stateful {
    
    public string query;
    global Database.QueryLocator start(Database.BatchableContext bc) {
        
        return Database.getQueryLocator([Select Id, contact.email ,CampaignMember.Email from CampaignMember where CampaignMember.Status = 'Responded' LIMIT 10000]);
        
    }
    
    global void execute(Database.BatchableContext bc,  List<Campaignmember> Scope){
        system.debug('Scope---->' + Scope);
        
        //EmailTemplate  et = [Select id from EmailTemplate where developername = 'Email to Campaign Members' limit 1]; Put here
        List<String> toAddresses = new List<String>();
        for(CampaignMember obj : Scope)
        {           
            toAddresses.add(obj.contact.email);
            system.debug('obj.Email--->' + obj.contact.email);
            system.debug('CampaignMember.Email--->' + CampaignMember.Email);
        }
        
        try {
            system.debug('toAddresses--->' + toAddresses);
        List<Messaging.SingleEmailMessage> USerEmailList = new List<Messaging.SingleEmailMessage>();
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(toAddresses);
        mail.setSubject('Test');
        mail.setSaveAsActivity(false);
        mail.setPlainTextBody
            ('Send data');
        USerEmailList.add(mail);
        Messaging.sendEmail(USerEmailList);
        System.debug('USerEmailList--->' + USerEmailList);
        }
        catch(Exception ex) {
            System.debug('Mess' + ex.getMessage() + '--' + ex.getLineNumber());
        }
    }
    
    
    global void finish(Database.BatchableContext bc){
        
    }   
}

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.
Thanks,
Ajay Dubedi
CBNCBN
Hi Ajay 

It is working on debug level but in ui not working 

Thanks
CBN
CBNCBN
Hi

i want send an email to Campaign Member's contact email Address when campaign member status is 'Responded' using email template

Thanks
CBN
Ajay K DubediAjay K Dubedi
Hi,
Please use below code:

Messaging.SendEmailResult[] results = Messaging.sendEmail(USerEmailList);
            if (results[0].isSuccess()) {
                System.debug('The email was sent successfully.');
            } else {
                System.debug('The email failed to send: '
                             + results[0].errors[0].message);
            }
I hope this will help you.

Thanks,
Ajay Dubedi
Ajay K DubediAjay K Dubedi
Hi,
Used this query to fulfill your requirement:
Select Id, contact.email ,CampaignMember.Email from CampaignMember where CampaignMember.Status = 'Responded'

Thanks,
Ajay Dubedi