2017-02-21 78 views
0

我在使用httr將文件發佈到Salesforce's REST API時遇到了一些麻煩。我認爲this SO question可能會照顧它,但似乎並沒有。我有一種預感,這是因爲Saleforce想要一個非二進制部分和upload_file創建form_file類的對象,作爲一個二元處理,但也許有人有另一種解釋/解決方案...如何使用httr(適用於Salesforce API)POST多部分二進制和非二進制

Salesforce的詢問以下捲曲的要求插入一個新的文檔:

curl https://yourInstance.salesforce.com/services/data/v23.0/sobjects/Document/ -H 
"Authorization: Bearer token" -H "Content-Type: multipart/form-data; 
boundary=\"boundary_string\"" --data-binary @newdocument.json 

newdocument.json看起來像這樣:

--boundary_string 
Content-Disposition: form-data; name="entity_document"; 
Content-Type: application/json 
{ 
"Description" : "Marketing brochure for Q1 2011", 
"Keywords" : "marketing,sales,update", 
"FolderId" : "005D0000001GiU7", 
"Name" : "Marketing Brochure Q1", 
"Type" : "pdf" 
} 
--boundary_string 
Content-Type: application/pdf 
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf" 
Binary data goes here. 
--boundary_string-- 

如果我嘗試生成的使用@吉榮的回答作爲一個有益的指導imilar輸出,我得到一個錯誤的請求錯誤:

library(httr) 
library(jsonlite) 

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/" 
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]")) 

media <- tempfile() 
png(media, width = 800, height = 600) 
plot(cars) 
dev.off() 

metadata <- tempfile() 
x <- data.frame(FolderId="a0a1300000ZG7u3", Name="test.png") #Salesforce Record ID and file name 
json <- toJSON(unbox(x), pretty=T) 
writeLines(json, metadata) 

body <- list(entity_document = upload_file(metadata, type = "application/json; charset=UTF-8"), 
      Body = upload_file(media, type = "image/png")) 


req <- POST(url, header, verbose(), body = body) 

(詳細輸出)

-> POST /services/data/v39.0/sobjects/Document/ HTTP/1.1 
-> Host: [Salesforce Instance] 
-> User-Agent: libcurl/7.51.0 r-curl/2.3 httr/1.2.1.9000 
-> Accept-Encoding: gzip, deflate 
-> Accept: application/json, text/xml, application/xml, */* 
-> Authorization: Bearer [Salesforce Key] 
-> Content-Length: 3720 
-> Expect: 100-continue 
-> Content-Type: multipart/form-data; boundary=------------------------6525413b2350e313 
-> 
<- HTTP/1.1 100 Continue 
>> --------------------------6525413b2350e313 
>> Content-Disposition: form-data; name="entity_document"; filename="file1510059b5200f" 
>> Content-Type: application/json 
>> 

>> { 
>>  "FolderId": "a0a1300000ZG7u3", 
>>  "Name": "test.png" 
>> } 

>> 
>> --------------------------6525413b2350e313 
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950" 
>> Content-Type: image/png 
>> 

>> ‰PNG 
>> 

>> 
>> --------------------------6525413b2350e313-- 

<- HTTP/1.1 400 Bad Request 

在第一部分中的文件名以外,這是相當接近期望的輸出,但Salesforce的返回消息:

content(req) 

[[1]] 
[[1]]$message 
[1] "Cannot include more than one binary part" 

[[1]]$errorCode 
[1] "INVALID_MULTIPART_REQUEST" 

我只用JSON嘗試,但得到一個稍微不同的錯誤請求:

body <- list(entity_document= json, 
      Body = upload_file(media, type = "image/png")) 

-> Content-Type: multipart/form-data; boundary=------------------------ecbd3787f083e4b1 
-> 
<- HTTP/1.1 100 Continue 
>> --------------------------ecbd3787f083e4b1 
>> Content-Disposition: form-data; name="entity_document" 
>> 
>> { 
>>  "FolderId": "a0a1300000ZG7u3", 
>>  "Name": "test.png" 
>> } 
>> --------------------------ecbd3787f083e4b1 
>> Content-Disposition: form-data; name="Body"; filename="file151001ac96950" 
>> Content-Type: image/png 
>> 

>> ‰PNG 
>> 

>> 
>> --------------------------ecbd3787f083e4b1-- 

content(req) 

[[1]] 
[[1]]$message 
[1] "Multipart message must include a non-binary part" 

[[1]]$errorCode 
[1] "INVALID_MULTIPART_REQUEST" 

挖掘到的細節,但在我看來,捲曲無論是讀取和張貼元數據文件作爲二進制如果我使用upload_file或職位不JSON內容類型,如果我將它張貼的字符。這是唯一的問題嗎?如果是這樣,有沒有辦法修改處理程序接受內容類型?

任何幫助非常感謝!

回答

0

這裏的基礎上@吉榮的最新補充curl一個(臨時)解決方案(見Github issue供參考):

library(curl) #>=2.4 on Cran 
library(httr) 
library(jsonlite) 

url <- "https://[Salesforce Instance]/services/data/v39.0/sobjects/Document/" 
header <- add_headers(c(Authorization = "Bearer [Salesforce Key]")) 

path <- tempfile() 
png(path, width = 800, height = 600) 
plot(cars) 
dev.off() 

media <- upload_file(path) 

x <- data.frame(Name=basename(path),ParentId="[Salesforce Parent ID]",Description="",IsPrivate=FALSE) 
x <- as.character(toJSON(unbox(x),pretty=T)) 
metadata <- form_data(x,"application/json") #new curl function to handle a character body with defined type 

body <- list(metadata=metadata,Body=media) 

req <- httr:::request(fields=body) 
req <- httr:::request_build("POST",url,req,header) 

response <- httr:::request_perform(req,new_handle()) 

我把一個requesthttr將這一新的處理和想象,它會更簡單易用,即一旦他們接近它,簡單的POST(url,header,body=body)

希望它有幫助!