tbhaxor
tbhaxor

Reputation: 1943

Google Drive API Says "Forbidden" When Fetching File

For some reason I want to fetch the file from the google drive and process it on the server. From the picker I am getting the FileID and sending it to backend for download and the processing. So on downloading the file using googleapis, I am getting this error

enter image description here

Prerequisites

  1. Drive API is Enabled in the Project
  2. Access Token has the permission to Drive

Permissions I have Tried

  1. https://www.googleapis.com/auth/drive.readonly
  2. https://www.googleapis.com/auth/drive.file
  3. https://www.googleapis.com/auth/drive

The Code I am Using is from the GitHub

const tmpDir = path.resolve(path.join(os.tmpdir(), "user-sheets"));
const file = path.join(tmpDir, Date.now().toString());

let stream = fs.createWriteStream(file);
let drive = google.drive({
    version: "v3",
    auth: "MY ACCESS TOKEN",
});

drive.files
    .get(
        {
            fileId: req.body.url,
            alt: "media",
            oauth_token: "MY ACCESS TOKEN",
        },
        {
            responseType: "stream",
        }
    )
    .then((r) => {
        r.data
            .on("end", async () => {
                console.log("ended");
                stream.close();
            })
            .on("error", function (err) {
                console.log("Error during download", err);
                res.json({
                    success: false,
                    message: "Something went wrong",
                    error: err,
                });
            })
            .pipe(stream);
    })
    .catch((e) => {
        console.error(e.response);
    });

Upvotes: 1

Views: 564

Answers (1)

Tanaike
Tanaike

Reputation: 201378

In this answer, I suppose the following points.

  • MY ACCESS TOKEN of auth: "MY ACCESS TOKEN", is the valid access token for downloading the file.
  • req.body.url of fileId: req.body.url, is the file ID which is not the URL.

If my guess was not correct, please tell me.

When my guess was the correct, please confirm the following modification.

Modification point:

  • Unfortunately, MY ACCESS TOKEN cannot be directly used for google.drive() and drive.files.get().

When this point is reflected to your script, it becomes as follows.

Modified script:

From:
let drive = google.drive({
    version: "v3",
    auth: "MY ACCESS TOKEN",
});

drive.files
    .get(
        {
            fileId: req.body.url,
            alt: "media",
            oauth_token: "MY ACCESS TOKEN",
        },
        {
            responseType: "stream",
        }
    )
To:
var oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials({access_token: "MY ACCESS TOKEN"});
const drive = google.drive({
  version: "v3",
  auth: oauth2Client,
});
drive.files
  .get(
    {
      fileId: req.body.url,  // Please use the file ID here.
      alt: "media",
    },
    { responseType: "stream" }
  )

Note:

  • In this case, the files except for Google Docs files (Google Document, Google Spreadsheet, Google Slides and so on) can be downloaded. Please be careful this.

Reference:

Upvotes: 2

Related Questions