如何使用 R 连接 Salesforce?

How to Connect Salesforce using R?

我正在获得 500 状态。有人能帮我吗

我在尝试执行登录操作时尝试使用 R 连接 Salesforce。我没有成功,请你看看这段代码并纠正我遗漏的地方。

library(RCurl)
library(httr)

  body1 = '<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
  <login xmlns="urn:partner.soap.sforce.com">
  <username>xxxxxx.Test@xxxxxx.com.xxxxxxx</username>
  <password>xxxxxxxxxxxx</password>
  </login>
  </s:Body>
  </s:Envelope>'

x <- httr::POST(url = "https://test.salesforce.com/services/Soap/48.0", body = body1, content_type("text/xml;charset=UTF-8"),SOAPAction = "login")
x$status_code

可能有很多事情,并不都与您的代码有关...

  1. 您的 SOAP 命名空间可能有误。也许首先尝试使用 SoapUI / Postman / curl,一旦你让它们工作 - 检查代码。试试这个版本的标签

     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com">
        <soapenv:Body>
           <urn:login>
              <urn:username>usernamegoeshere</urn:username>
              <urn:password>passwordgoeshere</urn:password>
           </urn:login>
        </soapenv:Body>
     </soapenv:Envelope>
    
  2. 手动登录 SF 组织并在页面底部查看该用户的登录历史记录。你看到你的尝试了吗?如果不是 - 你确定你连接到正确的地方(生产与沙箱)?或者,也许您的公司 IT 安装了一些代理,它只是吞噬了连接……如果登录历史记录中有一个条目 - 它是否表示密码无效?登录尝试失败次数过多?需要安全令牌?

  3. 管理员可能禁用了从通用 test.salesforce.com 登录,您必须使用在设置 -> 我的域中看到的内容。

  4. 管理员可能将您的用户设置为单点登录(您看到的是正常的 SF 登录页面还是被重定向到某些 Active Directory 内容)。如果是这种情况,通过 API.

    连接会更棘手
  5. 也许您的用户未启用 API,这是个人资料/权限集的问题。您是否使用系统管理员帐户?配置文件上是否有任何登录策略,例如只能从特定 IP 访问或在特定登录时间内访问。

我维护一个名为 {salesforcer} 的 R 包,它允许用户与 6 种不同的 Salesforce API(SOAP、REST、Bulk 1.0、Bulk 2.0、元数据、报告和仪表板)交互以管理他们的组织。如果这些 API 之一满足您的需求,我建议您使用该包,这样您就不需要从头开始编写代码。下面是一个示例,说明如何使用 OAuth 2.0(有时称为单点登录)或使用用户名、密码和安全令牌进行连接。请访问软件包的文档站点以获取更多详细信息和插图:https://stevenmmortimer.github.io/salesforcer/

# install.packages('salesforcer')
library(salesforcer)

# Using OAuth 2.0 authentication
sf_auth()

# Using Basic Username-Password authentication
sf_auth(username = "test@gmail.com", 
        password = "{PASSWORD_HERE}",
        security_token = "{SECURITY_TOKEN_HERE}")

# pull down information of person logged in
# it's a simple API call to get started 
# and confirm connection to the APIs
user_info <- sf_user_info()

sprintf("Organization Id: %s", user_info$organizationId)
#> [1] "Organization Id: 00D6A0000003dN3UAI"

sprintf("User Id: %s", user_info$userId)
#> [1] "User Id: 0056A000000MPRjQAO"

感谢您回答问题。经过几次尝试,我了解到 headers 中存在一些问题。我修复了 headers,它现在运行良好。我能够在 Salesforce 中毫无问题地执行查询。我已经在这里发布了我的完整代码,所以任何人都可以使用它。我不是这方面的专家,但仍然可以使用此代码进行管理。

#######Required Packages
library(RCurl)
library(httr)
library(XML)
library(jsonlite)
library(xml2)
library(magrittr)
library(randomNames)
library(rlang)
library(generator)
library(stringr)
require(data.table)

body1 = '<?xml version="1.0" encoding="utf-8"?>\
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\
  <s:Body>\
    <login xmlns="urn:partner.soap.sforce.com">\
      <username>XXXXXXXXXXXXXX</username>\
      <password>XXXXXXXXXXXXXXX</password>\
    </login>\
  </s:Body>\
</s:Envelope>\n'

require(httr)
################################Posting the Login##############################################
result <- POST("https://test.salesforce.com/services/Soap/u/48.0",body = body1,add_headers(.headers = c("Content-Type"="text/xml",'SOAPAction' = "https://test.salesforce.com")))

##############Parsing XML###############################################################
Output <- content(result)
doc = xmlTreeParse(Output, useInternal = TRUE)
top = xmlRoot(doc) 
xmlName(top)
names(top) 
names(top[[1]] [[1]] [[1]])
Session = top[[ 1 ]] [[1]] [[1]] [["sessionId"]] 
SessionId <- Session [1][1]$text
tok <- xmlToList(SessionId)  
Se <- paste("Bearer",tok,Sep="")
Se = trimws(Se)
Sever = top[[ 1 ]] [[1]] [[1]] [["serverUrl"]] 
SessionURL <- Sever [1][1]$text

################SF Query###########################################
SFQuery <- "SELECT Id,FirstName FROM Conatct limit 10"
SFQuery_Req <- GET(Pam,query = list(q=SFQuery),add_headers(Authorization=Se))
SFQuery_Con <- content(SFQuery_Req, as = 'text') %>% fromJSON()
SFQuery_Con_DF <- data.frame(SFQuery_Con$records)