Downloading and Uploading File to Google Drive without Saving File with Stream and Resumable Upload using Node.js

Gists

This is a sample script of Node.js for downloading the data and uploading the data to Google Drive with the resumable upload without saving it as a file. The downloaded data is uploaded to Google Drive with the stream.

Sample script

Before you use this, please set the variables of accessToken, url, fileSize, mimeType and filename. In this case, fileSize is required to set because the data is uploaded with the resumable upload.

const request = require("request");
const stream = require("stream");

// Please set the following variables.
const accessToken = "###"; // access token: This is used for uploading the data to Google Drive.
const url = "###"; // URL of data.
const fileSize = 123456789; // Data size of the downloaded data.
const mimeType = "###"; // MimeType of the downloaded data.
const filename = "sample file"; // This is the filename on Google Drive.

// 1. Download data from URL
const res = request(url);
const data = new stream.PassThrough();
data.on("error", (err) => console.log(err));
data.on("end", () => console.log("Done."));
res.pipe(data);

// 2. Retrieve session for resumable upload.
request(
  {
    method: "POST",
    url:
      "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ name: filename, mimeType: mimeType }),
  },
  (err, res) => {
    if (err) {
      console.log(err);
      return;
    }

    // 3. Upload the file.
    request(
      {
        method: "PUT",
        url: res.headers.location,
        headers: { "Content-Range": `bytes 0-${fileSize - 1}/${fileSize}` },
        body: data,
      },
      (err, res, body) => {
        if (err) {
          console.log(err);
          return;
        }
        console.log(body);
      }
    );
  }
);

Note

  • If the server, which has the file you want to download, can use Range in the request header, you can retrieve the fileSize and mimeType using the following script.

    request(
      { url: url, method: "get", headers: { Range: "bytes=0-1" } },
      (err, res) => {
        if (err) {
          console.log(err);
          return;
        }
        const fileSize = res.headers["content-range"].split("/").pop();
        const mimeType = res.headers["content-type"];
        console.log(fileSize);
        console.log(mimeType);
      }
    );
    

References

 Share!