2

I try to call the PageReference's getContent() method from a component that is nested in a visualforce email template.

If the template is send via the test button, all looks great. However if I fire the Email alert via workflow rule it got stuck somewhere in the middle of the process.

Console tells email alerts are fired - but no emails are logged (deliverability is set to all emails)

The solution I try to adopt is: http://kevindotcar.wix.com/home/apps/blog/how-to-schedule-a-report-to-send

Its quite old but I just can't find any information that getContent() is not supported by email alerts (if I replace the line with the getContent().toString() call with a dummy string all is fired as it should be)

VF Template

<messaging:emailTemplate subject="XLS EXEC" recipientType="User" relatedToType="ReportExport__c">
<messaging:plainTextEmailBody >

TEXT
</messaging:plainTextEmailBody>

<messaging:attachment renderAs="application/x-excel" filename="report.xls" >
<c:ReportOutputter xstrRptId="{!relatedTo.ReportId__c}" xstrEncoding="UTF-8" xstrFormat="xls"/>
</messaging:attachment>
</messaging:emailTemplate>

Component

<apex:component id="ReportOutputter" controller="ReportOutputter_Controller" access="global" allowDML="true">
<apex:attribute name="xstrRptId" description="report ID" type="String" assignTo="{!strRptId}"/>
<apex:attribute name="xstrEncoding" description="file Encoding, can be UTF-8 or ISO 8859-1" type="String" assignTo="{!strEncoding}"/>
<apex:attribute name="xstrFormat" description="file Format, can be xls or csv" type="String" assignTo="{!strFormat}"/>
<apex:outputText value="{!FileStream}" escape="false"/>

Controller

public with sharing class ReportOutputter_Controller {

public String strEmail{get;set;}
public String strRptId{get;set;}
public String strEncoding{get;set;}
public String strFormat{get;set;}

void ReportOutputter_Controller () {}

public String getFileStream() {
    return exportReport(strRptId, strEncoding, strFormat);
}

private static String exportReport(String reportName, String encoding, String format) {
    String requestURL;

    requestURL = '/' + reportName + '?export=1&enc='+encoding+'&xf='+format+'&inline=0';

    String pr = new PageReference(requestURL).getContent().toString();

    System.debug('### SEND PAGE:'+pr);

    return pr;
   }
}
  • I think, sending an email though workflow behaves as callout and in the email template getContent() also behaves as callout, that may be reason for failing – Santanu Boral May 31 '17 at 22:08
  • Thanks @SantanuBoral, yes its a callout but is there some kind of documentation that you can not send a callout from a email alert? I wonder because there are a lot of blogposts out there doing this kind of stuff and it seams to work for most people. – sric Jun 1 '17 at 12:24
  • rather than workflow email alert, you can write apex code to send email and perform getContent() – Santanu Boral Jun 1 '17 at 13:58
  • Wanted to avoid that much coding but there seams to be no way around it. – sric Jun 1 '17 at 15:20
0

Here is the documentation you are looking for (it states the method can't be used in Apex email services): https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_System_PageReference_getContent.htm

I have been trying a lot of workarounds like posting chatter feed posts to groups with emails on for every post, calling future methods, using batch class and invoking email in the finish context, etc.

Unfortunately, no workarounds work 100% of the time, HOWEVER invoking the email by calling its own apex class and future method does work most at times, but occasionally you will receive the following error: "FATAL_ERROR System.VisualforceException: null."

If anyone finds a workaround that works 100% of the time let me know!

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.