• vamsi@sfmobile
  • NEWBIE
  • 0 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 1
    Replies

We are developing a mobile app using salesforce mobile sdk for android(and ios too) and phonegap. This requires downloading Salesforce Content(Content can be a file of any type/extension) directly and saving it into mobile device.

We tried below url which exposes the content of the Salesforce Content document.

https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData.

Since the above url doesnt allow direct download of file, we are parsing the content and writing it into a file to save in mobile device.

 

//This function is invoked when download link is clicked and dwnldDocParams contains saleforce content record id and filename

function downloadFileToDevice(dwnldDocParams){                                

                var dwnldDocId = dwnldDocParams.substring(0,18);

                var fileNameWithExt = dwnldDocParams.substring(18);

                forcetkClient.getContentData(dwnldDocId, onSuccessContentData, onErrorSfContentData);

}

 

forcetk.Client.prototype.getContentData = function(recordId, callback, error) {

        var query = '/' + this.apiVersion + '/sobjects/ContentVersion/'+recordId+'/VersionData'

        this.ajaxForContent(query, callback, error);

}

               

forcetk.Client.prototype.ajaxForContent = function(path, callback, error, method, payload, retry) {

        var that = this;

        var url = this.instanceUrl + '/services/data' + path;

                                //This is the sample url

                                //https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData

                               

        $j.ajax({

            type: method || "GET",

            async: this.asyncAjax,

            url: (this.proxyUrl !== null) ? this.proxyUrl: url,

                                               

                                                contentType: 'application/octetstream', //since the response sent by salesforce has Content-type : application/octetstream for content of any type(text,image,docx..)

           

                                                cache: false,

            processData: false,

            data: payload,

            success: callback,

            error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) {

                if (jqXHR.status === 401) {

                    that.refreshAccessToken(function(oauthResponse) {

                        that.setSessionToken(oauthResponse.access_token, null,

                        oauthResponse.instance_url);

                                                                                                that.ajaxForContent(path, callback, error, method, payload, true);

                    },

                    error);

                } else {

                    error(jqXHR, textStatus, errorThrown);

                }

            },

 

                                                dataType: "text", //valid datatypes are text,json,xml,html,jsonp

                                               

            beforeSend: function(xhr) {

                if (that.proxyUrl !== null) {

                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);

                }

                xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId);

                xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);

                                               

                if (that.userAgentString !== null) {

                    xhr.setRequestHeader('User-Agent',that.userAgentString);

                }

            }

        });

    }         

               

//Success callback function         

function onSuccessContentData(response) {

    var $j = jQuery.noConflict();

                //Phonegap method

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,

                               function (fileSystem) {

                //fileSystem.root.getFile("readme.txt", {create: true, exclusive: false}, //here file name is hardcoded just for static verification for writing into files of different types

                fileSystem.root.getFile("testimage.png", {create: true, exclusive: false},

                //fileSystem.root.getFile("sampleDoc.docx", {create: true, exclusive: false},

                function (fileEntry) {

                                        fileEntry.createWriter(

                                        function gotFileWriter(writer) {

                                                                                writer.onwrite = function(evt) {

                                                                                console.log("write success");

                                                                                };

                                                                                writer.write(response);

                                                    }, fail);

                                    }, fail);

                }, fail);

}

 

The above code works only for text files. For text files response is text only.For other files, we could observe Though we could get response for files of other types also and write into file in device, they could not be viewed. May be the response sent as octetstream need to processed in some way before writing into file. Dont know if there is any issue writing binary data into file using above phonegap function. Any pointers to successfully write content into file (of any type) is  really helpful.

 

Sample response obtained for an image(png) file:

 

07-18 15:11:10.822: D/CordovaLog(1421): >onSuccessContentData&colon;response--"?PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000 \u0000\u0000\u0000?\b\u0002\u0000\u0000\u0000\u0005?v?\u0000\u0000\u0000\u0019tEXtSoftware\u0000Adobe ImageReadyq?e<\u0000\u0000\u0000?IDATx???1\u0012?0\u0010\u0005Pp????\n?86\u0014R?\u0006?`?\u0001,?\u0005\u0016_.??o\"Yp?????.?\u0012\nt\u0000?z??D;?(?\u001e?/?M>?K\u0013??n???\t6???\t\u0016?\u0013?\u0003?\u0004{'???g??'pL?\"??\u001e?;?RJl?5?c,0MS??1??\u0001\u0000\u0000\u0000\u0000r\\??s?a\u0018r??\u000f\u0000\u0000\u0000\u0000\u0000 Kgw???E\u0000\u0000\u0000\u0000\u0000\u0000\u0000[4^??\"S?\u0007\u0000?E?A?$P\"\tN?,??\u0018?>@\u0002C?J$???#??\u0004??\u0004???3?4c????\u0001\u0000\u0000\u0000\u0000?\u0004\b\u001f?v?\u0003\u0000\u0000\u0000\u0000\u0000\u0000|?\u0007?B?\u0019?|??\u0000\u0000\u0000\u0000IEND?B`?"

 

 

