Reputation: 83
I have found many posts on how to retrieve the contents of a .txt
file from the google drive with their API. I have tried using this:
const drive = google.drive({version: 'v3', auth});
var data = drive.files.get({
fileId: file_id,
alt: "media"
});
data.execute(function(response){
console.log(reponse)
})
My error
data.execute(function(response){
^
TypeError: data.execute is not a function
and also data.then
instead of data.execute
each time there is an error that I research and find no resolution to it. Could someone please give me an updated version of how to get the contents of a file from the file id? As I think the previous answers are outdated somewhat.
Sorry if this is pretty obvious. I relatively new to javascript and apis in general. So this would help me out a lot as it's the final stretch before I finish my program :)
Thanks, Mathias
Upvotes: 2
Views: 6387
Reputation: 6538
The solutions offered here do not handle concurrency correctly. The problem is that the functions will end before the stream of data for the file will end. Here is a solution where the function will end after the file data stream will be consumed:
import { google } from "googleapis"
const jwtClient = new google.auth.JWT("", undefined, "",
["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive"]
)
const googleDrive = google.drive("v3")
async function downloadFile(fileId: string): Promise<Buffer> {
await jwtClient.authorize()
const res = await googleDrive.files.get(
{ fileId, alt: "media", auth: jwtClient },
{ responseType: "stream" }
)
const buffers: any[] = []
await new Promise<void>((resolve, reject) => {
res.data
.on("end", () => {
console.log(`End of reading the file`)
resolve()
})
.on("error", err => {
reject(`Cannot create file ${err}`)
})
.on("data", chunk => {
buffers.push(chunk)
})
})
console.log(`End of the function`)
return Buffer.concat(buffers)
}
The message End of reading the file
will be printed before the message End of the function
will be printed.
Upvotes: 0
Reputation: 8783
When you run 'drive.files.get' for google drive API you receive a promise, and to get data you have to use then on it. This is how it works:
const filePath = `give_path_tosave_file`;
const dest = fs.createWriteStream(filePath);
let progress = 0;
drive.files.get(
{ fileId, alt: 'media' },
{ responseType: 'stream' }
).then(res => {
res.data
.on('end', () => {
console.log('Done downloading file.');
})
.on('error', err => {
console.error('Error downloading file.');
})
.on('data', d => {
d+='';
console.log(d);
//data will be here
// pipe it to write stream
}
})
.pipe(dest);
});
If above solution doesn't work, you can use this one. It is on official google website for doing the same:
var fileId = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo';
var dest = fs.createWriteStream('/tmp/filename.txt');
drive.files.export({
fileId: fileId,
mimeType: 'application/txt'
})
.on('end', function () {
console.log('Done');
})
.on('error', function (err) {
console.log('Error during download', err);
})
.pipe(dest);
For more info, you should check here.
Also, the below method will return all the files which you have access to in drive.
drive.files.list({}, (err, res) => {
if (err) throw err;
const files = res.data.files;
if (files.length) {
files.map((file) => {
console.log(file);
});
} else {
console.log('No files found');
}
});
Upvotes: 3