I'm working on uploading attachments from my website to Salesforce, attachments should be related to case object. I'm using REST API in PHP. So problem is that I get an error when I tried to upload new file. Other requests to Salesforce working well.
I'm logged in using this code:
curl_setopt($curl, CURLOPT_URL, "https://" . $this->salesforce_host . "/services/oauth2/token");
curl_setopt($curl, CURLOPT_POSTFIELDS, "client_id=" . $this->salesforce_client_id. "&grant_type=password&client_secret=" . $this->salesforce_client_secret . "&username=" . $this->salesforce_username . "&password=" . $this->salesforce_password . $this->salesforce_token);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded;"));
where $this->salesforce_host == 'test.salesforce.com'. I'm tested on developer account now.
In result I receive session ID and instance URL which I use in futher scripts. Instance url = https://cs30.salesforce.com.
Here is a PHP script that I use for upload files:
// https://$salesforceurl/services/data/v29.0/chatter/feeds/record/$caseId/feed-items
$session = $this->getSession();
$url = $session["instanceUrl"] . "/services/data/v" . $this->salesforce_version . "/chatter/feeds/record/" . $parentId . '/feed-items';
$curl = $this->_getDefaultCurl();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
//get file mime type and binary content of file
// form field separator
$delimiter = uniqid();
$fileFields = array(
'fileFeedItem' => array(
'type' => $finfo_mime,
'content' => implode('', $buffer)
),
);
$data = '';
$data .= "--" . $delimiter . "\r\n";
$data .= 'Content-Disposition: form-data; name="json";' . "\r\n";
$data .= 'Content-Type: application/json; charset=UTF-8;' . "\r\n\r\n";
$fileName = basename($file);
$json = array(
'body' => array(
'messageSegments' => array(
'type' => 'Text',
'text' => 'User uploaded attachment'
)
),
'attachment' => array(
'attachmentType' => 'NewFile',
'title' => $fileName
),
);
$data .= json_encode($json)."\r\n";
$data .= "\r\n\r\n";
foreach ($fileFields as $name => $fileItem) {
$data .= "--" . $delimiter . "\r\n";
$data .= 'Content-Disposition: form-data; name="feedItemFileUpload"; filename="' .$fileName . '"' . "\r\n";
$data .= 'Content-Type: ' . $fileItem['type'] . "\r\n";
$data .= 'Content-Transfer-Encoding: binary' . "\r\n";
$data .= "\r\n";
$data .= $fileItem['content'] . "\r\n";
}
$data .= "--" . $delimiter . "--\r\n";
$headers = '';
$headers .= "Accept: application/xml"."\r\n";
$headers .= "Content-Type: multipart/form-data; boundary=".$delimiter."\r\n";
$headers .= "Authorization: OAuth ". $session["sessionId"] ."\r\n";
$headers .= "Host: ". $session["instanceUrl"] ."\r\n";
$headers .= "Content-Length: " . strlen($data) . "\r\n";
$headers .= "Expect: 100-continue" . "\r\n";
$headers .= "\r\n";
$data = $headers . $data;
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response_json = curl_exec($curl);
here is $data content that I've added to request:
Accept: application/xml
Content-Type: multipart/form-data; boundary=52dd7f7e5fd87
Authorization: OAuth <session_id>
Host: https://cs30.salesforce.com
Content-Length: 494
Expect: 100-continue
--52dd7f7e5fd87
Content-Disposition: form-data; name="json";
Content-Type: application/json; charset=UTF-8;
{"body":{"messageSegments":{"type":"Text","text":"User uploaded attachment"}},"attachment":{"attachmentType":"NewFile","title":"attachment_test.txt"}}
--52dd7f7e5fd87
Content-Disposition: form-data; name="feedItemFileUpload"; filename="attachment_test.txt"
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: binary
�ttachment_test
--52dd7f7e5fd87--
But in response I got this error:
[{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]
Please help me how to solve this problem. I've tried many variants of code to decide this problem. Perhaps I should reset security token? But other Salesforce functions works well. Or I should to use another instance url?
Thanks, Yuriy
EDIT: new script
$session = $this->myLogin();
$url = $session["instanceUrl"] . "/services/data/v" . $this->salesforce_version . "/chatter/feeds/record/" . $parentId . '/feed-items';
$curl = $this->_getDefaultCurl();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
$fileName = basename($file);
$json = array(
'body' => array(
'messageSegments' => array(
'type' => 'Text',
'text' => 'User uploaded attachment'
)
),
'attachment' => array(
'attachmentType' => 'NewFile',
'title' => $fileName
),
);
$headers = array();
$headers[] = "Authorization: OAuth ". $session["sessionId"];
$headers[] = "Content-Type: application/json; charset=utf-8";
$headers[] = "Accept: application/json";
$fileArray = array(
'json' =>$json,
'feedItemFileUpload' => '@'.realpath($file),
);
$data = json_encode($fileArray);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
$response_json = curl_exec($curl);
Auth works well, but I got an error:
[{"message":"Unrecognized field \"json\" at [line:1, column:10]","errorCode":"JSON_PARSER_ERROR"}]
Is anyone can help me?
Thanks