Hi,
I am trying to moving files/attachments from Salesforce to smartsheet and facing errors when I see the debug logs. Here is my process:
- Row in smartsheet is created using a Smartsheet connector.
- Then after a delay of 3 minutes, I try to move the attachment from Salesforce to Smartsheet.
- I have seen from debug logs that I am referring to the correct sheet and rowid, but I am facing problem in attaching the file in SS.
- I get the following error in debug log:
|USER_DEBUG|[68]|DEBUG|Response Body: { "errorCode" : 1145, "message" : "Multipart upload request was invalid. Please check your request headers and payload.", "refId" : "utvlix"}
- Here is my logic in apex, what am I doing wrong in this?
public class SmartsheetUploader {
public static void uploadPdfToSmartsheet(String contentVersionId, String sheetId, String rowId, String smartsheetToken) {
// Step 1: Fetch file from ContentVersion
ContentVersion cv = [
SELECT Title, VersionData
FROM ContentVersion
WHERE Id = :contentVersionId
LIMIT 1
];
String fileName = cv.Title.endsWith('.pdf') ? cv.Title : cv.Title + '.pdf';
Blob fileBlob = cv.VersionData;
// Step 2: Define boundary and multipart structure
String boundary = '---------------------------4664151417711';
// Convert headers to Blob
String bodyStart = '--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="file"; filename="' + fileName + '"\r\n' +
'Content-Type: application/pdf\r\n\r\n';
String bodyEnd = '\r\n--' + boundary + '--';
Blob bodyStartBlob = Blob.valueOf(bodyStart);
Blob bodyEndBlob = Blob.valueOf(bodyEnd);
// Now concatenate blobs properly
Blob fullBody = concatBlobs( new List<Blob> {bodyStartBlob, fileBlob, bodyEndBlob});
System.debug('Body (Base64 Encoded): ' + EncodingUtil.base64Encode(fullBody));
// Step 3: Build HTTP request
HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.smartsheet.com/2.0/sheets/' + sheetId + '/rows/' + rowId + '/attachments');
req.setMethod('POST');
req.setHeader('Authorization', 'Bearer ' + smartsheetToken);
req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
req.setBodyAsBlob(fullBody);
// Step 4: Send request
Http http = new Http();
HttpResponse res = http.send(req);
// Step 5: Handle response
System.debug('Status: ' + res.getStatus());
System.debug('Response Body: ' + res.getBody());
if (res.getStatusCode() != 200 && res.getStatusCode() != 201) {
throw new CalloutException('Upload failed: ' + res.getBody());
}
}
// Method to concatenate blobs
public static Blob concatBlobs(List<Blob> blobs) {
String combinedBase64 = '';
for (Blob b : blobs) {
combinedBase64 += EncodingUtil.base64Encode(b);
}
return EncodingUtil.base64Decode(combinedBase64);
}
}