Google Drive API can not upload file into specific folder

27
November 26, 2020, at 06:10 AM

I have a unlimited storage google drive account from my school account, so I shared drive with my main google account, I want to use apis of google drive to upload video to that shared drive by an file input form. This is where i want to store the file:

where i want to store

I use express, googleapis, multer

And this is how I have done:

this is my credentials.json:

{
  "web": {
    "client_id": "607849031009-4gsgo99bbskgsou5676b59ievp4fadmb.apps.googleusercontent.com",
    "project_id": "spiritual-aloe-296616",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "OOAA7s1zXEUZ-5KemIhzjt4G",
    "redirect_uris": ["http://localhost:5000/google/callback"],
    "javascript_origins": ["http://localhost:5000"]
  }
}

I use express to write server and multer to upload file to the server:

const fs = require('fs');
const express = require('express');
const multer = require('multer');
const OAuth2Data = require('./credentials.json');
var name, pic;
const {google} = require('googleapis');
const app = express();
const CLIENT_ID = OAuth2Data.web.client_id;
const CLIENT_SECRET = OAuth2Data.web.client_secret;
const REDIRECT_URL = OAuth2Data.web.redirect_uris[0];
const oAuth2Client = new google.auth.OAuth2(
  CLIENT_ID,
  CLIENT_SECRET,
  REDIRECT_URL
);
var authed = false;
// If modifying these scopes, delete token.json.
const SCOPES =
  'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/userinfo.profile';
app.set('view engine', 'ejs');
var Storage = multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './images');
  },
  filename: function (req, file, callback) {
    callback(null, file.fieldname + '_' + Date.now() + '_' + file.originalname);
  },
});
var upload = multer({
  storage: Storage,
}).single('file'); //Field name and max count
app.get('/', (req, res) => {
  if (!authed) {
    // Generate an OAuth URL and redirect there
    var url = oAuth2Client.generateAuthUrl({
      access_type: 'offline',
      scope: SCOPES,
    });
    console.log(url);
    res.render('index', {url: url});
  } else {
    var oauth2 = google.oauth2({
      auth: oAuth2Client,
      version: 'v2',
    });
    oauth2.userinfo.get(function (err, response) {
      if (err) {
        console.log(err);
      } else {
        console.log(response.data);
        res.render('success', {
          success: false,
        });
      }
    });
  }
});
app.post('/upload', (req, res) => {
  upload(req, res, function (err) {
    if (err) {
      console.log(err);
      return res.end('Something went wrong');
    } else {
      console.log(req.file.path);
      const drive = google.drive({version: 'v3', auth: oAuth2Client});
      const fileMetadata = {
        name: req.file.filename,
      };
      const media = {
        mimeType: req.file.mimetype,
        body: fs.createReadStream(req.file.path),
      };
      drive.files.create(
        {
          resource: fileMetadata,
          media: media,
          fields: 'id',
        },
        (err, file) => {
          if (err) {
            // Handle error
            console.error(err);
          } else {
            fs.unlinkSync(req.file.path);
            res.render('success', {name: name, pic: pic, success: true});
          }
        }
      );
    }
  });
});
app.get('/logout', (req, res) => {
  authed = false;
  res.redirect('/');
});
app.get('/google/callback', function (req, res) {
  const code = req.query.code;
  if (code) {
    // Get an access token based on our OAuth code
    oAuth2Client.getToken(code, function (err, tokens) {
      if (err) {
        console.log('Error authenticating');
        console.log(err);
      } else {
        console.log('Successfully authenticated');
        console.log(tokens);
        oAuth2Client.setCredentials(tokens);
        authed = true;
        res.redirect('/');
      }
    });
  }
});
app.listen(5000, () => {
  console.log('App is listening on Port 5000');
});

finally it works, but the thing is, it uploaded to the home page of my google drive account

upload uploaded

meanwhile, I want it saved in the shared-drive folder, sorry for my bad English, thank you for help me out, hope you have a good day and a blessed ThanksGiving :)

UPDATE

this is the url of the shared-drive: https://drive.google.com/drive/u/3/folders/0AKRMoXHA-b-NUk9PVA?fbclid=IwAR2je0Ip7xwsaX7ghqZ0F0JWYYjImyvG1BEnRK2DjCGvRKFg7THFX8

one more thing is that how can i got the url of the file i have just uploaded?

Answer 1

You can create files in a specific folder by adding "parents" property in the request body and set its value based on the folder's id.

Sample:

folder_id = 'xxxxxxxxsamplefolderidxxxx'
file_metadata = {
'name': 'photo.jpg',
'parents': [folder_id]
}

In your code:

const fileMetadata = {
    name: req.file.filename,
    parents: 'xxxxxxxxsamplefolderidxxxx'
  };

It is also stated that if "parents" is not specified as part of a create request, the file will be placed directly in the user's My Drive folder. If not specified as part of a copy request, the file will inherit any discoverable parents of the source file. Update requests must use the addParents and removeParents parameters to modify the parents list.

Reference: https://developers.google.com/drive/api/v3/reference/files/create

To get the folder id, you can get it from the folder's link in drives.google.com

Sample:

https://drive.google.com/drive/folders/1234SampleFolderId

where Folder Id = 1234SampleFolderId

(Updated based on additional questions)

Note: Folder Id should start after 'folders/' and ends before '?'

Example: folders/HereIsTheFolderId?fbclid=

Regarding the url of the file that was uploaded, successful file creation will return a Files Resource in the response body.

File Resource Reference: https://developers.google.com/drive/api/v3/reference/files#resource

webContentLink -A link for downloading the content of the file in a browser.

webViewLink -A link for opening the file in a relevant Google editor or viewer in a browser.

READ ALSO
How to insert json object inside nested object in a document based on nested object UUID

How to insert json object inside nested object in a document based on nested object UUID

I am working on a small project and I am stuck from last month and looking for an exact query to update my document at the exact location

31
Trying to return from co generator runner in nodejs

Trying to return from co generator runner in nodejs

I want to create a function that runs asynchronous code sequentialyThis function takes parameters and returns a Promise that resolves with a JavaScript object

52
Problem with my ToDoList , findAndRemoveById dont work

Problem with my ToDoList , findAndRemoveById dont work

im doing my course and now making a ToDoList and upgrading it with mongoose but the problem is that in this video everything work fine but for me its showing ,,Argument passed in must be a single String

26
How to migrate a whole React.js web-app to Typescript [closed]

How to migrate a whole React.js web-app to Typescript [closed]

Want to improve this question? Update the question so it's on-topic for Stack Overflow

39