+ Start a Discussion
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK 

How do I send emails whenever a pdf is uploaded on Notes and Attachments ?

Hi,

I would appreciate if you could suggest me a sample code to automate sending pdf through mail.

So the "Notes and Attachment" related list is present in the custom object "Invoice". Whenever a pdf is uploaded in the "Notes and Attachment", an email should be sent to few people. How do I achieve the same ? 
Best Answer chosen by KRISHNAMURTHY KOLUMAM ANANTHARAMAK
Akhil TandonAkhil Tandon
Hi,

This should help you.
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
  system.debug('Entering the trigger');  //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
        
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Contact'))
        {
            //objectIds.add(att.parentId);
            
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {'akhiltandon1984@gmail.com'};
            String[] ccAddresses = new String[] {'akhiltandon1984@gmail.com'};
            mail.setToAddresses(toAddresses);
            mail.setCcAddresses(ccAddresses);
            //string body = 'Hi '+ portalUser.LastName;
            mail.setSubject('Test Subject');
            //mail.setTargetObjectId(id);
            mail.setSaveAsActivity(false);
            mail.setPlainTextBody('DUMMY BODY');
            
            Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
            efa.setFileName(att.Name);
            efa.setBody(att.Body);
            mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});

            //fileAttachments.add(efa);
            
            //mail.setHtmlBody(body); 
            mails.add(mail);
            
        }
    }

Messaging.sendEmail(mails);
}

If it helps you, please mark is as best answer, so it will be helpful for other developers.

All Answers

v varaprasadv varaprasad
HI Krishna,

Using developer console you can create a trigger on attachment object use after insert event on a trigger.

More Info please check once below links : 
https://help.salesforce.com/articleView?id=000181538&type=1
https://developer.salesforce.com/forums/?id=906F00000008mUNIAY


Please let me know in case of any other assistance.

Thanks
Varaprasad





 
Dheeraj VarmaDheeraj Varma
Hi Krishna,

You can add a trigger on the Attachment object. In the Trigger check if the attachment is pdf and the parent object type is the one that you want to work on (In the example below I chose case Object). Then  using soql to get the required data and send an email alert . Here is a sample code that you can use:
 
trigger Email_on_attachment on Attachment (after insert) {
    
    List<Id> objectIds = new List<Id>();
    
    //Filter the attachments based on the criteria, should be pdf and parent should be a case object
    for(Attachment att : Trigger.new)
    {
        if(att.name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Case'))
        {
            objectIds.add(att.parentId);
        }
    }
    
    //get the data needed from the case objects
    List<Case> cases = [select id from case where id in :objectIds];
    
    for(Case cs: cases)
    {
        //Write code to send the email alerts.
    }    

}

Here I fetche only Id of the cases just as an example, you can get attachments, owner information etc based on your requirement. 
For sending email alert, you can refer:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_forcecom_email_outbound.htm


Regards,
Dheeraj Varma
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

I appreciate you for providing the code. However there are a few things I would like to clarify.

1) Does the "Notes and Attachment" has an api name ? 

In my case the pdf is saved in "Notes and Attachment" related list which is present in Invoice object. What is the use of case object  It is confusing. Could you please clarify ?
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

Could you please check if this is correct ? There are a lot of mistakes. Kindly help me in getting this resolved.

