{"id":3851,"date":"2014-04-16T15:51:34","date_gmt":"2014-04-16T15:51:34","guid":{"rendered":"http:\/\/www.jitendrazaa.com\/blog\/?p=3851"},"modified":"2016-08-27T04:54:27","modified_gmt":"2016-08-27T04:54:27","slug":"send-email-with-generated-pdf-as-attachment-from-trigger","status":"publish","type":"post","link":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/apex\/send-email-with-generated-pdf-as-attachment-from-trigger\/","title":{"rendered":"Send Email with Generated PDF as attachment from Trigger &#8211; before Winter 16"},"content":{"rendered":"<p style=\"text-align: justify;\">There may be scenario in Salesforce that you need to send a Visualforce page rendered as PDF as a part of Email Attachment. This will be very easy if you want to perform this using Controller or Extension class, we just have to call <em>getContentAsPDF()<\/em> method of <a title=\"Salesforce PageReference Methods\" href=\"https:\/\/www.salesforce.com\/us\/developer\/docs\/apexcode\/Content\/apex_System_PageReference_methods.htm\" rel=\"nofollow\">PageReference<\/a> class and use returned blob data as a attachment in Email.<\/p>\n<p><strong>Update &#8211; 21 Oct 2015 (Winter 16)<\/strong><\/p>\n<p style=\"text-align: justify;\">After Winter 16 release, this solution will not work as\u00a0<em>getContent()\u00a0<\/em>method is treated as callout and if we try to call it from Async Apex or Rest API in this case, it will not return pdf content.<\/p>\n<p style=\"text-align: justify;\">This solution will only work for you if you have not enabled critical update &#8220;<em>PageReference getContent() and getContentAsPDF() Methods Treated as Callouts<\/em>&#8221; in your Salesforce organization.<\/p>\n<p style=\"text-align: justify;\">Note : <a href=\"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/send-visualforce-as-an-email-attachment-from-apex-trigger-alternate-design\/\">If this solution is not working for you then try this.<\/a><\/p>\n<p style=\"text-align: justify;\">If we are talking about achieving same in Trigger then it would be problem. Trigger does not support getContent() method of PageReference class. If you are thinking to use getContent() in future call then again we\u00a0are not lucky, because @future methods does not support it. Also <a title=\"Apex Scheduler\" href=\"http:\/\/www.salesforce.com\/us\/developer\/docs\/apexcode\/Content\/apex_scheduler.htm\" rel=\"nofollow\">Apex job<\/a> doesn&#8217;t support this method.<\/p>\n<p style=\"text-align: justify;\">Now, I hope you understood that in which situation we are \ud83d\ude42<\/p>\n<p style=\"text-align: justify;\">So, In this article, I am going to explain how to resolve this issue. Not exactly resolve but workaround for above problem.<\/p>\n<p style=\"text-align: justify;\">Solution is very simple, We will expose apex method as a REST API. Code for sending email will be written in APEX based REST API and our Trigger will call this method asynchronously using <strong>@future<\/strong> annotation.<!--more--><\/p>\n<p>Sample Visualforce Page, page Name &#8211; &#8220;<span style=\"text-decoration: underline;\">PDF_Demo<\/span>&#8221;<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n &lt;apex:page renderAs=&quot;PDF&quot; &gt;\r\n   &lt;!-- Begin Default Content REMOVE THIS -- &gt;\r\n\r\n&lt;h1 &gt;Congratulations &lt;\/h1 &gt;\r\n\r\n  This is your new Page\r\n   &lt;!-- End Default Content REMOVE THIS -- &gt;\r\n &lt;\/apex:page &gt;\r\n<\/pre>\n<p>Lets assume that above Visualforce page needs to be send as a part of attachment.<\/p>\n<p>Creating APEX based REST API with POST Method :<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\/**\r\n*\tCreated By\t:\tJitendra Zaa\r\n*\tDescription\t:\tApex based REST API which exposes POST method to send Email\r\n*\/\r\n@RestResource(urlMapping='\/sendPDFEmail\/*')\r\nGlobal class GETPDFContent{\r\n     @HttpPost\r\n    global static void sendEmail(String EmailIdCSV, String Subject, String body) {\r\n\r\n \tList&amp;amp;lt;String&amp;amp;gt; EmailIds = EmailIdCSV.split(',');\r\n\r\n        PageReference ref = Page.PDF_DEMO;\r\n        Blob b = ref.getContentAsPDF();\r\n\r\n        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();\r\n\r\n        Messaging.EmailFileAttachment efa1 = new Messaging.EmailFileAttachment();\r\n        efa1.setFileName('attachment_WORK.pdf');\r\n        efa1.setBody(b);\r\n\r\n        String addresses;\r\n        email.setSubject( Subject +String.valueOf(DateTime.now()));\r\n        email.setToAddresses( EmailIds  );\r\n        email.setPlainTextBody(Body);\r\n        email.setFileAttachments(new Messaging.EmailFileAttachment&#x5B;] {efa1});\r\n        Messaging.SendEmailResult &#x5B;] r = Messaging.sendEmail(new Messaging.SingleEmailMessage&#x5B;] {email});\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>In above code, we have created APEX based REST API with POST method. We are simply getting content of Visualforce rendered as PDF with method &#8220;<em>getContentAsPDF()<\/em>&#8221; and setting up this in object of &#8220;Messaging.EmailFileAttachment&#8221;.<\/p>\n<p>REST API created using Apex class can be accessed from URL &#8220;https:\/\/&lt;YOUR_SALESFORCE_INSTANCE&gt;\/services\/apexrest\/&lt;RESTURL&gt;&#8221;<\/p>\n<p>In below part of code, we will be consuming REST API recently created<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\/**\r\n*\tCreated By\t:\tJitendra Zaa\r\n*\tDescription\t:\tThis class exposes @future method to send VF page rendered as PDF as attachment in Email\r\n*\/\r\npublic class SendVFAsAttachment{\r\n\r\n    @future(callout=true)\r\n    public static void sendVF(String EmailIdCSV, String Subject,String body,String userSessionId)\r\n    {\r\n        \/\/Replace below URL with your Salesforce instance host\r\n        String addr = 'https:\/\/shivasoft--shiva1.cs6.my.salesforce.com\/services\/apexrest\/sendPDFEmail';\r\n        HttpRequest req = new HttpRequest();\r\n        req.setEndpoint( addr );\r\n        req.setMethod('POST');\r\n        req.setHeader('Authorization', 'OAuth ' + userSessionId);\r\n        req.setHeader('Content-Type','application\/json');\r\n\r\n        Map&amp;amp;lt;String,String&amp;amp;gt; postBody = new Map&amp;amp;lt;String,String&amp;amp;gt;();\r\n        postBody.put('EmailIdCSV',EmailIdCSV);\r\n        postBody.put('Subject',Subject);\r\n        postBody.put('body',body);\r\n        String reqBody = JSON.serialize(postBody);\r\n\r\n        req.setBody(reqBody);\r\n        Http http = new Http();\r\n        HttpResponse response = http.send(req);\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Note :<\/strong> Please make sure you have added URL of your salesforce in &#8220;<strong>Remote Site Settings<\/strong>&#8220;, else you will not be able to make REST API call.<\/p>\n<p><strong>Question : How do we set Body for POST method in Apex based REST API or How do we supply argument in POST method ?<\/strong><br \/>\n<strong>Answer :<\/strong> As you can see in above code sample, we have to supply JSON as a Request Body and set Header ContentType as &#8220;<em>application\/json<\/em>&#8220;.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n        req.setHeader('Content-Type','application\/json');\r\n\r\n        Map&amp;amp;lt;String,String&amp;amp;gt; postBody = new Map&amp;amp;lt;String,String&amp;amp;gt;();\r\n        postBody.put('EmailIdCSV',EmailIdCSV);\r\n        postBody.put('Subject',Subject);\r\n        postBody.put('body',body);\r\n        String reqBody = JSON.serialize(postBody);\r\n<\/pre>\n<p>Writing Trigger:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\/**\r\n*   Created By  :   Jitendra Zaa\r\n*   Description :   This Trigger calls @future method to send VF page rendered as PDF as attachment in Email\r\n*   Note        :   Make sure that this Trigger does not call Future methods more than 10 times.\r\n*\/\r\ntrigger SampleTrigger on Lead (before insert) {\r\n    SendVFAsAttachment.sendVF('emailaddress1@email.com,emailaddress2@email.com','Sample Test from Trigger',\r\n    'Sample Email Body',UserInfo.getSessionId());\r\n}\r\n<\/pre>\n<p>From above sample code, we are calling static method asynchronously, which in turn calling REST API to send Email with Visualforce as attachment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There may be scenario in Salesforce that you need to send a Visualforce page rendered as PDF as a part of Email Attachment. This will be very easy if you want to perform this using Controller or Extension class, we just have to call getContentAsPDF() method of PageReference class and use returned blob data as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"jz_research_post":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[20],"tags":[246,244,167,331,203,349],"class_list":["post-3851","post","type-post","status-publish","format-standard","hentry","category-apex","tag-getcontentaspdf","tag-pdf","tag-release","tag-salesforce","tag-trigger","tag-winter16"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":5662,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/send-visualforce-as-an-email-attachment-from-apex-trigger-alternate-design\/","url_meta":{"origin":3851,"position":0},"title":"Send Visualforce as an email attachment from Apex Trigger &#8211; Alternate design","author":"Jitendra","date":"August 27, 2016","format":false,"excerpt":"Process Builder & InvocableMethod- Alternative to send Visualforce as an email attachment from Apex Trigger","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Send Visualforce as an email attachment from Apex Trigger","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/08\/Send-Visualforce-as-an-email-attachment-from-Apex-Trigger.jpg?fit=922%2C369&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/08\/Send-Visualforce-as-an-email-attachment-from-Apex-Trigger.jpg?fit=922%2C369&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/08\/Send-Visualforce-as-an-email-attachment-from-Apex-Trigger.jpg?fit=922%2C369&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/08\/Send-Visualforce-as-an-email-attachment-from-Apex-Trigger.jpg?fit=922%2C369&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2924,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/apex-based-ddp-generation-using-looplus\/","url_meta":{"origin":3851,"position":1},"title":"APEX based DDP generation using LOOPlus","author":"Jitendra","date":"June 11, 2012","format":false,"excerpt":"Example of generating dynamic document packages (DDP) using Apex and LOOPlus in Salesforce","rel":"","context":"In &quot;Apex&quot;","block_context":{"text":"Apex","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/apex\/"},"img":{"alt_text":"Enabling Business Version of DrawLoop","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/06\/Enabling-Business-Version-of-DrawLoop.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/06\/Enabling-Business-Version-of-DrawLoop.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/06\/Enabling-Business-Version-of-DrawLoop.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":2797,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/creating-trigger-on-attachment-in-salesforce\/","url_meta":{"origin":3851,"position":2},"title":"Creating Trigger on Attachment in Salesforce","author":"Jitendra","date":"March 28, 2012","format":false,"excerpt":"Example and tutorial on creating the trigger for attachment in salesforce which will not allow to upload the file in opportunity if file contains some predefined text","rel":"","context":"In &quot;Apex&quot;","block_context":{"text":"Apex","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/apex\/"},"img":{"alt_text":"Before insert Trigger on Attachment using eclipse in Salesforce","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/03\/Before-insert-Trigger-on-Attachment-Salesforce.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/03\/Before-insert-Trigger-on-Attachment-Salesforce.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/03\/Before-insert-Trigger-on-Attachment-Salesforce.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":3150,"url":"https:\/\/www.jitendrazaa.com\/blog\/java\/merge-pdf-in-salesforce-using-java-itextpdf-and-oauth-2\/","url_meta":{"origin":3851,"position":3},"title":"Merge PDF in Salesforce Using Java, ITextPDF and OAuth 2","author":"Jitendra","date":"December 9, 2012","format":false,"excerpt":"Its long time, since i wrote any article because of my busy schedule However this time i came with advance one. In this article we are going to use the J2EE (Servlet) to Merge PDF attachment inside salesforce with the help of OAuth and ITextPDF jar file. The reason of\u2026","rel":"","context":"In &quot;Apex&quot;","block_context":{"text":"Apex","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/apex\/"},"img":{"alt_text":"Create Remote Access in Salesforce.com for OAuth 2","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/12\/Create-Remote-Access-in-Salesforce.com_.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/12\/Create-Remote-Access-in-Salesforce.com_.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2012\/12\/Create-Remote-Access-in-Salesforce.com_.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":4967,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/salesforce-flow-interview-questions-for-admins-part-23\/","url_meta":{"origin":3851,"position":4},"title":"Salesforce Flow Interview Questions for admins &#8211; Part 23","author":"Jitendra","date":"December 7, 2015","format":false,"excerpt":"\ufeff Consider it interview questions or FAQs, However below are some high level information or gotchas related to Salesforce Flow. 221. How to create lookup field in Salesforce flow? Ans : There is no direct way to create a lookup field in flow but we can use workaround mentioned in\u2026","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Sample Salesforce flow using loop element","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2015\/11\/Sample-Salesforce-flow-using-loop-element.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2015\/11\/Sample-Salesforce-flow-using-loop-element.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2015\/11\/Sample-Salesforce-flow-using-loop-element.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":4870,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/resolve-24-hour-apex-email-limit-error-in-salesforce\/","url_meta":{"origin":3851,"position":5},"title":"Resolve 24 hour Apex email limit error in Salesforce","author":"Jitendra","date":"October 13, 2015","format":false,"excerpt":"How to design and architect Salesforce application so that 24 hour Apex email limit error could be resolved and have reporting capabilities on emails sent from Salesforce","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Resolve 24 hour Apex email limit error in Salesforce","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2015\/10\/Resolve-24-hour-Apex-email-limit-error-in-Salesforce.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/3851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/comments?post=3851"}],"version-history":[{"count":10,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/3851\/revisions"}],"predecessor-version":[{"id":5666,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/3851\/revisions\/5666"}],"wp:attachment":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/media?parent=3851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/categories?post=3851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/tags?post=3851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}