function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ManiishManiish 

Google drive API integration. User not authorized.

Hi Everyone,
I am trying to integrate my Google drive with salesforce. I referred all the steps mentioned in FilesConnect document.
Same steps are shown in this link too.
https://www.youtube.com/watch?v=pSN7H8CPp-Y
As an admin, i am able to access the drive.
But other users, whom i have assigned the permission set to access Google drive are facing the issue as "You are not authorized to perform that operation." Below is the screeshot of the problem.
Error screen.
Needs your advice.

Thanks,
Manish KP
Azhar Jamil 5Azhar Jamil 5
Hi Maniish,

You need to first authenticate the credentials from the link https://console.developers.google.com/project
Follow the link for the step to create the project and credentials -- credentials https://help.salesforce.com/articleView?id=000239696&type=1

The second Step you need to create one visual force page, I have added the VF page 
<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: #87ceeb !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:form>
    </center>
</apex:page>

The third step is you need to create the apex-class and assign the client id and client secret which you will get from google API credentials,
I have attached the apex-class also after following this step you will be authenticated and your file will be uploaded from salesforce to google drive.
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 = 'Client_id';
    private string secret = 'Client_secret';
    private string redirect_uri = 'https://teqtrailhead-dev-ed--c.ap5.visual.force.com/apex/GoogleDrivePage';
    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 != '' && code != null) {
            System.debug(' code__ ' + code);
            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/v2/auth?'+
        'scope=https://www.googleapis.com/auth/drive&'+
        'state=security_token%3D138r5719ru3e1%26url%3Dhttps://oa2cb.example.com/myHome&'+
        'redirect_uri=' +uri+ 
        '&response_type=code&'+
        'client_id='+key+
        '&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()));
        system.debug('body.length()'+body.length());
        system.debug('body>>'+body);
        req.setBody(body);
        req.setMethod('POST');
        req.setTimeout(60 * 1000);
        HttpResponse resp = http.send(req);
        system.debug('resp'+resp);
        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);
        system.debug('resp>>>'+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);
    }
}

Feel free to ask if you need further clarification.

Mark, it as best answers if you like it.

Thanks! 
Manju Alabal 7Manju Alabal 7
Hi Azhar,
I have tried above code and I'm getting 'Unauthorized' 401 error. can you pls tell me if any permission I need give to perform file ipload.
In above code inside method 'GoogleDriveAuthUri' what should be the value of state parameter?

Thanks
Manujnath