trigger PDFTrigger on Attachment (before insert) {List<Id> objectIds = new List<Id>();
    
    //Filter the attachments based on the criteria, should be pdf and parent should be a case object
    for(Attachment att : Trigger.new)
    {
        if(att.name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice'))
        {
            objectIds.add(att.parentId);
        }
    }
    
    //get the data needed from the case objects
    List<Case> Invoice = [select Name__c from Invoice where Name__c in :objectIds];
    
    for(Case cs: Invoice)
    {
    Messaging.reserveSingleEmailCapacity(2);
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
// Strings to hold the email addresses to which you are sending the email.
    String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
    String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
// Assign the addresses for the To and CC lists to the mail object.
    mail.setToAddresses(toAddresses);
    mail.setCcAddresses(ccAddresses);
// Specify the address used when the recipients reply to the email.
    mail.setReplyTo('support@acme.com');
// Specify the name used as the display name.
    mail.setSenderDisplayName('System Administrator');
// Specify the subject line for your email address.
    mail.setSubject('New Invoice Created ' + Invoice.Name__c);
// Set to True if you want to BCC yourself on the email.
    mail.setBccSender(false);
// Optionally append the salesforce.com email signature to the email.
// The email address of the user executing the Apex Code will be used.
    mail.setUseSignature(false);
// Specify the text content of the email.
    mail.setPlainTextBody('Invoice: ' + Invoice.Name__c +' has been created.');
    mail.setHtmlBody('Invoice:<b> ' + Invoice.Name__c +' </b>has been created.<p>'+'To view your Invoice <a href=https://***yourInstance***.salesforce.com/'+Invoice.Id+'>click here.</a>');
// Send the email you have created.
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}    
}
 
Dheeraj VarmaDheeraj Varma
Hi Krishna,

Attachment is the api name for attachments. You can test this in the query editor as well. Try 
Select id, (select id from attachments ) from invoice where id = '<yourobjectid>'

If you give a valid invoce id in place of <yourobjectid> that should return you the ids of the attachments as well.

Coming to your question, the use of Case object is only for reference as you did not mention which object you are using in first place. 

The code that you sent, you are accessing the case object and trying to use that as invoce object. 

Instead of:
List<Case> Invoice = [select Name__c from Invoice where Name__c in :objectIds];

Try :
 
List<Invoice> Invoice = [select id, Name__c from Invoice where Name__c in :objectIds];

​Let me know if you are getting any other errors. Please make sure to mention the errors in the question.


Regards,
Dheeraj Varma
 
Dheeraj VarmaDheeraj Varma
Sorry for the wrong reply,
its not 
List<Invoice> Invoice = [select id, Name__c from Invoice where Name__c in :objectIds];
it is
List<Invoice> Invoice = [select id, Name__c from Invoice where id in :objectIds];
as the objectIds list consists of ids not names.
And yes you mentioned the object as 'Invoice' in your question, I missed that.​
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

I tried to put this in query editor, but it gave me an error saying that "Invoice_Payment__c"  is not a supported SObject type. The api name for Invoice is Invoice_Payment__c. Also for the above code that you gave me initially, what should be the change in for loop and I want to know whether the rest of the code that I sent you is correct. Kindly advice.
Select id, (select id from attachments ) from Invoice_Payment__c 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Dheeraj,

Also how do I find
<yourobjectid>
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
    //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice_Payment__c'))
        {
            objectIds.add(att.parentId);
        }
    }
    
    //get the data needed from the Invoice objects
    List<Invoice_Payment__c> Invoice = [select id, Name__c from Invoice_Payment__c where id in :objectIds];

    for(Invoice_Payment__c cs: Invoice)
    {
    Messaging.reserveSingleEmailCapacity(2);
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
// Strings to hold the email addresses to which you are sending the email.
    String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
    String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
// Assign the addresses for the To and CC lists to the mail object.
    mail.setToAddresses(toAddresses);
    mail.setCcAddresses(ccAddresses);
// Specify the address used when the recipients reply to the email.
    mail.setReplyTo('support@acme.com');
// Specify the name used as the display name.
    mail.setSenderDisplayName('System Administrator');
// Specify the subject line for your email address.
    mail.setSubject('New Invoice Created ' + Invoice_Payment__c.id);
// Set to True if you want to BCC yourself on the email.
    mail.setBccSender(false);
// Optionally append the salesforce.com email signature to the email.
// The email address of the user executing the Apex Code will be used.
    mail.setUseSignature(false);
// Specify the text content of the email.
    mail.setPlainTextBody('Invoice: ' + Invoice_Payment__c.Name__c +' has been created.');
    mail.setHtmlBody('Invoice:<b> ' + Invoice_Payment__c.Name__c +' </b>has been created.<p>'+'To view your Invoice <a href=https://***yourInstance***.salesforce.com/'+Invoice_Payment__c.id+'>click here.</a>');
// Send the email you have created.
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}    
}

Hi Dheeraj, This is my final piece of code. Could you check if it is correct. When ever an invoice pdf is added in Notes and Attachements, an email should trigger. It doesn't seem to work but it doesn't give any error. Kindly help.
Dheeraj VarmaDheeraj Varma

Hi Krishna,

Its always good to add debug statements and check if you are not sure why the code is not working, so that you know what result the code is giving.

Try adding a debug statement to see if the objectIds list is getting populated and also to see if the Invoice list is having any values after the soql query.

