[SalesForce] Get xls File on Remote Server and Send as Email Attachment APEX

I have an xls file sitting on www.mysite.com/files/myfile.xls. I would like to have SalesForce via APEX grab (Not Read) this file and send it as an attachment to an email.

I know how to send emails in SalesForce via APEX, however I'm not sure how to:
1. Grab a file on a remote server with APEX
2. Attach this file to an email and send from APEX.

I have looked over the web for solutions on the first and have only come across a few unanswered questions.

I have looked over the below info about attachments, but not sure if xls files can be used in the getContent() method. First thing I wanted to get figured out is the grabbing a file from a server.
http://www.salesforce.com/us/developer/docs/pages/Content/pages_email_sending_attachments.htm

I believe I could POST the file from that server via PHP to SalesForce and invoke an APEX class, but I was hoping to do it all from SF to avoid logging in as a user.

Any help is greatly appreciated.

I've tested out the solution below, but I believe I am not putting in the correct URL. My code is below, and the error I receive is:

Error:

A problem with the OnClick JavaScript for this button or link was encountered:

{faultcode:'soapenv:Client', faultstring:'System.VisualforceException: No Visualforce context has been established!

Class.AccountExcelGetAndEmail.getExcelFile: line 18, column 1', }

Code:

global class AccountExcelGetAndEmail {


WebService static void getExcelFile(string id){

List<User>Users = [SELECT id From User Where email = 'infoSys@mycompany.com' AND name = 'API Admin'];
User testUser = Users[0];


PageReference ref = new PageReference('http://dev.mysite.com/sf/PHPExcel_1_7_9/testCSV%20-%20Copy.xls');
system.debug('Page Ref'+ref);
Blob b = ref.getContent();
Messaging.SingleEmailMessage m = new Messaging.SingleEmailMessage();
m.setTargetObjectId(testUser.id);
Messaging.EmailFileAttachment a = new Messaging.EmailFileAttachment();
a.setBody(b);
a.setContentType('application/vnd.ms-excel');
a.setFileName('some-file.xls');
a.setInline(false);
m.setFileAttachments(new Messaging.EmailFileAttachment[] { a } );
m.setSubject('Test');
m.setPlainTextBody('See attachment');
m.setSaveAsActivity(false);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { m } );

}

}

However, per this page, I am referencing a page properly.

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_pages_pagereference.htm

Update: Its not because I am calling a file vs a web page. If I set the page reference to

PageReference ref = new PageReference('http://www.mysite.com');

The same error still occurs.

Solution

I ended up using HTTP Request/Response as suggested it could be done this way over PageReference. Never did figure out why PageReference would not work but HTTP Request/Response does?
Code is below: ( I removed wrapper class and webservice class. this code would go in the webservice class)

        List<User>Users = [SELECT id From User Where email = 'testUser@gmail.com'];
    User testUser = Users[0];
    // Instantiate a new http object
        Http h = new Http();
        String url = 'http://mysite.com;
    // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');

    // Send the request, and return a response
        HttpResponse res = h.send(req);
        //system.debug(res.getBody());


    Blob myBlob = res.getBodyAsBlob(); 
    Messaging.SingleEmailMessage m = new Messaging.SingleEmailMessage();
    m.setTargetObjectId(testUser.id);
    Messaging.EmailFileAttachment a = new Messaging.EmailFileAttachment();
    a.setBody(myBlob);
    a.setFileName('some-file.xls');
    a.setInline(false);
    m.setFileAttachments(new Messaging.EmailFileAttachment[] { a } );
    m.setSubject('Test');
    m.setPlainTextBody('See attachment');
    m.setSaveAsActivity(false);
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { m } );

Thank you sfdcfox!

Best Answer

Here's one way that you can accomplish your task. The other involves the use of Http, HttpRequest, and HttpResponse. Either method is acceptable and will deliver the contents of your file to Apex Code for delivery. Note that you must allow the site in Remote Site Settings for this to work. I find that using PageReference is a little "lighter" than using Http for things like this.

PageReference ref = new PageReference('<some url here>');
Blob b = ref.getContent();
Messaging.SingleEmailMessage m = new Messaging.SingleEmailMessage();
m.setTargetObjectId(UserInfo.getUserId());
Messaging.EmailFileAttachment a = new Messaging.EmailFileAttachment();
a.setBody(b);
a.setContentType('application/vnd.ms-excel');
a.setFileName('some-file.xls');
a.setInline(false);
m.setFileAttachments(new Messaging.EmailFileAttachment[] { a } );
m.setSubject('Test');
m.setPlainTextBody('See attachment');
m.setSaveAsActivity(false);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { m } );

Updated

HTTP version:

Http binding = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint('<some url here>');
HttpResponse res = binding.send(req);
Blob b = res.getbodyasblob();

The rest of the code, of course, is identical.

Related Topic