Skip to main content

Hi,

I’m running an API Call to upload a PDF file to Box. I get the PDF URL from another API call to another software, and then input the URL into this apex class, it downloads it and uploads it into Box folder of specific folder Id which I input. For some reason, everything works, but the file that comes into Box is not PDF and is of unsupported file type (can’t be opened or downloaded). Can anyone find what my error could possibly be? 

public class HV_BoxPDFUploader {
    @InvocableMethod(label='Upload PDF to Box' description='Uploads a PDF from a URL to Box using Box Toolkit')
    public static List<Result> uploadPDFToBox(List<Request> requests) {
        List<Result> results = new List<Result>();
        
        for (Request req : requests) {
            Result res = new Result();
            try {
                // Download PDF content
                Http http = new Http();
                HttpRequest pdfRequest = new HttpRequest();
                pdfRequest.setEndpoint(req.pdfUrl);
                pdfRequest.setMethod('GET');
                HttpResponse pdfResponse = http.send(pdfRequest);
                
                if (pdfResponse.getStatusCode() == 200) {
                    Blob pdfContent = pdfResponse.getBodyAsBlob();
                    
                    String fileName = req.fileName != null ? req.fileName : 'document.pdf';
                    String parentFolderId = req.parentFolderId != null ? req.parentFolderId : '0';
                    
                    String boundary = '---------------------------' + String.valueOf(DateTime.now().getTime());
                    
                    String attributes = '{"name":"' + fileName + '", "parent":{"id":"' + parentFolderId + '"}, "content_type":"application/pdf"}';
                    
                    String body = '--' + boundary + '\r\n' +
                        'Content-Disposition: form-data; name="attributes"\r\n\r\n' +
                        attributes + '\r\n' +
                        '--' + boundary + '\r\n' +
                        'Content-Disposition: form-data; name="file"; filename="' + fileName + '"\r\n' +
                        'Content-Type: application/pdf\r\n\r\n';
                    
                    Blob completeBody = Blob.valueOf(body);
                    completeBody = Blob.valueOf(completeBody.toString() + EncodingUtil.base64Encode(pdfContent));
                    completeBody = Blob.valueOf(completeBody.toString() + '\r\n--' + boundary + '--\r\n');
                    
                    HttpRequest uploadRequest = new HttpRequest();
                    uploadRequest.setEndpoint('https://upload.box.com/api/2.0/files/content');
                    uploadRequest.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
                    uploadRequest.setBodyAsBlob(completeBody);
                    uploadRequest.setMethod('POST');
                    
                    Box.Toolkit boxToolkit = new Box.Toolkit();
                    HttpResponse uploadResponse = boxToolkit.sendRequest(uploadRequest);
                    
                    if (uploadResponse.getStatusCode() == 201) {
                        Map<String, Object> responseMap = (Map<String, Object>)JSON.deserializeUntyped(uploadResponse.getBody());
                        List<Object> entries = (List<Object>)responseMap.get('entries');
                        Map<String, Object> fileInfo = (Map<String, Object>)entries'0];
                        String fileId = (String)fileInfo.get('id');
                        
                        res.success = true;
                        res.message = 'PDF uploaded successfully to Box';
                        res.boxFileId = fileId;
                    } else {
                        res.success = false;
                        res.message = 'Failed to upload PDF to Box. Status code: ' + uploadResponse.getStatusCode();
                    }
                } else {
                    res.success = false;
                    res.message = 'Failed to download PDF from provided URL. Status code: ' + pdfResponse.getStatusCode();
                }
            } catch (Exception e) {
                res.success = false;
                res.message = 'Error: ' + e.getMessage();
            }
            results.add(res);
        }
        
        return results;
    }
    
    public class Request {
        @InvocableVariable(required=true label='PDF URL' description='The URL of the PDF to upload to Box')
        public String pdfUrl;
        
        @InvocableVariable(required=false label='File Name' description='The name to give the uploaded file (without .pdf extension)')
        public String fileName;
        
        @InvocableVariable(required=false label='Parent Folder ID' description='The ID of the parent folder in Box (default is root folder)')
        public String parentFolderId;
    }
    
    public class Result {
        @InvocableVariable(label='Success' description='Indicates if the operation was successful')
        public Boolean success;
        
        @InvocableVariable(label='Message' description='Detailed message about the operation')
        public String message;
        
        @InvocableVariable(label='Box File ID' description='ID of the uploaded file in Box')
        public String boxFileId;
    }
}

Box uses the file extension to determine what preview technology to render, so a missing “.pdf” extension may be the culprit. Here is an example of an invocable

https://github.com/kylefernandadams/box-upload-invocable-example/blob/main/force-app/main/default/classes/UploadFileFromContentDocument.cls#L86

 

You may run into Apex limits for files larger than 12mb (more like 10mb when you include the total payload size). Here is an enhancement request that you can upvote to add a new upload toolkit method and Flow action that allows you to pass in a ContentDocument.ID and would also solve for the 12mb Apex callout limit 

https://pulse.box.com/forums/909778-help-shape-the-future-of-box/suggestions/48358991-salesforce-flow-action-to-upload-by-contentdocumen


Thank you so much Kyle for taking the time to respond! I think I’ve figured out the apex class, now I have an issue accessing the PDF URL itself, it’s an error 403 so it may not be doable in flow. I will see if I can upload some other way. Thanks a lot for your help, much appreciated!


Thank you so much Kyle for taking the time to respond! I think I’ve figured out the apex class, now I have an issue accessing the PDF URL itself, it’s an error 403 so it may not be doable in flow. I will see if I can upload some other way. Thanks a lot for your help, much appreciated!

A 403 error typically means that the user running the Flow (and the corresponding Invocable) needs the appropriate access to the folder to which you’re uploading the file. If you can, I would ensure the user has been added to the folder with the appropriate permissions first, then test running the flow in Debug. 

 

Here are docs on the 403 error: https://developer.box.com/guides/api-calls/permissions-and-errors/common-errors/#403-forbidden

 


Reply