Carlos Rogerio
Carlos Rogerio

Reputation: 11

Google API to upload files using the Authentication Service Account

I'm trying to send files by API Google Drive, though, I can not find any documentation on how to perform C # Uploading files using the Authentication Service Account.

I downloaded the Daimto library, however, he uploads using the DriveService class, when we use the authentication ClientId and ClientSecret. But using authentication for account service he returns to PlusService class, and found no way to upload files this way.

Can someone help me? Best regards

Using Authentication Service Account

    public PlusService GoogleAuthenticationServiceAccount()
    {
        String serviceAccountEmail = "106842951064-6s4s95s9u62760louquqo9gu70ia3ev2@developer.gserviceaccount.com";

        //var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
        var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

        ServiceAccountCredential credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = new[] { PlusService.Scope.PlusMe }
           }.FromCertificate(certificate));

        // Create the service.
        var service = new PlusService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Plus API Sample",
        });

        return service;
    }

Using Authentication ClientId and ClientSecret

    public DriveService GoogleAuthentication(string userClientId, string userSecret)
    {
        //Scopes for use with the Google Drive API
        string[] scopes = new string[] { DriveService.Scope.Drive, DriveService.Scope.DriveFile };
        // here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
        UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = userClientId, ClientSecret = userSecret }, scopes, Environment.UserName, CancellationToken.None, new FileDataStore("Daimto.GoogleDrive.Auth.Store")).Result;

        DriveService service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Drive API Sample"
        });

        return service;
    }

Daimto class method that makes the file upload to google drive DaimtoGoogleDriveHelper.uploadFile(_service, fileName, item.NomeArquivo, directoryId);

As you can see, the Daimto library, has a method to upload, however, uses the _service parameter, which is the DriveService type, which is what is returned by GoogleAuthentication method. But the GoogleAuthenticationServiceAccount method returns a PlusService type and is incompatible with the DriveService type.

Upvotes: 1

Views: 3862

Answers (1)

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116869

I am not sure which one of my tutorials you are following. But your first hunk of code is using a PlusService you should be using a DriveService. Any requests you make to the Google drive API must go though a DriveService

Authenticating to Google drive with a service account:

/// <summary>
        /// Authenticating to Google using a Service account
        /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
        /// </summary>
        /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com</param>
        /// <param name="keyFilePath">Location of the Service account key file downloaded from Google Developer console https://console.developers.google.com</param>
        /// <returns></returns>
        public static DriveService AuthenticateServiceAccount(string serviceAccountEmail, string keyFilePath)
        {

            // check the file exists
            if (!File.Exists(keyFilePath))
            {
                Console.WriteLine("An Error occurred - Key file does not exist");
                return null;
            }

            //Google Drive scopes Documentation:   https://developers.google.com/drive/web/scopes
            string[] scopes = new string[] { DriveService.Scope.Drive,  // view and manage your files and documents
                                             DriveService.Scope.DriveAppdata,  // view and manage its own configuration data
                                             DriveService.Scope.DriveAppsReadonly,   // view your drive apps
                                             DriveService.Scope.DriveFile,   // view and manage files created by this app
                                             DriveService.Scope.DriveMetadataReadonly,   // view metadata for files
                                             DriveService.Scope.DriveReadonly,   // view files and documents on your drive
                                             DriveService.Scope.DriveScripts };  // modify your app scripts     

            var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
            try
            {
                ServiceAccountCredential credential = new ServiceAccountCredential(
                    new ServiceAccountCredential.Initializer(serviceAccountEmail)
                   {
                       Scopes = scopes
                   }.FromCertificate(certificate));

                // Create the service.
                DriveService service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Daimto Drive API Sample",
                });
                return service;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                return null;

            }
        }
    }

Upload a file:

private static string GetMimeType(string fileName)
        {
            string mimeType = "application/unknown";
            string ext = System.IO.Path.GetExtension(fileName).ToLower();
            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
            if (regKey != null && regKey.GetValue("Content Type") != null)
                mimeType = regKey.GetValue("Content Type").ToString();
            return mimeType;
        }

        /// <summary>
        /// Uploads a file
        /// Documentation: https://developers.google.com/drive/v2/reference/files/insert
        /// </summary>
        /// <param name="_service">a Valid authenticated DriveService</param>
        /// <param name="_uploadFile">path to the file to upload</param>
        /// <param name="_parent">Collection of parent folders which contain this file. 
        ///                       Setting this field will put the file in all of the provided folders. root folder.</param>
        /// <returns>If upload succeeded returns the File resource of the uploaded file 
        ///          If the upload fails returns null</returns>
        public static File uploadFile(DriveService _service, string _uploadFile, string _parent) {

            if (System.IO.File.Exists(_uploadFile))
            {
                File body = new File();
                body.Title = System.IO.Path.GetFileName(_uploadFile);
                body.Description = "File uploaded by Diamto Drive Sample";
                body.MimeType = GetMimeType(_uploadFile);
                body.Parents = new List<ParentReference>() { new ParentReference() { Id = _parent } };

                // File's content.
                byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
                System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
                try
                {
                    FilesResource.InsertMediaUpload request = _service.Files.Insert(body, stream, GetMimeType(_uploadFile));
                    request.Upload();
                    return request.ResponseBody;
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error occurred: " + e.Message);
                    return null;
                }
            }
            else {
                Console.WriteLine("File does not exist: " + _uploadFile);
                return null;
            }           

        }

The upload code is the same if you are using Oauth2 or a service account there is no difference.

Code ripped from Google Drive .net sample on Github Tutorial: Google Drive API with C# .net – Download

Upvotes: 1

Related Questions