If any of the lists are not getting populated then something is wrong with the logic. 
Dheeraj VarmaDheeraj Varma
Hi Krishna,

I have noticed some defects in your code lately,
 
mail.setPlainTextBody('Invoice: ' + Invoice_Payment__c.Name__c +' has been created.');

mail.setHtmlBody('Invoice:<b> ' + Invoice_Payment__c.Name__c +' </b>has been created.<p>'+'To view your Invoice <a

You need to use cs.Name__c instead of Invoice_Payment__c.Name__c.

Let me know if the debug logs helped in identifying any issue.

Regards,
Dheeraj Varma
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

Thank you for your assistance. I am really grateful to you.

For some reason the debugger is not working. I tried to use system.debug(""); but whenever I uploaded an attachement, it doesn't trigger the debugger and the logs aren't recorded. I have approaced SF support straightaway.

Can you explain a few things in the code ?

1) for(Invoice_Payment__c cs: Invoice) --> What does cs in the for loop mean ?

2)
 
{

            objectIds.add(att.parentId);

  }
What does this statement signify ?

3) What is objectIds ? 
4) Why do I need to use the SOQL query to fetch the data first ?
5) Where in the code it attaches the pdf in the mail ?
 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

I also have this issue. In Sandbox, if I type 
Select id, (select id from attachments ) from Invoice_Payment__c where id = '<yourobjectid>'
It is giving me an error saying that the Invoice_Payment__c is not supported in SObject, but the same query is working in Production.
Akhil TandonAkhil Tandon
Hi KRISHNAMURTHY,

Are you sure that you have an Object "Invoice_Payment__c" in the sandbox/org where you are getting this error.

Also the code you shared earlier is sending an email within for loop. This code will fail in case of bulk uploads. Please refer to code mentioned below to send out bulk emails.
 
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(User portalUser :lstPortalUser) {
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
string body = 'Hi '+ portalUser.LastName;
mail.setSubject('Test Subject');
mail.setTargetObjectId(portalUser.Id); mail.setSaveAsActivity(false);
mail.setHtmlBody(body); mails.add(mail);
}
Messaging.sendEmail(mails);

Regards
Akhil Tandon​ 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

I just checked now in the query editor for other objects. None of the sObjects are supported in sandbox, but I can find all the objects in Object Manager. Do you know what could be the reason for this ?

Thanks
Krishna
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

Where should I specify the from and to address in your code ? 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

I have modified the code as per your suggested. Could you check if it is correct ?
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
  system.debug('Entering the trigger');  //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice_Payment__c'))
        {
            objectIds.add(att.parentId);
        }
    }
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(User portalUser :lstPortalUser) 
{
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
mail.setToAddresses(toAddresses);
mail.setCcAddresses(ccAddresses);
string body = 'Hi '+ portalUser.LastName;
mail.setSubject('Test Subject');
mail.setTargetObjectId(portalUser.Id);
mail.setSaveAsActivity(false);
mail.setHtmlBody(body); 
mails.add(mail);
}
Messaging.sendEmail(mails);

I have given the to address and cc address. So if two people upload at the same time, does this code work ?
Akhil TandonAkhil Tandon
Hi,

I do not have access to Invoice Payment object so I have modified the code to work for contact object. To answer your question if two users upload two files at the same time then trigger will be invoked for the two of them seprately. In case of a bulk upload where more than one records are available in trigger then trigger will handle that load because it has been bulkified.
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
  system.debug('Entering the trigger');  //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Contact'))
        {
            objectIds.add(att.parentId);
        }
    }
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(ID id :objectIds) 
{
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'akhiltandon1984@gmail.com'};
String[] ccAddresses = new String[] {'akhiltandon1984@gmail.com'};
mail.setToAddresses(toAddresses);
mail.setCcAddresses(ccAddresses);
//string body = 'Hi '+ portalUser.LastName;
mail.setSubject('Test Subject');
//mail.setTargetObjectId(id);
mail.setSaveAsActivity(false);
mail.setPlainTextBody('This email is for contact ID::'+id);
//mail.setHtmlBody(body); 
mails.add(mail);
}
Messaging.sendEmail(mails);
}

 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

Thanks for the explantion and code. What is the purpose of having id in body ? Could you please clarify. 
 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

I wanna attach pdf in the body.
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil, Dheeraj,

