3

I am writing a nodejs function to transfer files from google drive to some other place

Following is the sample code block to get file from drive

var fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
var dest = fs.createWriteStream('/tmp/photo.jpg');
drive.files.get({
  fileId: fileId,
  alt: 'media'
})
    .on('end', function () {
      console.log('Done');
    })
    .on('error', function (err) {
      console.log('Error during download', err);
    })
    .pipe(dest);

instead of piping it to writable stream , I would like to get a readable stream that i can pass on to my function

uploadsomeplace(readableStream)

Update 1

i wrote a function to get that readable stream and upload it again to some folder in google drive (seems dumb but for test as drive.files.creates takes a readable stream)

const transferit = async () => {
  var fileId = '0BwwA4oUTe1UVNwOHItT0xfa2M' // some valid id

  let somereadstream = drive.files.get(
    { fileId, alt: 'media' },
    { responseType: 'stream' }
  )

  var folderId = '1oC90HZDLbfYiW2neSCMERHZ8ZH1X' // some valid id
  var fileMetadata = {
    name: 'photo.jpg',
    parents: [folderId]
  }
  var media = {
    mimeType: 'image/jpeg',
    // body: fs.createReadStream('image.jpg')
    body: somereadstream
  }
  return await drive.files.create({
    resource: fileMetadata,
    media: media
    // fields: 'id'
  })
}
transferit().then(data => console.log(data))

but i get error

(node:6200) UnhandledPromiseRejectionWarning: TypeError: part.body.pipe is not a function
Solaris
  • 674
  • 7
  • 22

3 Answers3

3

drive.files.get returns a promise which if fulfilled gives a response object which contains the readable stream in response.data

const isStream = require('is-stream')
const transferit = async () => {
  var fileId = '1uw5PhBF8z8uBsxmFKJef582Pp92UKpxM' // some valid id

  let somereadstream = await drive.files.get(
    { fileId, alt: 'media' },
    { responseType: 'stream' }
  )
  console.log(somereadstream)
  return isStream.readable(somereadstream.data)
}
Solaris
  • 674
  • 7
  • 22
1

By the looks of things

drive.files.get({
  fileId: fileId,
  alt: 'media'
})

already returns a readable stream. Just assign it to a variable and pass it into your function.

const readableStream = drive.files.get({
  fileId: fileId,
  alt: 'media'
});

uploadsomeplace(readableStream);
Dan Starns
  • 3,765
  • 1
  • 10
  • 28
0

This works for me in typescript:

async function getReadableStreamForFileId(
    drive: drive_v3.Drive,
    fileId: FileId,
): Promise<stream.Readable> {
  console.log('getReadableStreamForFileId', {drive, fileId});
  // https://developers.google.com/drive/api/v3/manage-downloads#node.js
  return (await drive.files.get(
      {fileId, alt: 'media'},
      {responseType: 'stream'},
  )).data as any as Promise<stream.Readable>;
}

example:

const fileId = '1F2*******************xGC';
const fileDataStream = await getReadableStreamForFileId(drive, fileId);
const target = fs.createWriteStream('data-out');
fileDataStream.pipe(target);

drive is initialized as described in https://developers.google.com/drive/api/v3/quickstart/nodejs

masterxilo
  • 2,503
  • 1
  • 30
  • 35