It would be really great if there is any way to download the file directly from salesforce instead of reading response and writing manually into a file in device.

I could find another url which DIRECTLY DOWNLOADS THE FILE if we are currently in salesforce session. I tried this url in place of url in above scenario but no progress..

https://<instance>content.force.com/sfc/servlet.shepherd/version/download/<ContentVerion record Id>

Eg: https://c.ap1.content.force.com/sfc/servlet.shepherd/version/download/06890000000CZjT.

 

 

Hi i was trying to download the attachment for content document which is text file.. I used the url https://c.ap1.content.force.com/sfc/servlet.shepherd/version/download/06890000000CZjT

and while downloading, the below content is present in downloaded text file instead of its actual content. I think this occurs if i m not authorized to access the content. But i specified http headers for authorization and Content-disposition. But i could not download the actual file. Any pointers or any other way to download the salesforce content document is really helpful

 

Thanks,

Vamsi.

 

<script>
if (window.location.replace){
window.location.replace('https://login.salesforce.com/?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fc.ap1.content.force.com%252Fsfc%252Fservlet.shepherd%252Fversion%252Fdownload%252F06890000000CZjT');
} else {;
window.location.href ='https://login.salesforce.com/?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fc.ap1.content.force.com%252Fsfc%252Fservlet.shepherd%252Fversion%252Fdownload%252F06890000000CZjT';
}
</script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">






</head>


</html>



<!--
...................................................................................................
...................................................................................................
...................................................................................................
...................................................................................................
-->

 

MY CODE:

 

