Upload/Create/Send attechments/file to Google Drive from Apex Salesforce (Using Salesforce Google Drive Integration)

First we need to integrate third party system (Google Drive) in salesforce using Auth. provider and Named Credentials.

=> Steps to Integrate Salesforce with Google Drive:


1.        Click on https://console.developers.google.com

2.        Create a New Project

3.        After creating New project click on credentials

=>     Enable API “Google Drive API”, “Google App Marketplace SDK” for newly created project.

4.        After clicking on credentials click on create credentials and select 0Auth client Id.





5.        Now select Web application.

6.        Fill the name as you desire and click on create.

7.        Once you click on create you can able to see 0Auth 2.0 Client Ids.




8.        Click on the newly created 0Auth 2.0 client Id.

9.        You can able to see client Id & client secret. (Please copy and keep it for next steps)

10.     Add one Authorized redirect URIs (https://developers.google.com/oauthplayground) and save it. 



11.      Now click https://developers.google.com/oauthplayground/

12.       Now add OAuth Client ID and OAuth Client secret in  Use your own OAuth credentials.




13.      Select the relevant google API category, and then select the scope inside that category in the UI.


















14.      Get the authorization code by clicking "authorize API" blue button. Exchange authorization code for token by clicking the blue button.

15.      Now go to step 2 and click “Exchange authorization code for tokens” blue button.

16.      Now you will get Refresh token and access token.

=> Now Configure Auth. Provider for Salesforce Google Drive Integration:    

17. In Salesforce go to Setup enter Auth. Providers in the quick find box and click New button.

18. A form will open and select Open ID Connect as Provider Type.

19. Enter name, Consumer Key and Consumer Secret. Enter endpoints URL.

20. Authorize Endpoint URL: (https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force)

21. Token Endpoint URL: https://accounts.google.com/o/oauth2/token

22. Add scopes defined in your google app e.g. (https://www.googleapis.com/auth/drive) as default scopes. Click Save.

23.   Once saved, a callback URL is available in the Salesforce Configuration Section.



24.   Add this callback URL as the Authorized Redirect URls in the Google App.

25.    Create two Remote Site Setting in Salesforce.

-> https://www.googleapis.com

-> https://console.cloud.google.com



=>   Create Named Credentials in Salesforce:-

27. In Salesforce go to Setup enter Named Credentials in the quick find box and         click New Named Credentials button.

A.    A form will open. Fill out the following fields:

I. Name

II.   URL: https://www.googleapis.com

III.  Identity Type: Named Principal

IV.   Authentication Protocol: OAuth 2.0

V.    Authentication Provider: Auth. Provider configured earlier

VI.   Scope: Enter space separated scope defined in your google app. e.g.  https://www.googleapis.com/auth/drive

VII.  Start Authentication Flow on Save: check the checkbox.

B.  Upon saving, your will redirect to the google Authorization.

C.  We need to open an unsafe connection.

D.  Allow the access.

E. Once you are authorized as a user. If you find (The authentication provider didn’t provide a refresh token. If the access token expires, your org won’t be able to access this named credential) on the name credential page, that means the refresh token logic is missing.

F. Update the Authorization endpoint URL in the auth provider configured earlier to continue getting the refresh token. Add the query parameter to the base URL. The updated URL will be https://accounts.google.com/o/oauth2/auth?     access_type=offline&approval_prompt=force. The approval_prompt parameter is required to get the refresh token after the first one continuously .

G. Test the connection once again and the user will be authenticated. (Make sure don't show any error on Named Credential)



Now Upload/Create/Send attechments/file to Google Drive from Apex Salesforce:-

Btw I used Report object. to upload attech to Drive.

Here is the code:-

public class ReportController { private string key = '36701353XXXXXXXXXXXXXXXXXXXXXXXXntent.com'; private string secret = 'GOCSPX-0VXXXXXXXXXXXXXXD46x3SNST_N9K'; private string refresh_token = '1%2F%2F04kKSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXbL7AOUeoUo_ZEU'; private string refreshToken; private String accesstoken; private Integer expiresIn; private String tokentype; public ReportController() { AccessToken(); } public void generateReport(string reportDevName) { try { List<Report> reportList = [SELECT Id, DeveloperName, Name FROM Report where DeveloperName =: reportDevName]; if (reportList.size() > 0) { String reportId = (String) reportList.get(0).get('Id'); string reportName = (String) reportList.get(0).get('Name'); string url = '/' + reportId + '?csv=1&isdtp=p1'; System.debug('url-->' + url); ApexPages.PageReference objPage = new ApexPages.PageReference(url); blob urlStor = objPage.getContent(); System.debug('urlStor--->' + urlStor); String boundary = 'SalesforceNewsTechnologyStuff9889464542212'; String delimiter = '\r\n--' + boundary + '\r\n'; String close_delim = '\r\n--' + boundary + '--'; String bodyEncoded = EncodingUtil.base64Encode(urlStor); System.debug('bodyEncoded--->' + bodyEncoded); String FolderId = '1zS5uMK6hKOi2SW19xwqUmaxFDGyXw9Mf'; String driveId = '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x'; String body = delimiter + 'Content-Type: application/json\r\n\r\n' + '{ "name" : "' + reportName + '.csv' + '",' + ' "mimeType" : "text/csv",' + '"teamDriveId": "' + driveId + '",\n "driveId": "' + driveId + '",\n "parents":[\n "' + folderId + '"\n ]}' + delimiter + 'Content-Type: text/application/vnd.ms-excel' + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + bodyEncoded + close_delim; String endpoint = 'https://www.googleapis.com/upload/drive/v3/files?driveId=' + driveId + '&includeItemsFromAllDrives=true&corpora=drive&supportsAllDrives=true&uploadType=multipart'; system.debug('endpoint==>' + endpoint); System.debug('body--->' + body); System.debug('body--->' + JSON.serializePretty(body)); System.debug('accesstoken466==>' + accesstoken); Http http = new Http(); HttpRequest req = new HttpRequest(); req.setEndpoint(endpoint); 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); system.debug('reqreqreqreqreq' + req); String resp2 = resp.getBody(); System.debug('resp2==>' + resp2); } } catch (Exception ex) { system.debug(ex.getMessage()); } } 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 = 'client_secret=' + secret + '&grant_type=refresh_token' + '&refresh_token=' + refresh_token + '&client_id=' + key; System.debug('messageBody===>' + messageBody); req.setHeader('Content-length', String.valueOf(messageBody.length())); req.setBody(messageBody); req.setTimeout(60 * 1000); Http h = new Http(); HttpResponse res = h.send(req); String resp = res.getBody(); System.debug('resp=====>' + resp); 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('accesstoken162==>' + accesstoken); System.debug(' You can parse the response to get the access token ::: ' + resp); } public String createFolder() { //Local variable declarations //folder search String folderId; string folderName = 'SalesforceDataBackup_' + system.now().format('MM.dd.yyyy'); folderName = 'name=\'' + folderName + '\''; folderName = EncodingUtil.urlencode(folderName, 'UTF-8'); string searchFolderEndpoint = 'https://www.googleapis.com/drive/v3/files?driveId=' + '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x' + '&includeItemsFromAllDrives=true&corpora=drive&supportsAllDrives=true&q=' + folderName; Http https1 = new Http(); HttpRequest requ1 = new HttpRequest(); HttpResponse respo1 = new HttpResponse(); //method execution requ1.setMethod('GET'); requ1.setEndpoint(searchFolderEndpoint); requ1.setHeader('Authorization', 'Bearer ' + accesstoken); respo1 = https1.send(requ1); system.debug('status' + respo1.getStatusCode()); system.debug('response body--- ' + respo1.getBody()); if (String.isEmpty(folderId)) { //folder create String Endpoint = 'https://www.googleapis.com/upload/drive/v3/files?driveId=' + '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x' + '&includeItemsFromAllDrives=true&corpora=drive&supportsAllDrives=true&uploadType=multipart'; datetime d1 = system.now(); string body = '--287032381131322\nContent-Type: application/json\n\n{\n "name": "SalesforceDataBackup_' + system.now().format('MM.dd.yyyy') + '",\n "mimeType": "application/vnd.google-apps.folder",\n "description": "Stuff about the file",\n "teamDriveId": "' + '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x' + '",\n "driveId": "' + '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x' + '",\n "parents":[\n "' + '1DVRPlthRkYBeGAGGPt-TW_tVrEpa_A9x' + '"\n ]\n}\n--287032381131322\nContent-Type: application/vnd.google-apps.folder\n\n\'testing body\'\n--287032381131322--'; Http https = new Http(); HttpRequest requ = new HttpRequest(); HttpResponse respo = new HttpResponse(); //method execution requ.setMethod('POST'); requ.setEndpoint(Endpoint); requ.setHeader('content-type', 'multipart/form-data; boundary=287032381131322'); //system.debug('access token----in drive search---->'+Access_Token); requ.setHeader('Authorization', 'Bearer ' + accesstoken); requ.setBody(body); respo = https.send(requ); system.debug('createFolder HttpResponse====>' + respo); GoogleResponses.GoogleFolder obj = (GoogleResponses.GoogleFolder) JSON.deserialize(respo.getbody(), GoogleResponses.GoogleFolder.class); folderId = obj.id; System.debug('folderId===>' + folderId); return folderId; } else { return folderId; } } }

Comments

Post a Comment

Popular posts from this blog

🛠️ Custom Field Change Tracking in Salesforce – Overcoming Limitations of Field History Tracking

OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration