1

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.

8
  • It seems that your upper and lower scripts are Javascript and Node.js, respectively. Unfortunately, I cannot understand about your question. I apologize for this. Can I ask you about the detail of your current issue and your goal? Commented Aug 18, 2020 at 4:41
  • @Tanaike Thanks for your comment. Let me paraphrase my question again. I have an image on a certain url say (example.com/something). So I want to upload that image from that url to my Google Drive using Google Drive API. I want to save/upload that image on a particular folder, which I also wanna create from my client end. So here I have created that folder under a parent folder after successful authentication (1st part of my code section in the post). Commented Aug 18, 2020 at 9:57
  • Now It's time to upload/save the image from that url (example.com/something) to my Google Drive inside this newly created folder. But when I searched in the Google API official documentation, I found this code (2nd part of my code section in the post), where I don't know how to attached my url (example.com/something) so that it could be uploaded to my Google Drive. Commented Aug 18, 2020 at 9:57
  • So in the official doc of Google API (2nd part of my code) I am seeing name: photo.jpg under var fileMetadata, but I have url instead of any image name. So how can I attached my url with this function so that it upload to my Google Drive. Thanks! Commented Aug 18, 2020 at 10:01
  • Take a look on my answer, test it and let me know your result Commented Aug 18, 2020 at 14:23

2 Answers 2

1

I believe your goal as follows.

  • You want to download a file from an URL and upload the downloaded file to Google Drive using Javascript.
  • In your case, your gapi.client can be used for uploading the file to Google Drive.

Modification points:

  • In the current stage, unfortunately, it seems that 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.
  • In this workaround, the access token is used from gapi.client. So this script supposes that your gapi.client can be used for uploading the file. Please be careful this.

Modified script:

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"
      }
    

Note:

  • In this case, 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. Ref

References:

Added:

In 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.

Usage:

Please do the following flow.

1. Create new project of Google Apps Script.

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.

2. Prepare script.

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 Script

This 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);
}

3. Deploy Web Apps.

  1. On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
  2. Select "Me" for "Execute the app as:".
    • By this, the script is run as the owner.
  3. Select "Anyone, even anonymous" for "Who has access to the app:".
  4. Click "Deploy" button as new "Project version".
  5. Automatically open a dialog box of "Authorization required".
    1. Click "Review Permissions".
    2. Select own account.
    3. Click "Advanced" at "This app isn't verified".
    4. Click "Go to ### project name ###(unsafe)"
    5. Click "Allow" button.
  6. Click "OK".
  7. Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
    • When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.

4. Upload a file from client side to server side.

Client side: HTML & Javascript

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": "###"
}

Note:

  • When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to Web Apps. Please be careful this.

References:

Sign up to request clarification or add additional context in comments.

23 Comments

I am looking into it Sir. Thanks for your long support and suggestion. I really appreciate that. Stay safe stay blessed! :)
@Avow Studio Thank you for replying. I'm glad your issue was resolved. I would like to support you. But the issue of your comment is new issue, and that is different from your question. So can you post it as new question by including the detail information? Because when your initial question is changed by comment, other users who see your question are confused. By posting it as new question, users including me can think of your new question. If you can cooperate to resolve your new issue, I'm glad.
@Avow Studio Thank you for your response. When you posted the new question including more information, I would like to check it. And also, it will help other users think of the solution.
Hello sir, I have posted my question. Please take have a look. Thanks! stackoverflow.com/questions/63555056/…
@Avow Studio Thank you for your response. I will check it. When I could find the modification point, I would like to propose it as an answer.
|
1

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)
  })

}

Documentation

3 Comments

Thanks for your reply. But where would I attached the value of my image URL here? As I said say (example.com/something) this is my image URL link, but in the answer, there is nothing related to this. All I can see the name: photo001 parameter in fileMetadata. How should I pass the URL parameter?
Hi @AvowStudio, I edited my answer (added how to download a file from website), test it and let me know if everything works to you as expected
Thanks @Jeff Rush. Can you please tell me what should I put here let file = fs.createWriteStream('Photo001.jpg'), cause I have only URL image. And Folder ID, in which I want to upload that image.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.