Last active
October 23, 2015 00:01
-
-
Save StevenMMortimer/f84f6d853ea3c886ebe4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(RForcecom) | |
library(XML) | |
library(RCurl) | |
username <- "YOURS" | |
password <- "YOURS" | |
instanceURL <- "YOURS" | |
apiVersion <- "34.0" | |
session <- rforcecom.login(username, password, instanceURL, apiVersion) | |
# define metadata endpoint | |
rforcecom.api.getMetadataEndpoint <- function(apiVersion){ | |
return(paste("services/Soap/m/", apiVersion, sep="")) | |
} | |
#helper function that converts a list of metadata to XML | |
metadataListToXML <- function(root, sublist, metatype=NULL){ | |
for(i in 1:length(sublist)){ | |
if (!is.null(metatype)){ | |
this <- newXMLNode("Metadata", attrs = c(`xsi:type`=metatype), parent=root, suppressNamespaceWarning=T) | |
} else { | |
this <- newXMLNode(names(sublist)[i], parent=root) | |
} | |
if (typeof(sublist[[i]]) == "list"){ | |
listToXML(this, sublist[[i]], metatype=NULL) | |
} | |
else{ | |
xmlValue(this) <- sublist[[i]] | |
} | |
} | |
return(root) | |
} | |
#let's read just the Account object's metadata | |
object_names <- c('Account') | |
object_list <- as.list(object_names) | |
names(object_list) <- rep('fullNames', length(object_list)) | |
#create XML for readMetadata call | |
root=newXMLNode("readMetadata", | |
namespaceDefinitions=c('http://soap.sforce.com/2006/04/metadata')) | |
root2=newXMLNode("metadataType", "CustomObject", parent=root) | |
metadataListToXML(root=root, sublist=object_list, metatype=NULL) | |
#build soapBody | |
soapBody <- paste0('<?xml version="1.0" encoding="UTF-8"?> | |
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<env:Header> | |
<SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata"> | |
<sessionId>', | |
session['sessionID'], | |
'</sessionId> | |
</SessionHeader> | |
</env:Header> | |
<env:Body>', | |
as(root, 'character'), | |
'</env:Body> | |
</env:Envelope>') | |
# perform request | |
# HTTP POST | |
h <- basicHeaderGatherer() | |
t <- basicTextGatherer() | |
httpHeader <- c("SOAPAction"="readMetadata", 'Content-Type'="text/xml") | |
curlPerform(url=paste0(session['instanceURL'], rforcecom.api.getMetadataEndpoint(apiVersion)), | |
postfields=soapBody, httpheader=httpHeader, headerfunction = h$update, writefunction = t$update, ssl.verifypeer=F) | |
x.root <- xmlRoot(xmlInternalTreeParse(t$value(), asText=T)) | |
result_body <- xmlToList(x.root)[['Body']][['readMetadataResponse']] | |
#result_body should contain a list the metadata for the Account object | |
# now rename the object metatdata Custom_Account__c to create a new Account object copy | |
result_body$result$records$fullName <- 'Custom_Account__c' | |
# we need to change a few metadata configurations that are prevented during creation | |
d <- result_body$result$records | |
# remove default actionOverrides | |
d[which(names(d) %in% c("actionOverrides"))] <- NULL | |
# remove lingering attribute tag | |
d$.attrs <- NULL | |
# specify a plural label | |
d$pluralLabel <- 'Custom_Accounts' | |
# specify a name field | |
d$nameField <- list(displayFormat='AN-{0000}', | |
label='Custom_Account__c Name', | |
type='AutoNumber') | |
# set the deployment status | |
d$deploymentStatus <- 'Deployed' | |
# make a description to identify this easily in the UI setup tab | |
d$description <- 'created by the Metadata API' | |
#construct XML | |
root=newXMLNode("createMetadata", namespaceDefinitions=c('http://soap.sforce.com/2006/04/metadata')) | |
if(typeof(d[[1]]) != "list"){ | |
d <- list(d) | |
} | |
metadataListToXML(root=root, sublist=d, metatype='CustomObject') | |
#construct SOAP | |
soapBody <- paste0('<?xml version="1.0" encoding="UTF-8"?> | |
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<env:Header> | |
<SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata"> | |
<sessionId>', | |
session['sessionID'], | |
'</sessionId> | |
</SessionHeader> | |
</env:Header> | |
<env:Body>', | |
as(root, 'character'), | |
'</env:Body> | |
</env:Envelope>') | |
# HTTP POST | |
h <- basicHeaderGatherer() | |
t <- basicTextGatherer() | |
httpHeader <- c("SOAPAction"="createMetadata", 'Content-Type'="text/xml") | |
curlPerform(url=paste0(session['instanceURL'], rforcecom.api.getMetadataEndpoint(apiVersion)), | |
postfields=soapBody, httpheader=httpHeader, headerfunction = h$update, writefunction = t$update, ssl.verifypeer=F) | |
x.root <- xmlRoot(xmlTreeParse(t$value(), asText=T)) | |
result_body <- xmlToList(x.root)[['Body']][['createMetadataResponse']] | |
# result body look like this | |
# <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata"> | |
# <soapenv:Body> | |
# <createMetadataResponse> | |
# <result> | |
# <fullName>Custom_Account__c</fullName> | |
# <success>true</success> | |
# </result> | |
# </createMetadataResponse> | |
# </soapenv:Body> | |
# </soapenv:Envelope> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am working through the code; this is great. I have worked with JSON in
R
in the past, butXML
is new to me, so I am slowly wrapping my head around this. I am excited for what's possible. What do you think the best place to start is?