I have made modifications in the code to include attachments.
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
                                                 
 //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
for(Attachment att : Trigger.new)
                                                 {
                                                     if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice_Payment__c'))
                                                     {
                                                         objectIds.add(att.parentId);
                                                     }
                                                 }
                                                 system.debug('objectIds-->' + objectIds);
                                                 //get the data needed from the Invoice objects
                                                 List<Invoice_Payment__c> Invoice = [select id, Name__c from Invoice_Payment__c where id in :objectIds];
                                                 
                                                 for(Invoice_Payment__c cs: Invoice)
                                                 {
                                                     Messaging.reserveSingleEmailCapacity(2);
                                                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                                                     
                                                     String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
                                                     String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
                                                     mail.setToAddresses(toAddresses);
                                                     mail.setCcAddresses(ccAddresses);
                                                     mail.setReplyTo('support@acme.com');
                                                     mail.setSenderDisplayName('System Administrator');
                                      				 mail.setSubject('New Invoice Created ' + Invoice_Payment__c.id);
                                                     mail.setBccSender(false);
                                                     mail.setUseSignature(false);
                                                     mail.setPlainTextBody('Invoice: ' + Invoice_Payment__c.Name__c +' has been created.');
                                                     mail.setHtmlBody('Invoice:<b> ' + Invoice_Payment__c.Name__c +' </b>has been created.<p>'+'To view your Invoice <a href=https://***yourInstance***.salesforce.com/'+Invoice_Payment__c.id+'>click here.</a>');
                                                     Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
                                                 }  
                                                 // Set email File Attachment
                                                 List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
                                                 for (Attachment a : [select Name, id from Attachment where id in :objectIds])
                                                 {
                                                     // Add to attachment file list
                                                     Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
                                                     efa.setFileName(a.Name);
                                                     efa.setBody(a.Body);
                                                     fileAttachments.add(efa);
                                                 }
                                                 mails.setFileAttachments(fileAttachments);
                                                 //Send email
                                                 Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mails });
                                                 
                                                }

 
Akhil TandonAkhil Tandon
Hi,

This should help you.
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
  system.debug('Entering the trigger');  //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
        
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Contact'))
        {
            //objectIds.add(att.parentId);
            
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {'akhiltandon1984@gmail.com'};
            String[] ccAddresses = new String[] {'akhiltandon1984@gmail.com'};
            mail.setToAddresses(toAddresses);
            mail.setCcAddresses(ccAddresses);
            //string body = 'Hi '+ portalUser.LastName;
            mail.setSubject('Test Subject');
            //mail.setTargetObjectId(id);
            mail.setSaveAsActivity(false);
            mail.setPlainTextBody('DUMMY BODY');
            
            Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
            efa.setFileName(att.Name);
            efa.setBody(att.Body);
            mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});

            //fileAttachments.add(efa);
            
            //mail.setHtmlBody(body); 
            mails.add(mail);
            
        }
    }

Messaging.sendEmail(mails);
}

If it helps you, please mark is as best answer, so it will be helpful for other developers.
This was selected as the best answer
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Thank you so much for your help.
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Akhil,

Could you give me a link to study more about ObjectIds ? What are they and whu should they be used in a list ?
Akhil TandonAkhil Tandon
Please use this link. It contains list of all standard objects.
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_list.htm
Dheeraj VarmaDheeraj Varma
Hi Krishna,

The objectIds is just a variable name here in the code. We used that to store ids of the records for which the attachments are being added. For example if you are adding attchment to some invoice record the id of the record is added to the list, so that we can use these ids while querying the records using soql.

For more information on ids of records in salesforce, refer to documentation.
"Every Record, regardless of entity type, has a globally unique identification value in its ID field which is generated at the time of record creation. That Record ID value will never change, even if the record is deleted and then undeleted.
The URL of a record viewed within Salesforce via web browser contains the Salesforce instance and the Record ID.
 
For example:  http://na1.salesforce.com/5003000000D8cuI
 
Record ID: 5003000000D8cuI
Instance: na1 "
 

Here based on your requirement, we are using trigger on the attachment object. So whenever we are adding an attachment the trigger gets executed irrespective of the objecttype of the record for which the attchment is being added. So we are filtering the records that records of invoice object type and storing the ids of those records in the list 'objectIds'.

