Reputation: 87
I am new in Javascript and sorry if my question seems lame to you. I want to upload an image from my website to my Google Drive. I have successfully implemented the Authentication and Folder creation part, but I am confused about the uploading process.
Say this is my code for creating a folder inside Google Drive:
function createFolder(folderName) {
var parentId = 'xxxxxxx';//some parentId of a folder under which to create the new folder
var fileMetadata = {
'name' : folderName,
'mimeType' : 'application/vnd.google-apps.folder',
'parents': [parentId]
};
gapi.client.drive.files.create({
resource: fileMetadata,
}).then(function(response) {
switch(response.status){
case 200:
var file = response.result;
console.log('Created Folder Id: ', file.id);
uploadImage(file.id);
break;
default:
console.log('Error creating the folder, '+response);
break;
}
});
}
Now I want to upload my image from this url: https://xxxxxx.com
into the newly created folder from upper response (file.id
)
This is what I got in Google API documentation, but where should I put/attached my url in it?
function uploadImage(folderId) {
var fileMetadata = {
'name': 'photo.jpg',
parents: [folderId]
};
var media = {
mimeType: 'image/jpeg',
body: fs.createReadStream('files/photo.jpg')
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.id);
}
});
}
Thanks a lot in advance.
Upvotes: 1
Views: 3487
Reputation: 201583
I believe your goal as follows.
gapi.client
can be used for uploading the file to Google Drive.gapi.client.drive.files.create
cannot still send the request including the content. Ref So in this case, I would like to propose to use fetch
as a workaround. When fetch
is used, the file content and metadata can be requested with multipart/form-data
.gapi.client
. So this script supposes that your gapi.client
can be used for uploading the file. Please be careful this.const url = "###"; // Please set the URL.
const fileName = "sample filename";
const folderId = "###"; // Please set the folder ID.
fetch(url).then(res => res.blob()).then(blob => {
const form = new FormData();
form.append('metadata', new Blob([JSON.stringify({name: fileName, parents: [folderId]})], {type: 'application/json'}));
form.append('file', blob);
fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
method: 'POST',
headers: new Headers({'Authorization': 'Bearer ' + gapi.auth.getToken().access_token}),
body: form
}).then(res => res.json()).then(val => console.log(val));
});
When you run this script, the following result can be seen at the console. (When the URL is the direct link of Jpeg image file.)
{
"kind": "drive#file",
"id": "###",
"name": "sample filename",
"mimeType": "image/jpeg"
}
uploadType=multipart
is used. So the maximum file size is 5 MB. Please be careful this. When you want to use more than 5 MB, please check Resumable upload. RefIn order to avoid the error related to CORS, as an another method, I would like to propose to use the Web Apps as a wrapper. In this case, the client side is Javascript. This Javascript can be used at outside of the Google.
Please do the following flow.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps.
Server side: Google Apps ScriptThis script is used for Web Apps. In this case, the Web Apps is used as the wrapper.
function doGet(e) {
const imageUrl = e.parameter.imageUrl;
const res = UrlFetchApp.fetch(imageUrl);
if (res.getResponseCode() != 200) throw new Error("Image couldn't be retrieved.");
const blob = res.getBlob();
const file = DriveApp.getFolderById(e.parameter.folderId).createFile(blob.setName(e.parameter.filename));
const obj = {id: file.getId(), name: file.getName(), mimeType: file.getMimeType()};
return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}
https://script.google.com/macros/s/###/exec
.
Please set the URL of your Web Apps to the following script. And, please set the filename and folder ID.
const imageUrl = "###"; // Please set the URL of image.
const url = "https://script.google.com/macros/s/###/exec"; // Please set the URL of Web Apps.
const qs = new URLSearchParams({
imageUrl: imageUrl,
filename: "sample filename",
folderId: "###", // Please set folder ID.
});
fetch(`${url}?${qs}`).then((res) => res.json()).then(console.log).catch(console.log);
Result:
When above script is run, the following value is returned. You can see the returned value at the console.
{
"id": "###",
"name": "###",
"mimeType": "###"
}
Upvotes: 1
Reputation: 912
Try to upload your photo file using this snippet:
// download file from website
const http = require('https')
const fs = require('fs')
let file = fs.createWriteStream('Photo001.jpg')
let request = http.get(
'https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_2x.png',
(response) => {
response.pipe(file)
})
// upload file to Google Drive
let fileMetadata = {
'name' : 'Photo001',
'mimeType': 'image/jpeg'
}
let media = {
mimeType : 'image/jpeg',
body : fs.createReadStream('Photo001.jpeg')
}
function uploadFile(auth){
const drive = google.drive({version: 'v3', auth})
drive.files.create({
resource: fileMetadata,
media : media,
fields : 'id'
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err)
})
}
Upvotes: 1