Search code examples
node.jsgoogle-apigoogle-drive-apiservice-accountsgoogle-api-nodejs-client

Download Google Drive file owned by some account and shared with my service account


There is an URL of a shared spreadsheet file hosted by Google Drive.

It looks similar to this one

https://docs.google.com/spreadsheets/d/1TFFswncS12FAc-Fsh33dMfL0UK87LCcZZNToV0/edit?usp=sharing

I want to download this file by nodejs app using some Google service account and Google Drive API client library. But as far as I can see that library just doesn't have such a method or option to download a file by URL.

https://developers.google.com/drive/api/v3/manage-downloads

Instead of that, there is a get method that requires fileId property, and it seems to me that it is not possible to access somebody's files by that fileId.

So, most probably, I'll have to generate an authentication token based on service account client_id and private_key and download (actually, exported CSV) with any HTTP client passing the token as a header.

Is that a correct choice and how to authenticate to the app without password?

I have such application environment variables

GOOGLE_FEED_ACCOUNT_TYPE=service_account
GOOGLE_FEED_PROJECT_ID=my-app
GOOGLE_FEED_PRIVATE_KEY_ID=sdf796a7S58FSADF9A8S97FD987AS6D8F75A8Sas
GOOGLE_FEED_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n\n-----END PRIVATE KEY-----\n"
[email protected]
GOOGLE_FEED_CLIENT_ID=398387234329388162487
GOOGLE_FEED_FOLDER_ID=1QFBASSDFasdfasew3wsD85cHpf-9U

Solution

  • What you need to understand is that if someone else has access to your file then its private data. You need the permission of the owner of the flie to access it. Using a service account you can preauthorize it and grant it access to the file. If that person shares the file with the service account email address like you would share it with any other user then then and only then will the service account have access to download the file.

    Is that a correct choice and how to authenticate to the app without password?

    The only way you can get access to private user data is if the user grants you access. You can use Oauth2 and ask the user to run your application and grant you access, or you can use a service account and pre authorize it to access the data.

    There is really no way to gain access to private user data without them granting you that access somehow. Client login used login and password and that was shut down by google in 2015 so that hasn't worked in years.

    Exporting a sheet with a service account.

    You are correct this is not done by downloading a url this is done by using the file.id of the file you wish to download.

    As you will be downloading a google sheet your going to want to do a file.export to download the flie. File export will convert your sheet to a csv file so that you can read it on your machine.

    Just make sure that you shared it with the service account.

    const {google} = require('googleapis');
    
    const auth = new google.auth.GoogleAuth({
      keyFile: '/path/to/your-secret-key.json',
      scopes: ['https://www.googleapis.com/auth/cloud-platform'],
    });
    
    var fileId = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo';
    var dest = fs.createWriteStream('/tmp/resume.pdf');
        drive.files.export({
          fileId: fileId,
          mimeType: 'application/pdf'
        })
            .on('end', function () {
              console.log('Done');
            })
            .on('error', function (err) {
              console.log('Error during download', err);
            })
            .pipe(dest);