4

First at all: Happy New Year to you and your family. I wish you all the best in new 2014 year.

And about my case:

I use 'MyPdfRenderingPage.getContent();' method to get Blob PDF-body, create PDF attachment and sent it by mail.

And a code (please see below) works great in Console's Execute Anonimous Window. It creates a mail with PDF file attached which I can open later.

But if I insert the same piece of code in my Email service (it receives a mail, creates a record and returns new mail with PDF attachment), it doesn't work correctly. I receive the mail, but can't open PDF attachment.

So I checked what does that Blob return content? If to execute 'MyPdfRenderingPage.getContent();' method in Email service, it returns HTML file with JS script inside leads to MyPdfRenderingPage.

In both cases the code runs by the same user, i did check it as well.

I have no idea what is wrong here...

Thanks a lot for your help.


And that code below


Messaging.reserveSingleEmailCapacity(5);

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

String[] toAddresses = new String[] {'[email protected]'};

mail.setToAddresses(toAddresses);

mail.setReplyTo('[email protected]');

mail.setSenderDisplayName('Support');

mail.setSubject('New Record Created : ' + newRecords[0].id);

mail.setBccSender(true);

mail.setUseSignature(false);

mail.setPlainTextBody('Your new record has been created.');

mail.setHtmlBody('Your new record has been created.');


    PageReference pdf = Page.MyPDFpage;
    pdf.getParameters().put('id', (String)newRecords[0].id);
    pdf.getParameters().put('position', '1');
    pdf.setRedirect(true);

    Blob pageContent = pdf.getContent();

    Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
    efa.setFileName('PrintThisPDF.pdf');
    efa.setBody(pageContent);                                                          

mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});                                                         

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
3
  • great question Denis - who or what exactly is sending email to this email service? An external system? a person? Or Apex code authored by you? Dec 31, 2013 at 19:44
  • What about an Email Template with an expressed Attachment utilising a VF Component to render the content? (you can set the Email Template Id in your code, and thus the body, attachment etc is expressed via the template). Jan 3, 2014 at 13:01
  • Dear Andrew Fawcett! Thanks a lot for your comment. Probably your great idea is close to an idea in the second answer below. I will try it later - I'm exhausted today. Hopefully we will not face with 'Session ID is null' problem, if to go this way. Jan 3, 2014 at 21:47

2 Answers 2

7

You can't get the PDF content unfortunately.

While Email Services do run under a 'Context User', you will notice that UserInfo.getSessionId() returns null from any InboundEmailHandler implementation you may have.

The HTML with JavaScript is serving up a client-side redirect to a Salesforce login page. This is because pdf.getContent() runs in a different execution context that also lacks a Session ID at the time of making the request to render the page.

Salesforce have documented this:

This method can't be used in [...] Apex email services

2
  • Dear user320! I appreciate greatly your answer! Happy New Year for you! Your answer surprised me - it has been the first time I see that SFDC can not do something. In my case we expect emails both from an external system and probably users. They should send a mail with CSV file to be parsed. Email service parses the file, makes records and returns (good formated, good-looking) file (pdf is perfect for that) which contents pictures with QR codes. (please see continuation in the next comment) Jan 1, 2014 at 18:04
  • I expect a lot of situations in coming projects, when an Email service should send a mail reply with 'on the fly' created PDF file. And what to do? Can we SAVE that PDF rendered page like a PDF-Attachment or PDF-Document to our Org and than attach it to the mail? Can we do it in Email service execution context? Or one more idea: is it possible to run APEX code within any Session programmatically, in other words without a real person login in the system? Thank you so much for your great help. Jan 1, 2014 at 18:05
4

If you consider that the lowest common denominator in this scenario, is the creation of the new record - it might be worth considering a Workflow Rule to send out the email with the attachment using a Visualforce Email Template. That way, you don't have to write Apex code to send the email (thus preserving your daily limit).

Firstly, you'd need to create a Visualforce Email Template, for example:

<messaging:emailTemplate subject="New Record Created {!relatedTo.Id}" recipientType="User" relatedToType="Account">

    <messaging:attachment renderAs="PDF" filename="{!relatedTo.Name}.pdf">
        Place the Visualforce in MyPDFPage here     
    </messaging:attachment>

    <messaging:plainTextEmailBody >
        Your new record has been created.   
    </messaging:plainTextEmailBody>

</messaging:emailTemplate>

And then refer to that in a simple workflow rule that 'fires' everytime a new record is created (i.e. the thought being, your email service creates your new record but you delegate the sending of the email/attachment to workflow upon record creation), for example:

enter image description here

There may be other reasons that exclude the use of workflow, but I thought it worth a mention as its often overlooked.

2
  • Dear Phil Hawthorn! Thanks a lot for your great answer. I will try it later- I'm exhausted today. Hopefully we will not face with 'Session ID is null' problem, if to go this way. I hope so much... Plus we still need to put parameters in the PDFpage, I do hope all that works together... Jan 3, 2014 at 22:00
  • Good luck @DenisBrown, let us know how you get on. Jan 4, 2014 at 0:20

You must log in to answer this question.

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