Google Drive API can not upload file into specific folder

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?

Upvotes: 0

Views: 3749

Answers (2)

Diogo Fagundes
Diogo Fagundes

Reputation: 11

I've had the same problem even doing everything as said, then I found out that seems to be needed that you activate some kind of support to shared-drives for it to work.

https://developers.google.com/drive/api/guides/enable-shareddrives

You should use supportsAllDrives: true in your request...like:

drive.files.create({
  resource: fileMetadata,
  media: media,
  fields: 'id',
  supportsAllDrives: true
});

This way you activate the shared-drives support. Otherwise it will return you an 404 error since GDrive won't find your folder.

Upvotes: 1

Kristkun
Kristkun

Reputation: 5963

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.

Upvotes: 2

Related Questions