function downloadFile(){
console.log("> downloadFile--");        
        window.requestFileSystem(
                     LocalFileSystem.PERSISTENT, 0,
                     function onFileSystemSuccess(fileSystem) {
                     fileSystem.root.getFile(
                                 "dummy.html", {create: true, exclusive: false},
                                 function gotFileEntry(fileEntry){
                            
                                 var sPath = fileEntry.fullPath.replace("dummy.html","");
                                 var fileTransfer = new FileTransfer();
                                 fileEntry.remove();
 
                                 fileTransfer.download(
                                           //"http://www.w3.org/2011/web-apps-ws/papers/Nitobi.pdf",
                                           "https://c.ap1.content.force.com/sfc/servlet.shepherd/version/download/06890000000CZjT",
                                            
                                           
                                           sPath + "DNotesOAuth.txt",
                                           
                                           function(theFile) {
                                           console.log("download complete: " + theFile.toURI());
                                           showLink(theFile.toURI());

                                           },
                                           
                                           /*
                                           function(error) {
                                           console.log("download error source " + error.source);
                                           console.log("download error target " + error.target);
                                           console.log("upload error code: " + error.code);
                                           }
                                           */
                                           
    function(error) {
        console.log("download error source " + error.source);
        console.log("download error target " + error.target);
        console.log("upload error code" + error.code);
    },
    false,
    {
        headers: {
            //"ACCEPT": "text/plain"
            //"Content-Type": "application/octetstream"
            "Authorization" : "OAuth 00D90000000n5Zf!AQoAQC05DDFvKVRz1fuaQ_DmjSxePcWD2zm9JICR3xBKO9H25GqGJbrya9.MFbsG8KvVRYb9Y9j85nigb23A7YsZVbePeXoi",
            
            //"Accept": "application/octetstream"
            "Content-disposition": "attachment"

        }
    }

We are developing a mobile app using salesforce mobile sdk for android(and ios too) and phonegap. This requires downloading Salesforce Content(Content can be a file of any type/extension) directly and saving it into mobile device.

We tried below url which exposes the content of the Salesforce Content document.

https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData.

Since the above url doesnt allow direct download of file, we are parsing the content and writing it into a file to save in mobile device.

 

//This function is invoked when download link is clicked and dwnldDocParams contains saleforce content record id and filename

function downloadFileToDevice(dwnldDocParams){                                

                var dwnldDocId = dwnldDocParams.substring(0,18);

                var fileNameWithExt = dwnldDocParams.substring(18);

                forcetkClient.getContentData(dwnldDocId, onSuccessContentData, onErrorSfContentData);

}

 

forcetk.Client.prototype.getContentData = function(recordId, callback, error) {

        var query = '/' + this.apiVersion + '/sobjects/ContentVersion/'+recordId+'/VersionData'

        this.ajaxForContent(query, callback, error);

}

               

forcetk.Client.prototype.ajaxForContent = function(path, callback, error, method, payload, retry) {

        var that = this;

        var url = this.instanceUrl + '/services/data' + path;

                                //This is the sample url

                                //https://salesforce.com/services/data/v23.0/sobjects/ContentVersion/06890000000wo1zAAA/VersionData

                               

        $j.ajax({

            type: method || "GET",

            async: this.asyncAjax,

            url: (this.proxyUrl !== null) ? this.proxyUrl: url,

                                               

                                                contentType: 'application/octetstream', //since the response sent by salesforce has Content-type : application/octetstream for content of any type(text,image,docx..)

           

                                                cache: false,

            processData&colon; false,

            data&colon; payload,

            success: callback,

            error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) {

                if (jqXHR.status === 401) {

                    that.refreshAccessToken(function(oauthResponse) {

                        that.setSessionToken(oauthResponse.access_token, null,

                        oauthResponse.instance_url);

                                                                                                that.ajaxForContent(path, callback, error, method, payload, true);

                    },

                    error);

                } else {

                    error(jqXHR, textStatus, errorThrown);

                }

            },

 

                                                dataType: "text", //valid datatypes are text,json,xml,html,jsonp

                                               

            beforeSend: function(xhr) {

                if (that.proxyUrl !== null) {

                    xhr.setRequestHeader('SalesforceProxy-Endpoint', url);

                }

                xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId);

                xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);

                                               

                if (that.userAgentString !== null) {

                    xhr.setRequestHeader('User-Agent',that.userAgentString);

                }

            }

        });

    }         

               

//Success callback function         

function onSuccessContentData(response) {

    var $j = jQuery.noConflict();

                //Phonegap method

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,

                               function (fileSystem) {

                //fileSystem.root.getFile("readme.txt", {create: true, exclusive: false}, //here file name is hardcoded just for static verification for writing into files of different types

                fileSystem.root.getFile("testimage.png", {create: true, exclusive: false},

                //fileSystem.root.getFile("sampleDoc.docx", {create: true, exclusive: false},

                function (fileEntry) {

                                        fileEntry.createWriter(

                                        function gotFileWriter(writer) {

                                                                                writer.onwrite = function(evt) {

                                                                                console.log("write success");

                                                                                };

                                                                                writer.write(response);

                                                    }, fail);

                                    }, fail);

                }, fail);

}

 

The above code works only for text files. For text files response is text only.For other files, we could observe Though we could get response for files of other types also and write into file in device, they could not be viewed. May be the response sent as octetstream need to processed in some way before writing into file. Dont know if there is any issue writing binary data into file using above phonegap function. Any pointers to successfully write content into file (of any type) is  really helpful.

 

Sample response obtained for an image(png) file:

 

07-18 15:11:10.822: D/CordovaLog(1421): >onSuccessContentData&colon;response--"?PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000 \u0000\u0000\u0000?\b\u0002\u0000\u0000\u0000\u0005?v?\u0000\u0000\u0000\u0019tEXtSoftware\u0000Adobe ImageReadyq?e<\u0000\u0000\u0000?IDATx???1\u0012?0\u0010\u0005Pp????\n?86\u0014R?\u0006?`?\u0001,?\u0005\u0016_.??o\"Yp?????.?\u0012\nt\u0000?z??D;?(?\u001e?/?M>?K\u0013??n???\t6???\t\u0016?\u0013?\u0003?\u0004{'???g??'pL?\"??\u001e?;?RJl?5?c,0MS??1??\u0001\u0000\u0000\u0000\u0000r\\??s?a\u0018r??\u000f\u0000\u0000\u0000\u0000\u0000 Kgw???E\u0000\u0000\u0000\u0000\u0000\u0000\u0000[4^??\"S?\u0007\u0000?E?A?$P\"\tN?,??\u0018?>@\u0002C?J$???#??\u0004??\u0004???3?4c????\u0001\u0000\u0000\u0000\u0000?\u0004\b\u001f?v?\u0003\u0000\u0000\u0000\u0000\u0000\u0000|?\u0007?B?\u0019?|??\u0000\u0000\u0000\u0000IEND?B`?"

 

 

It would be really great if there is any way to download the file directly from salesforce instead of reading response and writing manually into a file in device.

I could find another url which DIRECTLY DOWNLOADS THE FILE if we are currently in salesforce session. I tried this url in place of url in above scenario but no progress..

https://<instance>content.force.com/sfc/servlet.shepherd/version/download/<ContentVerion record Id>

Eg: https://c.ap1.content.force.com/sfc/servlet.shepherd/version/download/06890000000CZjT.

 

Hi,

 

A client is hosting documents (about 50) as Content Documents on Salesforce that need to be accessible for download from a Visualforce page.

 

Right now, the VF page is creating a link of the format:

    https://<SERVER>.salesforce.com/sfc/servlet.shepherd/version/download/<CONTENT VERSION ID>

 

This link returns a page that causes the file to download automatically (via "Content-disposition: attachment" in the HTTP header).  This solution, while preferable in most situations, is not possible for mine.  Our documents are PDFs and they need to open in the browser (reasons are complicated -- just trust me, there is no negotiating this point).

 

So what I need to know, is there any way to dynamically get a link to the actual file of a Content Version, rather than this Content delivery servlet link?

 

Thanks!