I have a file up on Google drive, which was uploaded using Google drive api v3. The file in question was not converted to a Google sheet when it was uploaded. (Yes my code was messed up, trying to fix it.)
It was uploaded with the mime type of text/csv
Image below shows its type as Comma separated values
.
I have another file which was uploaded with the correct mime type application/vnd.google-apps.spreadsheet
which caused the file to be converted to a Google sheet. Image below shows its type as Google sheet
What I am trying to do is run a file.update on the file that was uploaded with the wrong mime type and change its mime type and upload the file again, causing it to be converted to a Google sheet.
Sending the following as the metadata for the file should cause it to be converted.
'mimeType': 'application/vnd.google-apps.spreadsheet'
Unfortunately it does not it results in the following error
errors: [ { domain: 'global', reason: 'invalidContentType', message: 'Invalid MIME type provided for the uploaded content.', locationType: 'other', location: 'media.mimeType' }
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
// npm install googleapis
// https://developers.google.com/drive/api/v3/quickstart/nodejs
// Desktop app credentials from Google Cloud console.
const KEYFILEPATH = 'C:\\Youtube\\dev\\ServiceAccountCred.json';
const FILEIDTOUPDATE = '1YtJxL1WptkHUbDHNWpcbKwcRs7rPo_cY';
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive'];
// Create a service account initialize with the service account key file and scope needed
const auth = new google.auth.GoogleAuth({
keyFile: KEYFILEPATH,
scopes: SCOPES
});
/**
* Creates a new file on google drive and uploads it.
* @param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
async function createAndUploadFile(auth) {
const driveService = google.drive({version: 'v3', auth});
let fileMetadata = {
'name': 'sheet',
'mimeType': 'application/vnd.google-apps.spreadsheet' // will cause the file to be converted to the google drive type.
};
let media = {
mimeType: 'text/csv',
body: fs.createReadStream('sheet.csv')
};
await driveService.files.update({
fileId : FILEIDTOUPDATE,
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.data.id);
}
});
}
createAndUploadFile(auth).catch(console.error);
In order to test this that it wasn't actually an issue with my code i ran the code against the sheet that had been uploaded properly and it worked fine. According to the documentation MimeType should be writable
I am at a loss to explain this issue. I am wondering if the update method does not have the covert super power that the create method does.
'Invalid MIME type provided for the uploaded content.
:When your situation is considered, it seems that you are trying to change the mimeType of CSV file to Google Spreadsheet using the method of "Files: update" of Drive API. If the mimeType can be changed with "Files: update" method, from above situation, the file ID is also required to be changed. I guessed that such situation might be the reason of the current issue.
In order to check this hypothesis, I did the following experiments.
text/csv
, the PNG file is converted to the CSV file without changing the file ID.image/png
without changing the file content.
From above results, it is considered the following situation.
media
of 0 byte was required to be used for changing the mimeType.Also, above results might be able to answer for "writable" of mimeType for "Files: update".
About your script, for example, when the mimeType of CSV file is converted to Google Spreadsheet, the method of "Files: copy" of Drive API can be used. In this case, the file ID of the converted file (Spreadsheet) is changed from the CSV file. So, I thought that your script might be able to be modified as follows.
const driveService = google.drive({ version: 'v3', auth });
let fileMetadata = { name: 'sheet' };
let media = {
mimeType: 'text/csv',
body: fs.createReadStream('sheet.csv'),
};
driveService.files.update(
{
fileId: FILEIDTOUPDATE,
resource: fileMetadata,
media: media,
fields: 'id',
},
function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.data.id);
driveService.files.copy(
{
fileId: FILEIDTOUPDATE,
resource: { mimeType: "application/vnd.google-apps.spreadsheet" },
},
function (err, { data }) {
if (err) {
console.error(err);
return;
}
console.log(data);
}
);
}
}
);
FILEIDTOUPDATE
is updated by the file of sheet.csv
using the method of "Files: update". And, the CSV file is converted to Google Spreadsheet using the method of "Files: copy".