We created an 100% native Salesforce IDE as a Managed Package which is using ToolingAPI and MetadataAPI via APEX. This works fine. But there is one thing which really bothers people after the installation of the package: they are annoyed be the well know endpoint-exception:
System.CalloutException: IO Exception: Unauthorized endpoint, please check Setup->Security->Remote site settings
In my opinion it is very bad to let users run into that exception - even if you may assume that developers are the target-group and they will figure the simple steps to proceed. We want to do it better.
What we have done first, was to include the most common endpoints as Remote-Sites in the packaged - knowing that we'll never be able to cover all due to the myDomain feature. So we have done it for na0..naX, eu0..euX and csX. Now, I have developed a strong dislike to this kind of bulk-inclusion, because:
- it is bad to include > 30 endpoints in a (frustrated) preemptive measure when only a single one is really required.
- there is an issue in the installer, when you need to confirm the endpoints and the list is too long, the confirm-button falls out of the visible screen area...
- for sure, security review will dislike that sort of misdemeanor - and I totally agree.
So what can we do? Writing an manual or display a nice list of post-install manual steps? C'mon, still not nice. One guy from Salesforce suggested a Heroku-Proxy: APEX calls Heroku (one static endpoint, passing required endpoint as parameter) and Heroku calls back MetadataAPI to configure the endpoint... hmmmm... overkill...? What else?
I just read this very cool answer from @sfdcfox here Dynamically set remote site Setting in Apex Fast-forward discarding the options Flash, Java, Silverlight and ThirdParty as having too many tradeoffs, I really love the JavaScript idea!
Now, my draft would be to create a Post-Install page which contains the JavaScript. First thing to ask for username, password and token (or better go with OAuth?). Then to access MetadataAPI via a callout by Javascript and dynamically add the single endpoint to the org. Bottom-line: the Heroku-Pattern without Heroku ;-)
And finally here is my question: does anyone of you have accessed MetadataAPI directly from JavaScript? Even if in a completely different use-case, a JS-callout-skeleton to do just "something" with the MetadataAPI would help me a lot to figure out the final solution on my own. Or are there any obvious show-stoppers which prevent JavaScript from accessing the MetadateAPI?
I think it could be worth to share a concept here, since it would be a repeatable pattern usable for many use cases.