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:
4. Click on Create Credentials:
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>
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); } }
Share test class for your controller.
HI Thanks For such great blog…. I just want to know what we have to put in this &state=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’
I am getting error
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.
state is just an xsrf token to prevent request forgery. Read more here: https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken
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.
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?
you can use anything dynamic for example ‘math.random()’ function which will always give dynamic values
hi how to get “code”?
it will fetch automatically. just copy paste the above code.
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.
I am getting 401 error while connecting with google drive. Please help on this,
please make sure you created remote site settings with base URL’s.. for this integration to work it requires 2 remote site settings.. (https://www.googleapis.com) and (https://accounts.google.com) and do please generate client id and client secret and you will get these 2 when you create credentials for oAuth client ID.
“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.
which valie we should give to state please ? struggling with it
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;
hey it shows me no oauth state valid
The code does not work. It is not redirecting to Google drive while authenticating
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/