How to upload a document to Chatter from Google Drive


Dec 03, 2020    Janaki Mahapatra, Salesforce

Last week I had a requirement to create a chatter post with an attachment from google drive to a salesforce object. You are more than welcome to post a better solution. Thank You for your time. Let Say we have a test account

Account ac = new Account();
ac.Name = 'Test Account';
insert ac;
 

We have to create a chatter post and attach a file from google drive to that account record. So this is how I created my class

public with sharing class GdriveSync {

    private final String  client_secret='';
    private final String  refresh_token='';
    private final String  client_id='';
    private final String  root_folder='';

    public GdriveSync(){
        this.driveLogin();
    }

    public void processFiles(String objectId){        
        /*
         Search Drive for files within last 24 hours
        */
        List listFiles = this.searchDrive();

        for(JsonObj file:listFiles)
        {       
            //Get the Content from drive
            Blob blobData = this.getDriveFileContent(file.id);
         
            contentVersion cv = new contentversion();
            cv.versionData = blobData;
            cv.title = file.name;
            cv.pathOnClient = file.name;
            cv.Description = objectId; // May be Accounts, Opportuiny or Custom Object Id
            insert cv;
          
            FeedItem post = new FeedItem();
            post.Body = 'New File added';
            post.ParentId = inv.Id;
            post.Title = 'Important Information';
            insert post;

            FeedAttachment feedAttachment = new FeedAttachment();
            feedAttachment.FeedEntityId = post.Id;
            feedAttachment.RecordId = cv.id;
            feedAttachment.Type = 'CONTENT';
            insert feedAttachment;         
        }
    }

    private Blob getDriveFileContent(String fileId){

        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://www.googleapis.com/drive/v3/files/'+fileId+'?alt=media');
        req.setMethod('GET');

        req.setHeader('Authorization', 'Bearer '+this.access_token);
        req.setHeader('Accept', 'application/json');
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');

        Http h = new Http();
        HttpResponse response = h.send(req);
        return response.getBodyAsBlob();
    }

    private  List searchDrive(){

        // To search within 24 hours
        Datetime dt = System.now().addDays(-1);
        String GMTDate =  dt.formatGMT('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'');

        String q = '\''+this.root_folder+'\' in parents and createdTime>=\''+GMTDate+'\'' ;

        String searchString = EncodingUtil.urlEncode(q,'UTF-8');
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://www.googleapis.com/drive/v3/files?q='+searchString);
        req.setMethod('GET');

        req.setHeader('Authorization', 'Bearer '+this.access_token);
        req.setHeader('Accept', 'application/json');
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');

        Http h = new Http();
        HttpResponse response = h.send(req);

        Map dMap = (Map) JSON.deserializeUntyped(response.getBody());

        List files = (List) dMap.get('files');
        List listFiles = new List();
        if(files.size()>0)
        {
            for(Integer i=0;i dMap = (Map) JSON.deserializeUntyped(response.getBody());

        this.access_token = String.valueOf(dMap.get('access_token'));
        this.token_type = String.valueOf(dMap.get('token_type'));
    }

    public class JsonObj{
        public String id {get; set;}
        public String mimeType {get; set;}
        public String kind {get; set;}
        public String name {get; set;}
    }
}

// and I called it as 
GdriveSync obj = new GdriveSync();
obj.processFiles(ac.Id);