1

I'm having an interesting problem trying to send an email to a Contact with a PDF attachment. I've got a VF page that renders as a PDF, and an page controller apex class that creates the email and attaches the PDF using the getContent() call. I call the controller class from a 'send' button page.

The interesting part is that it works great in the sandbox. But when when I run it from production, it returns an HTML file instead of a PDF file. The VF page renders fine on the production system, so that doesn't appear to be the problem.

The VF page (I removed most of the code to make sure that wasn't the problem):

<apex:page standardController="hed__Course_Enrollment__c" renderAs="pdf" applyBodyTag="false" applyHtmlTag="false" showHeader="false">
    <html>
    <head>
        <style>
        </style>
    </head>

    <body>
        <p>
            This is a test!
        </p>
    </body>
    </html>
</apex:page>

The page controller code to create the PDF and send as an email attachment:

public class CourseCertAAIRecEmailPageController {
    private final hed__Course_Enrollment__c courseRoster {get; set;}

    private string courseRosterId { get; set; } 
    
    // Create a constructor that populates the Course Roster object
    public CourseCertAAIRecEmailPageController() {
        courseRosterId = ApexPages.currentPage().getParameters().get('id');
    
        courseRoster = [select id, Contact_First_Name__c, Contact_Last_Name__c, Contact_Email__c, Contact_ID__c, Course_Clean_Name__c 
                        from hed__Course_Enrollment__c where id = :ApexPages.currentPage().getParameters().get('id')];
    }

    public PageReference send() {
        // Define the email
        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); 

        String[] toAddresses = new String[] { this.courseRoster.Contact_Email__c };
        String subject = 'AAI Course Completion Certificate for ' + courseRoster.Course_Clean_Name__c;

        String body = 'Dear ' + courseRoster.Contact_First_Name__c + ',<br><br>';
        body += 'Thank you for taking your recent <strong>' + courseRoster.Course_Clean_Name__c + '</strong> class with us.<br><br>';
        body += 'Attached is your completion certificate! Please retain this in a convenient and accessible location for your records.<br><br>';
        body += '<strong>American Avalanche Institute</strong>';
    
        string filename = 'AAI Course Completion Certificate: ' + courseRoster.Course_Clean_Name__c + '.pdf';
        
        // Set the parameters of the email
        email.setToAddresses(toAddresses);
        email.setReplyTo('[email protected]');
        email.setSenderDisplayName('American Avalanche Institute');
        email.setSubject(subject);
        email.setHtmlBody(body);
        
        // Create the certificate
        PageReference pdf = Page.CourseCertAAIRec;
        pdf.getParameters().put('id', (String)courseRoster.id);
        pdf.setRedirect(true);
    
        // Get the PDF content
        Blob pdfBlob;
        if (Test.isRunningTest()) 
        { 
            pdfBlob = blob.valueOf('Unit.Test');
        } 
        else 
        {
            try
            {
                // pdfBlob = Blob.toPdf('This is the certificate!');
                // pdfBlob = pdf.getContentAsPDF();
                pdfBlob = pdf.getContent();
            } 
            catch (VisualforceException e) 
            {
                pdfBlob = Blob.toPdf('getContent failed, error is: ' + e.getMessage());
            }            
        }
        
        // Get the contact for the Course Roster object
        string contactId = courseRoster.Contact_ID__c;
        System.Debug('Contact ID: ' + contactId);

        // Create content version -- this is the document itself
        ContentVersion fileToUpload = new ContentVersion();
        fileToUpload.ContentLocation = 'S';         // Salesforce. The other option is: 'E'
        fileToUpload.pathOnClient = filename;
        fileToUpload.title = subject;
        fileToUpload.versionData = pdfBlob;
        Database.SaveResult saveResult;
        try 
        {
            saveResult = Database.insert(fileToUpload);
        } 
        catch (DmlException dmle) 
        {
            system.debug('Failed to insert fileToUpload, error is: ' + dmle.getMessage());
        }

         // First get the content document Id from ContentVersion
        Id contentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:fileToUpload.Id].ContentDocumentId;
        System.Debug('Content Document ID: ' + contactId);
        
        // Create ContentDocumentLink -- links document to contact
        ContentDocumentLink linkToRecord = new ContentDocumentLink();
        linkToRecord.ContentDocumentId = contentDocumentId;
        linkToRecord.LinkedEntityId = contactId;    // Record ID of the parent
        linkToRecord.ShareType = 'V';               // Visible to all
        insert linkToRecord;
        
        // Create the email attachment
        Messaging.EmailFileAttachment fileAttachment = new Messaging.EmailFileAttachment();
        fileAttachment.setContentType('application/pdf');
        fileAttachment.setFileName('AAI Course Completion Certificate.pdf');
        fileAttachment.setBody(pdfBlob);
        fileAttachment.setInline(false);
        
        // Attach it
        email.setFileAttachments(new Messaging.EmailFileAttachment[] { fileAttachment });
        
        // Send the email
        Messaging.SendEmailResult [] result = Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });   
        if (result[0].isSuccess() == false) {
            // TODO: Something...
        }

        string sessionId = UserInfo.getSessionId();
        System.Debug('Session ID: ' + sessionId);
        
        return null;
    }   
}

Any thoughts would be greatly appreciated!

3
  • 1
    I suspect that pdf.setRedirect(true); is the cause, though I'm not sure why it'd work in one org and not another. It may have something to do with some of the code having not deployed properly.
    – sfdcfox
    Oct 18, 2023 at 21:43
  • I changedsetRedirect to pdf.setRedirect(false), with the same results. Not sure how/why the code would deploy improperly? Seems pretty straightforward to me, but I'm not a SFDC pro, more like advanced intermediate. :-)
    – Lars
    Oct 19, 2023 at 16:53
  • After doing some additional testing, I'm starting to think that this might be related to a permissions thing. I changed the process to create and HTML file instead of PDF and got the same results. So I think something is blocking the PageReference to Blob conversion.
    – Lars
    Oct 30, 2023 at 16:21

1 Answer 1

0

I was experiencing a similar issue & Salesforce support was able to fix it by creating an explicit URL to the VisualForce page.

Here's the change they made in my code.

String vfHostname = DomainCreator.getVisualforceHostname('c'); //Get the Visualforce hostname
String vfPageUrl = 'https://' + vfHostname + '/apex/QuotePDF_EU?id=' + quoteId; //Build the URL
PageReference pdf = new PageReference(vfPageUrl);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .