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.
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;
}
}
}
Very helpful
ReplyDelete