In this article I will show the simple and straight forward method for adding an attachment to a Opportunity using the Salesforce REST APIs.
Introduction
This article is written as a summation of a frustrating couple of days trying to discern the Salesforce REST API documentation. I started with the Insert or update Blob page. With all the examples based on UNIX commands it made it very difficult to figure out how to do this using client side JavaScript.
Eventually I realized there was a link to the SObject Basic Information help page and SObject Rows help page. Using a combination of all three pages of information as a reference I was able to figure out how to do what I needed to. I needed to write it up as I will likely forget about it 😉
Adding attachments
To add an attachment into Salesforce you have to get the base64 encoded string thereof and submit it as an Attachment Object, referencing the parentId of the Opportunity.
In my example I have an opportunity Id = 00658000004kGVRAA2. note that there are no attachments.
Using the combination of the three help documents I was able to figure out that sending the base64 encoded attachment to the opportunity is nothing more complicated that constructing the following
var root = "https://yourpath.my.salesforce.com/" var url = root+"services/data/v37.0/sobjects/Attachment" var data = { "Name" : "demoAttachment.pdf", "Body": "Base64Encoded Attachment", "parentId": "00658000004kGVRAA2" //the id of the opportunity } $.ajax({ url: url, method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer "+OAuthToken }, data: JSON.stringify(data) })
When the POST is successful you will receive the new Id of the Attached file
The attachment appears on the opportunity
and we can download and open the file
Conclusion
The important part of this example is to understand that we are not creating an attachment from the opportunity. We are creating the attachment and associating itself with the opportunity. Trying to go at the opportunity and throw the attachment at it directly was a complete failure.
Thanks for the post. I have uploaded an attachment fine but it doesn’t recognize the file type, in your example a PDF. If you attach a PDF using the Salesforce GUI it will show it as a PDF file, which will then open in the browser if you click on it, rather than having to download it first and then open it.
Any ideas on how to do this. I may try uploading as a multipart upload.
Thanks in advance.
Regards
Steve
It’s OK, it looks like I need to create a ContentVersion object, which is the new way of doing it … apparently ..
Regards
Steve
Sorry for not getting back to you quicker 🙂
Thanks for the update 🙂
Hey Marky, thanks for the post. Any direction on how you Base64 encoded your file? I am using an ETL tool, but my Base64 encoding will literally encode the file path string, not the file the path is pointing to.
Have you tested your Base64 encoding for 25+ MB Files?
Salesforce claims their REST API supports up to GB files, but the Base64 encoded string I copied for a 66MB zip file into Workbench to test is so massive that is crashed the workbench browser.
SF Doc on File Sizes with REST API:
https://help.salesforce.com/articleView?id=collab_files_size_limits.htm&type=0
Thanks for leaving a comment 🙂
When I built my demo for this IRL I used the browser to do the encoding using the HTMl5 canvas object – and sure as hell that will blow up if you use huge files in the browser I am afraid. I am not using files that large I am afraid – sorry for not being much more help I am afraid.
How to get the OAuthToken in the VF page?
Please help me on getting OAuthToken, I tried using {!GETSESSIONID()} and also “Authorization”: “Bearer {!$Api.Session_ID}”, it does not create attachment. Any pointers on this?
Thanks Marky, this was super helpful.
In case anyone is still looking, I got the session ID (to use as the OAuthToken in the example) like so:
// Visualforce page
jstag
vfData = {
sessionID: “{!$Api.Session_ID}”
};
closejstag
// In my JS
“Authorization”: “Bearer ” + window.vfData.sessionID
One other thing I wasn’t entirely clear on was the format of the domain I should use. I saw some documentation that suggested the REST API calls should go to xxxx.salesforce.com (e.g. cs19.salesforce.com) and some that suggested xxxx.my.salesforce.com. The format that worked for me was: https://ourdomain–sandboxname.cs19.my.salesforce.com, of course replacing your domain, sandbox and instance name, which in my case was cs19.
Hope that helps.
Oh also, to get the response back properly, I needed to add my domain as a Whitelisted Origin in SF Admin -> Security Controls -> CORS
Thank you so much for taking the time to share mate !!!! 🙂