Saving the contents of an image or file URL as an attachment or Salesforce content

I was recently given the following problem.  Given the URL of an image file like a jpg or a document file like a PDF can that file be saved as an attachment or a Salesforce content document?  The answer is yes,but we need to tie certain pieces of APEX together to make it work.  Here are our steps.

1) Add a Remote Site
- This will allow Salesforce to call out to this remote site using a HTTP Get call.
- To do this click on Your Name, Setup, Administration Setup, Security Controls, Remote Site Settings, click on ‘New Remote Site’.

2) Now we need our code to retrieve the contents of the remote file into Salesforce.  To test this type of code, I ran it in execute anonymous against my developer edition account.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Http h = new Http();
HttpRequest req = new HttpRequest();
string firstImageURL = 'http://www.myDomain.com/myImage.jpg';
//Replace any spaces with %20
firstImageURL = firstImageURL.replace(' ', '%20');
req.setEndpoint(firstImageURL);
req.setMethod('GET');
//If you want to get a PDF file the Content Type would be 'application/pdf'
req.setHeader('Content-Type', 'image/jpeg');
req.setCompressed(true);
req.setTimeout(60000);
                
HttpResponse res = null;
res = h.send(req);
//These next three lines can show you the actual response for dealing with error situations
string responseValue = '';
responseValue = res.getBody();
system.debug('Response Body for File: ' + responseValue);
//This is the line that does the magic.  We can get the blob of our file.  This getBodyAsBlob method was added in the Spring 2012 release and version 24 of the API.
blob image = res.getBodyAsBlob();

3) Now we can save that blob as an attachment

1
2
3
4
5
6
7
8
Attachment n = new Attachment();
//You will want to tie your attachment to some type of custom or standard object
//n.ParentId = myAccount.Id;
n.Name = 'myImage.jpg';
n.Body = image;
//If we were saving a PDF as an attachment the ContentType would be 'pdf'
n.contentType = 'image/jpeg';
insert n;

4) Or we can save it as a document in Salesforce content

1
2
3
4
5
6
7
8
9
10
11
12
//Not that by simply inserting into ContentVersion that the actual ContentDocument entry will be created for you
ContentVersion cv = new ContentVersion();
cv.VersionData = image;  //This is our blob
cv.title = 'MyImageName';
cv.Description = 'MyImageDescription';
cv.FirstPublishLocationId = '058E00000000RIg';  //This is the library
cv.TagCsv = 'Tag1';
cv.ReasonForChange = ''; // If we update an image then we may have to set this
//cv.ContentDocumentID = ''; //If we are inserting a revision to a document then we need this.  May have to query for it first
//When testing this remember that it takes a few seconds for a document to show up in the library
insert cv;

If you need to do a lot of images or PDFs at one time a batch APEX job could be setup so each one could be done separately.  Then we would not run into the limitation where we are only allowed 10 HTTP Callouts in one transaction.

Let me know if you find any creative ways of pulling in external documents into Salesforce.

Happy Coding!

This entry was posted in Technology and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>