Link Search Menu Expand Document

Make Searchable PDF From Uploaded File Async - Salesforce

PDF Make Text Searchable or Unsearchable sample in Salesforce demonstrating ‘Make Searchable PDF From Uploaded File Async’

MakeSearchablePDFWithFileUpload.cls
public class MakeSearchablePDFWithFileUpload {
    public static String API_KEY = '**************************';
    public static string DestinationFile = 'Searchable PDF(Using File Upload)';    
    String[] fileName = new String[] {'sampleScannedPDF'};
    List<String> urlList = new List<String>();
    
    public void startProcessing()
    {
        try
        {
            for(String fname : fileName)
            {
                ContentVersion cv = [select Title, VersionData from ContentVersion where Title = :fname limit 1];
                Blob SourceFile  = cv.VersionData;
                //1. Prepare URL for "Get Presigned URL" API call
                string url = 'https://api.pdf.co/v1/file/upload/get-presigned-url?contenttype=application/octet-stream&name=:fname'; 
                HttpRequest req = new HttpRequest();
                req.setHeader('x-api-key', API_KEY);
                req.setEndpoint(url);
                req.setMethod('GET');
                req.setTimeout(60000);
                Http http = new Http();
                HTTPResponse res = http.send(req);
                if(res.getStatusCode() == 200) 
                {
                    System.Debug('res ' + res);
                    Map<String, Object> deserializedBody =  (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
                    Boolean isError = Boolean.ValueOf(deserializedBody.get('error'));
                    if(isError == false)
                    {
                        // Get URL to use for the file upload
                        String uploadUrl = String.ValueOf(deserializedBody.get('presignedUrl'));
                        // Get URL of uploaded file to use with later API calls
                        String uploadedFileUrl = String.ValueOf(deserializedBody.get('url'));
                        SYstem.debug('uploadedFileUrl :: '+uploadedFileUrl);
                        // 2. UPLOAD THE FILE TO CLOUD.
                        if(uploadFile(API_KEY, uploadUrl, SourceFile))
                        {                            
                            urlList.add(uploadedFileUrl);  
                            System.debug('urlList ' + urlList);                           
                        }
                    }
                }
                else
                {
                    System.debug('Error Response ' + res.getBody());
                    System.Debug(' Status ' + res.getStatus());
                    System.Debug(' Status Code' + res.getStatusCode());
                    System.Debug(' Response String' + res.toString());
                } 
            }
            if (urlList.size() > 0)
            {                
                makePdfTextSearchable(urlList);
            }
        }
        catch(Exception ex)
        {
            String errorBody = 'Message: ' + ex.getMessage() + ' -- Cause: ' + ex.getCause() + ' -- Stacktrace: ' + ex.getStackTraceString();
            System.Debug(errorBody);
        }
    }   
    
    @TestVisible
    public static boolean uploadFile(String API_KEY, String url, Blob sourceFile)
    {
        HttpRequest req = new HttpRequest();
        req.setHeader('x-api-key', API_KEY);
        req.setHeader('Content-Type', 'application/octet-stream');
        req.setEndpoint(url);
        req.setMethod('PUT');
        req.setTimeout(60000);
        req.setBodyAsBlob(sourceFile);
        Http http = new Http();
        HTTPResponse res = http.send(req);
        if(res.getStatusCode() == 200) 
        {
            System.Debug(res.getBody());
            return true;
        }
        else
        {
            System.debug('Error Response ' + res.getBody());
            System.Debug(' Status ' + res.getStatus());
            System.Debug(' Status Code' + res.getStatusCode());
            System.Debug(' Response String' + res.toString());
            return false;
        }
    }
    
    public static void makePdfTextSearchable(List<String> uploadedFileUrl)
    {
        System.debug('uploadedFileUrlList[0] :: '+uploadedFileUrl[0]);
        string SourceFileUrl = uploadedFileUrl[0]; 
        Map<string, Object> parameters = new Map<string, Object>();
        parameters.put('async', 'true');
        parameters.put('password', '');
        parameters.put('name', 'result.pdf');
        parameters.put('pages', '');        
        parameters.put('lang', 'eng');
        parameters.put('url', SourceFileUrl);
        string jsonPayload = Json.serialize(parameters); 
        try
        {    
            string url = 'https://api.pdf.co/v1/pdf/makesearchable';
            HttpRequest req = new HttpRequest();
            req.setBody(jsonPayload);
            req.setHeader('x-api-key', API_KEY);
            req.setHeader('Content-Type', 'application/json');
            req.setEndpoint(url);
            req.setMethod('POST');
            req.setTimeout(60000);
            Http http = new Http();
            HTTPResponse res = http.send(req);
            if(res.getStatusCode() == 200) 
            {
                System.Debug('res.getBody()' + res.getBody());
                Map<String, Object> deserializedBody =  (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
                String urlVal = (String)deserializedBody.get('url');
                String jobId = (String)deserializedBody.get('jobId');
                SYstem.debug('urlVal >>> '+urlVal);
                do
                {
                    String statusVal = checkJobStatus(jobId);
                    if(statusVal == 'success')
                    {
                        downloadFile(urlVal, DestinationFile);   
                        break;
                    } 
                    else if(statusVal == 'working')
                    {
                        sleep(3000);
                    }
                    else
                    {
                        break;
                    }                        
                }while(true);
            }
            else
            {
                System.debug('Success Response ' + res.getBody());
                System.Debug(' Status ' + res.getStatus());
                System.Debug(' Status Code' + res.getStatusCode());
                System.Debug(' Status String' + res.toString());
            }
        }
        catch(Exception ex)
        {
            String errorBody = 'Message: ' + ex.getMessage() + ' -- Cause: ' + ex.getCause() + ' -- Stacktrace: ' + ex.getStackTraceString();
            System.Debug(errorBody);
        }        
    }    
    
    
    public static String checkJobStatus(String jobId)
    {
        String statusVal;
        try
        {            
            string url = 'https://api.pdf.co/v1/job/check?jobid=' + jobId;
            HttpRequest req = new HttpRequest();
            req.setHeader('x-api-key', API_KEY);
            req.setHeader('Content-Type', 'application/json');
            req.setEndpoint(url);
            req.setMethod('POST');
            req.setTimeout(60000);
            Http http = new Http();
            HTTPResponse res = http.send(req);
            if(res.getStatusCode() == 200) 
            {
                System.Debug('res ' + res.getBody());
                Map<String, Object> deserializedBody =  (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
                statusVal = (String)deserializedBody.get('status');                
            }
            else
            {
                System.debug('Success Response ' + res.getBody());
                System.Debug(' Status ' + res.getStatus());
                System.Debug(' Status Code' + res.getStatusCode());
                System.Debug(' Status String' + res.toString());
            }            
        }
        catch(Exception ex)
        {
            String errorBody = 'Message: ' + ex.getMessage() + ' -- Cause: ' + ex.getCause() + ' -- Stacktrace: ' + ex.getStackTraceString();
            System.Debug(errorBody);
        }
        return statusVal;
    }
    
    @TestVisible
    private static void downloadFile(String extFileUrl, String DestinationFile)
    {
        Http h = new Http(); 
        HttpRequest req = new HttpRequest(); 
        extFileUrl = extFileUrl.replace(' ', '%20'); 
        req.setEndpoint(extFileUrl); 
        req.setMethod('GET'); 
        req.setHeader('Content-Type', 'application/pdf');
        req.setCompressed(true); 
        req.setTimeout(60000); 
        //Now Send HTTP Request
        HttpResponse res  = h.send(req); 
        if(res.getStatusCode() == 200) 
        {
            blob fileContent = res.getBodyAsBlob();
            ContentVersion conVer = new ContentVersion();
            conVer.ContentLocation = 'S'; // to use S specify this document is in Salesforce, to use E for external files
            conVer.PathOnClient = DestinationFile + '.pdf'; // The files name, extension is very important here which will help the file in preview.
            conVer.Title = DestinationFile; // Display name of the files
            conVer.VersionData = fileContent;
            insert conVer;
            System.Debug('Success');
        }
        else
        {
            System.debug('Error Response ' + res.getBody());
            System.Debug(' Status ' + res.getStatus());
            System.Debug(' Status Code' + res.getStatusCode());
            System.Debug(' Response String' + res.toString());
        }
    }
    
    public static void sleep(integer milliseconds) 
    {
        Long timeDiff = 0;
        DateTime firstTime = System.now();
        do {
            timeDiff = System.now().getTime() - firstTime.getTime();
        }
        while(timeDiff <= milliseconds);      
    }
}
MakeSearchablePDFWithFileUploadTest.cls
@isTest
private class MakeSearchablePDFWithFileUploadTest {

    @isTest static void testStartProcessing()
    {
        ContentVersion con = new ContentVersion();
        con.Title = 'sampleScannedPDF';
        con.VersionData=Blob.valueOf('Test Document');
        con.PathOnClient = 'sampleScannedPDF.pdf';
        insert con;
        
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MakeSearchablePDFCallOutMock());
        MakeSearchablePDFWithFileUpload searchablePDF = new MakeSearchablePDFWithFileUpload();
        MakeSearchablePDFWithFileUpload.API_KEY = 'testapikey';
        searchablePDF.startProcessing();
        Test.stopTest();
        List<ContentVersion> cv = [select Id,Title from ContentVersion];
        System.assertEquals('sampleScannedPDF', cv[0].Title);
    }
    
    @isTest static void testStartProcessingForCatch()
    {
        ContentVersion con = new ContentVersion();
        con.Title = 'sampleScannedPDF';
        con.VersionData=Blob.valueOf('Test Document');
        con.PathOnClient = 'sampleScannedPDF.pdf';
        insert con;
        
        Test.startTest();
        MakeSearchablePDFWithFileUpload searchablePDF = new MakeSearchablePDFWithFileUpload();
        MakeSearchablePDFWithFileUpload.API_KEY = 'testapikey';
        searchablePDF.startProcessing();
        Test.stopTest();
        List<ContentVersion> cv = [select Id,Title from ContentVersion];
        System.assertEquals('sampleScannedPDF', cv[0].Title);
    }
    
    @isTest static void testmakePdfTextSearchableJobSuccess()
    {
        List<String> urlList = new List<String>();
        urlList.add('test');
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MakeSearchablePDFCallOutMockForCheckStatusSuccess());
        MakeSearchablePDFWithFileUpload.makePdfTextSearchable(urlList);
        Test.stopTest();
        
    }
    
    @isTest static void testmakePdfTextSearchableJobSuccessForCatch()
    {
        List<String> urlList = new List<String>();
        urlList.add('test');
        Test.startTest();
        MakeSearchablePDFWithFileUpload.makePdfTextSearchable(urlList);
        Test.stopTest();
    }
    
    @isTest static void testSleep()
    {
        Test.startTest();
        MakeSearchablePDFWithFileUpload.sleep(3000);
        Test.stopTest();
    }
    
    public class MakeSearchablePDFCallOutMock implements HttpCalloutMock {
        
        public HTTPResponse respond(HTTPRequest request) {
            // Create a fake response
            HttpResponse response = new HttpResponse();
            response.setHeader('Content-Type', 'application/json');
            response.setBody('{"presignedUrl":"https://pdf-temp-files.s3-us-west-2.amazonaws.com/0c72bf56341142ba83c8f98b47f14d62/test.pdf?X-Amz-Expires=900&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIZJDPLX6D7EHVCKA/20200302/us-west-2/s3/aws4_request&X-Amz-Date=20200302T143951Z&X-Amz-SignedHeaders=host&X-Amz-Signature=8650913644b6425ba8d52b78634698e5fc8970157d971a96f0279a64f4ba87fc","url": "https://pdf-temp-files.s3.amazonaws.com/a0d52f35504e47148d1771fce875db7b/test.pdf", "pageCount": 1, "error": false, "Status": 200, "name": "test.pdf", "remainingCredits": 99033681, "credits": 35 } ');
            response.setStatusCode(200);
            return response; 
        }
    }
    
    public class MakeSearchablePDFCallOutMockForCheckStatusSuccess implements HttpCalloutMock {
        
        public HTTPResponse respond(HTTPRequest request) {
            // Create a fake response
            HttpResponse response = new HttpResponse();
            response.setHeader('Content-Type', 'application/json');
            response.setBody('{ "status": "success", "remainingCredits": 60227,"url": "https://pdf-temp-files.s3.amazonaws.com/a0d52f35504e47148d1771fce875db7b/result.pdf" } ');
            response.setStatusCode(200);
            return response; 
        }
    }
}

PDF.co Web API: the Web API with a set of tools for documents manipulation, data conversion, data extraction, splitting and merging of documents. Includes image recognition, built-in OCR, barcode generation and barcode decoders to decode bar codes from scans, pictures and pdf.

Get your PDF.co API key here!

Download Source Code (.zip)

return to the previous page explore PDF Make Text Searchable or Unsearchable endpoint