Then we are doing a soql query to get the data regarding the record, like the name, owner, attachments etc that we need in the email content. Then we are seding emails using the content of the records on by one. 

I have taken a look at your code, I see that you are using the invoice ids for querying the attachments.
 
for (Attachment a : [select Name, id from Attachment where id in :objectIds])
Are you able to add the attachments in the mail using this?

Regards,
Dheeraj Varma
 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj,

This is my revised code as per Akhil's recommendation but I don't see the attachment object used in query. Is this correct and does it trigger and send an email whenever a pdf is uploaded in attachments ?
 
trigger PDFTrigger on Attachment (after insert) {List<Id> objectIds = new List<Id>();
    
  system.debug('Entering the trigger');  
                                                 
    //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
        
    for(Attachment att : Trigger.new)
    {
        if(att.Name.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice'))
        {
            //objectIds.add(att.parentId);
            
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
            String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
            mail.setToAddresses(toAddresses);
            mail.setCcAddresses(ccAddresses);
            //string body = 'Hi '+ portalUser.LastName;
            mail.setSubject('New Invoice Generated');
            //mail.setTargetObjectId(id);
            mail.setSaveAsActivity(false);
            mail.setPlainTextBody('Hi Andre, A new invoice has been generated for you review.');
            
            Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
            efa.setFileName(att.Name);
            efa.setBody(att.Body);
            mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
			//fileAttachments.add(efa);
            //mail.setHtmlBody(body); 
            mails.add(mail);
            
        }
    }

Messaging.sendEmail(mails);
}

 
Dheeraj VarmaDheeraj Varma
Hi Kiran,

The looks good, I guess you need to replace 
att.parentId.getSObjectType().getDescribe().getName().equals('Invoice')
with 
att.parentId.getSObjectType().getDescribe().getName().equals('Invoice_Payment__c')
It depends on how the object is configured in your box. We are not querying the Attachment object again as the trigger itself is fired by the Attachment object and we donot need to run a query for that. You need to run a query on Invoice object if you need other data regarding the invoice record like name etc. 

Let us know id the updated code is working and your requirement is acheived.

Regards,
Dheeraj Varma
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj, Akhil,

There is a problem in lightning version that if you upload a pdf it consider it as a file and not an attachement. So instead of using Attachment, I used Content Version but it is giving me an error when I upload an attachement.

Please see the below code and help.
trigger FilesTrigger on ContentVersion(after insert) {
    system.debug('Entering the trigger');  
    
    //Filter the attachments based on the criteria, should be pdf and parent should be a Invoice object
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    
    for(ContentVersion att : Trigger.new)
    {
        //if(att.Title.endsWith('.pdf') && att.parentId.getSObjectType().getDescribe().getName().equals('Invoice'))
        //{
        //objectIds.add(att.parentId);
        
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       
        
        String[] toAddresses = new String[] {'andre.nobre@cleantechsolar.com'};
        String[] ccAddresses = new String[] {'krishnamurthy.ka@cleantechsolar.com'};
        mail.setToAddresses(toAddresses);
        mail.setCcAddresses(ccAddresses);
        //string body = 'Hi '+ portalUser.LastName;
        mail.setSubject('New Invoice Generated');
        //mail.setTargetObjectId(id);
        mail.setSaveAsActivity(false);
        mail.setPlainTextBody('Hi Andre, A new invoice has been generated for you review.');
       
        Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
        efa.setFileName('Invoice.pdf');
        String body = 'Dear ' ;
        efa.setBody(body);
        // efa.setBody(att.Description);
        mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
        
        
        mails.add(mail); 
        
        //}
    }
    
    Messaging.sendEmail(mails); 
}

setBody() -- It is throwing an error saying that the method is not available, but this field is needed.
What do I need to modify ? 
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
See the error :

User-added image
KRISHNAMURTHY KOLUMAM ANANTHARAMAKKRISHNAMURTHY KOLUMAM ANANTHARAMAK
Hi Dheeraj, Akhil

Any idea on the above query ?
Dheeraj VarmaDheeraj Varma
Hi Kiran,

The setBody method allows only blob type, it does not allow string type. you chttps://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm?search_text=Contentan use Blob.valueOf('String') method to convert the string to Blob type content.

Regards,
Dheeraj Varma
Ash Jones 10Ash Jones 10
@ Akhil Tanton, How can i pass current user's email address in String[] toAddresses = new String[]?
Thanks.