Salesforce Google drive integration | Upload files from Salesforce to Google drive

|
| By Webner

Follow the below steps for the integration of Salesforce and Google drive (to select files from local and upload to Google drive using Salesforce code):

1. Open Google Drive console. Here is the link for console:
https://console.developers.google.com/apis

2. Select a project. If you don’t have any project then create one.

3. Click on Drive API:
1

4. Click on Create Credentials:
2

5. Generate API key and Client Secret.

6. Use key and client secret in your apex class to get access token.

7. Enable Google apis.

Create a visualforce page for browsing a file from your local system and uploading it to google drive.

Sample code of the visualforce page with CSS:

<apex:page controller="GoogleDriveController">
<style>
.error {
font-style: italic;
font-size: 15px;
font-weight: bold;
text-align: center;
color: green;
}

.myClass {
color: black !important;
background: #145a32 !important;
width: 300px;
font-size: 20px !important;
height: 35px;
}
</style>
<center>
<apex:form style="margin-top:5%;margin-left:5%;width:60%">
<apex:pageblock>
<apex:commandbutton styleClass="myClass" onclick="this.value = 'Authenticating....'" action="{!DriveAuth}" value="Google Drive Authentication">
</apex:commandbutton>
<br/>
<br/>
<br/>
<br/>
<apex:inputfile value="{!file}" contentType="{!filetype}" filename="{!filename}" />
<br/>
<br/>
<br/>
<br/>
<apex:commandButton styleClass="myClass" onclick="this.value = 'Uploading...'" value="Upload file" action="{!UploadFile}" />
<br/>
<br/>
<apex:messages styleClass="error" />
<br/>
</apex:pageblock>
</apex:pageblock>
</apex:form>
</center>
</apex:page>

3
Click on Google Drive Authentication button then browse your file and finally upload that file.

Create an apex class for the above visualforce page for uploading a file to google drive.

Sample code of apex class:

public class GoogleDriveController {
private String code;

public boolean val {
    get;
    set;
    }

public blob file {
    get;
    set;
    }

public String filetype {
    get;
    set;
    }
   
public String filename {
    get;
    set;
    }
private string key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
private string secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
private string redirect_uri = 'https://xxxxxxxxxxxxxxx.force.com/apex/GoogleDrive';
private String accesstoken;
private Integer expiresIn;
private String tokentype;
public GoogleDriveController() {
code = ApexPages.currentPage().getParameters().get('code');
//Get the access token once we have code
if (code != '' & amp; & amp; code != null) {
AccessToken();
 }
}
public PageReference DriveAuth() {
//Authenticating
PageReference pg = new PageReference(GoogleDriveAuthUri(key, redirect_uri));
return pg;
}

public String GoogleDriveAuthUri(String Clientkey, String redirect_uri) {
String key = EncodingUtil.urlEncode(Clientkey, 'UTF-8');
String uri = EncodingUtil.urlEncode(redirect_uri, 'UTF-8');
String authuri = '';
authuri = 'https://accounts.google.com/o/oauth2/auth?' +
      'client_id=' + key +
      '&response_type=code' +
      '&scope=https://www.googleapis.com/auth/drive' +
      '&redirect_uri=' + uri +
      '&state=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
       +
      'access_type=offline';
       return authuri;
    }
public void UploadFile() {
String boundary = '----------9889464542212';
String delimiter = '\r\n--' + boundary + '\r\n';
String close_delim = '\r\n--' + boundary + '--';
String bodyEncoded = EncodingUtil.base64Encode(file);
String body = delimiter + 'Content-Type: application/json\r\n\r\n' + '{ "title" : "' + filename + '",' + ' "mimeType" : "' + filetype + '" }' + delimiter + 'Content-Type: ' + filetype + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + bodyEncoded + close_delim;
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart');
req.setHeader('Authorization', 'Bearer ' + accessToken);
req.setHeader('Content-Type', 'multipart/mixed; boundary="' + boundary + '"');
req.setHeader('Content-length', String.valueOf(body.length()));
req.setBody(body);
req.setMethod('POST');
req.setTimeout(60 * 1000);
HttpResponse resp = http.send(req);
file = null;
filetype = '';
filename = '';
}
public void AccessToken() {
//Getting access token from google
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('https://accounts.google.com/o/oauth2/token');
req.setHeader('content-type', 'application/x-www-form-urlencoded');
String messageBody = 'code=' + code + '&client_id=' + key + '&client_secret=' + secret + '&redirect_uri=' + redirect_uri + '&grant_type=authorization_code';
req.setHeader('Content-length', String.valueOf(messageBody.length()));
req.setBody(messageBody);
req.setTimeout(60 * 1000);
Http h = new Http();
String resp;
HttpResponse res = h.send(req);
resp = res.getBody();
JSONParser parser = JSON.createParser(resp);
while (parser.nextToken() != null) {
    if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)) {
    String fieldName = parser.getText();
    parser.nextToken();
    if (fieldName == 'access_token') {
    accesstoken = parser.getText();
    } else if (fieldName == 'expires_in') {
     expiresIn = parser.getIntegerValue();
    } else if (fieldname == 'token_type') {
     tokentype = parser.getText();
    }
 } }
 System.debug(' You can parse the response to get the access token ::: ' + resp);
    }
}

18 comments

  1. HI Thanks For such great blog…. I just want to know what we have to put in this &state=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’

    I am getting error

    1. 401. That’s an error.

      Error: invalid_client

      The OAuth client was not found.

      Request Details
      client_id=AIzaSyDZ4zc4YJJmPeOJ0KBfECU4Jt-w04Sm85M
      redirect_uri=https://pravinjoshi-dev-ed.my.salesforce.com/apex/GoogleDrive
      response_type=code
      scope=https://www.googleapis.com/auth/drive
      state=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaccess_type=offline
      That’s all we know.

      1. please use the client ID which will be generated after creating credentials(oAuth) and use the same ID and secret key in the above code. It will work. make sure redirect_uri is your vf page link and post this create a web application in credentials(OAuth), in here provide your org base URL and redirect_uri referred in the code.

  2. No matter what State we are using in above code, we are always getting invalid state error. Will you be able to guide us on this?

  3. When the authorization is complete, the third party targets the redirect url, this Code is basically a parameter that we get in the response url.

    In the given example, the DriveAuth function is executed first. This o-authentication requests for the CODE. Once oauth is complete, the code is received in the URL. And the controller of the apex class gets its value in a variable that has a getter setter.

    1. “401 error” occurs when we try to hit a URL from salesforce that is not added to our remote site settings. In general also, if we try to hit a URL that we have not access, it gives 401 error.

    1. I think you are using xxxxxx as state. Rather you should use some hashcode so that you can use it to check the connection is correct or not. I am not sure how you are comparing the state value with the one retrieved in the response URL along with Code,
      So, check the apex code to ensure the proper value of state. For this, add the below code in the constructor GoogleDriveController() before reading value for queryString “code”:

      if(apexPages.currentPage().getParameters().get(‘state’) != ‘testStringForStateComparison_DCEeFWf45A53sdjkle983ddf’)
      return null;

  4. What is maximum file size that we can upload? I tried to upload 5mb file it throwing exception String length exceeds maximum: 6000000. how to resolve this error/

Leave a Reply

Your email address will not be published. Required fields are marked *