You need to sign in to do that
Don't have an account?

How to attach external PDF file to the email sent via Apex code
Hi,
The following links shows how to attach pdf and send email using Apex code
http://www.salesforce.com/us/developer/docs/pages/Content/pages_email_sending_attachments.htm
The part in the article given at end of my post reads a pdf and set its content as attachment.But this example only shows how to attach VisualForce page which is renderd as PDF.
When I tried same example code with a PDF file hosted on some other server and is public(Say: http://myserver.com/myFile.pdf). The VisualForce page runs without error, but does not give any response. Doesn't Apex attaching external files as attachment with email. If Not is there any other workaround. The problem is I want to attach a PDF which is hosted on some other server and send email using Apex.
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
// Reference the attachment page and pass in the account ID
PageReference pdf = Page.attachmentPDF;
pdf.getParameters().put('id',(String)account.id);
pdf.setRedirect(true);
// Take the PDF content
Blob b = pdf.getContent();
// Create the email attachment
Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
efa.setFileName('attachment.pdf');
efa.setBody(b);
Rohit - as I had mentioned in my original post, you can't do what you're trying to do with Apex HTTP callouts either. Apex HTTP callouts currently only support a String/text type response. You can't access binary data (like your PDF) using HTTP callouts as you're trying to do. Your only option is still to somehow store the PDF inside Salesforce (as an Attachment or Document or Content file) and access it that way. Hope this helps.
All Answers
Unfortunately you can't currently access binary data hosted on an external site using Apex - either via a direct HTTPRequest callout or indirectly via a VF page that points to the external URL (as you're trying to do). The only option I can think of for you is to store this external PDF in Salesforce (assuming that its static content) either as an Attachment or a Document and then use SOQL to query its content and attach to the email message.
Thanks forecast_is_cloudy for the quick reply. As you specified in your response it is not directly possible I tried to adapt a diffrent method using HTTP callouts.
I used following code in my Apex Class
I am trying to get PDF content as a blob using HTTP callout and creating an email attachment using this Blob. But when I open the email and save the PDF attachment and open it. It opens as blank PDF document always. Not sure either I am missing something or this is not possible at all using Apex code.
Please guide me.
Note: in my code replace myemail@myemail.com with your email id so that you will receive an email with PDF.
Thanks.
-----------------Apex Class START----------------------
public class PDFCreator
{
public PDFCreator()
{
}
public void createPDF()
{
try
{
// Instantiate a new http object
Http h = new Http();
// Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
HttpRequest req = new HttpRequest();
req.setEndpoint('http://www.salesforce.com/assets/pdf/datasheets/sales-force-automation.pdf');
req.setMethod('GET');
// Send the request, and return a response
HttpResponse res = h.send(req);
System.debug('res is>>>>>>'+res);
System.debug('res.getBody()>>>>>>'+res.getBody());
Blob pdfContent= Blob.valueOf(res.getBody());
//System.debug('pdfContent>>>>'+pdfContent);
// Define the email
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'myemail@myemail.com'};
Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
efa.setFileName('attachment.pdf');
efa.setContentType('application/pdf');
efa.setBody(pdfContent);
email.setSubject('Testing PDF attachment');
email.setToAddresses(toAddresses);
email.setPlainTextBody('Hello');
email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
// Sends the email
Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
//System.debug('>>>>>Email sent result'+r);
}
catch(Exception ex)
{
System.debug('>>>>>>>>>>>>>><<<'+ex);
}
}
}
-----------------Apex Class END----------------------
I have also tried following approach, but this works only with files hosted on salesforce.com server, for other servers (Even after adding them in Remote Site Settings) function never gets executed completely)
public void readPDF()
{
PageReference pdf = new PageReference('http://www.genius.com/media/GeniusDatasheet.pdf');
Blob b = pdf.getContentAsPDF();
System.debug('Blob is>>>>>>>'+b);
// Define the email
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'youremail@yourdomain.com'}; //{a.CreatedBy.Email};
Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
efa.setFileName('attachment.pdf');
efa.setContentType('application/pdf');
efa.setBody(b);
email.setSubject('Testing PDF attachment');
email.setToAddresses(toAddresses);
email.setPlainTextBody('Hello1');
email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
// Sends the email
Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
//System.debug('>>>>>Email sent result'+r);
}
Rohit - as I had mentioned in my original post, you can't do what you're trying to do with Apex HTTP callouts either. Apex HTTP callouts currently only support a String/text type response. You can't access binary data (like your PDF) using HTTP callouts as you're trying to do. Your only option is still to somehow store the PDF inside Salesforce (as an Attachment or Document or Content file) and access it that way. Hope this helps.
Hi forecast_is_cloudy,
Thanks again for the quick reply and explanation. I have accepted your last post as a solution to the problem. But it would be great if you help me in giving some directions if I want to periodically read the files on external server and store them as documents or attachments in Salesforce, without manual upload by SFDC user.
Can we do this using batch apex (I guess we can not as you have already mentioned that Apex can not do this)?
If not can you give me someinformation how we can do this using some third party integration, may be Apex or .NET. or Adobe Flex.
I have refered SFDC forums, documentation and other SFDC related blogs, but yet did not get any solution.
Rohit - I would recommend that you develop an external program/application that periodically updates Salesforce with the latest PDF. In other words, instead of a 'pull' model where Salesforce reaches out and grabs the PDF (which is not currently possible to do) you implement a 'push' model whereby an external application pushes the PDF(s) into Salesforce periodically. You can develop such an external application is the language of your choice (Java, .NET, PHP etc.) and then have it use the Salesforce Web Services API to post the PDF as an attachment to Salesforce. Hope this helps.
Thanks forecast_is_cloudy. I will try to explore in the directions you have given. I hope JAVA or .NET wil alllow me to read external files as blob and store it in Salesforce as attachments using Web services API.
Best of luck!
Hi rohit, currently working on similar kind of task, could you please let me know your result in getting the pdf from external server and email it as an attachment.
Hi,
Finally instead of pure Apex approach, I used Integration with Java. Here I sent my email body and subject to a java code along with file Id (A refernce Id of pdf file which has been stored on some remote location) using Apex callouts and then I used java code with SFDC partner WSDL integration to send email with this PDF file as an attachment.
So file has been read in javacode instead of Apex.This approach worked well for me.
thank you so much for replying back. It would be really helpful if could you e send me that java code to access pdf file from external servers to vk.raavi@gmail.com .
// URLName is complete url of your file
public String dump(String URLName)
{
try
{
URL u = new URL(URLName);
HttpURLConnection con = (HttpURLConnection) u.openConnection();
String contentType = con.getContentType();
int contentLength = con.getContentLength();
if (contentType.startsWith("text/") || contentLength == -1) {
thrownew IOException("This is not a binary file.");
}
InputStream raw = con.getInputStream();
InputStream in =
newBufferedInputStream(raw);
data = newbyte[contentLength];
int bytesRead = 0;
int offset = 0;
while(offset < contentLength) {
bytesRead = in.read(
data, offset, data.length- offset);
if(bytesRead == -1)
break;
offset += bytesRead;
}
in.close();
return"Success";
}
catch(Exception e) {
e.printStackTrace();
}
return"Failure";
}
Use this one:
That's all, now I receive the PDF in the email.