Faça upload da imagem do URL para o Google Drive por meio da API Javascript do Google Drive

Aug 18 2020

Eu sou novo em Javascript e desculpe se minha pergunta parece coxo para você. Quero fazer upload de uma imagem do meu site para o Google Drive. Implementei com sucesso a parte de autenticação e criação de pasta, mas estou confuso sobre o processo de upload.
Digamos que este seja meu código para criar uma pasta dentro do 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;
    }
  });
}

Agora eu quero fazer o upload da minha imagem deste url: https://xxxxxx.compara a pasta recém-criada da resposta superior ( file.id)

Isso é o que eu obtive na documentação da API do Google, mas onde devo colocar / anexar meu url nele?

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

Muito obrigado antecipadamente.

Respostas

1 Tanaike Aug 19 2020 at 08:26

Eu acredito em seu objetivo da seguinte maneira.

  • Você deseja fazer download de um arquivo de um URL e carregá-lo no Google Drive usando Javascript.
  • No seu caso, gapi.clientpode ser usado para enviar o arquivo ao Google Drive.

Pontos de modificação:

  • No estágio atual, infelizmente, parece que gapi.client.drive.files.createainda não é possível enviar a solicitação incluindo o conteúdo. Ref Então, neste caso, eu gostaria de propor o uso fetchcomo uma solução alternativa. Quando fetché usado, o conteúdo do arquivo e os metadados podem ser solicitados com multipart/form-data.
  • Nesta solução alternativa, o token de acesso é usado de gapi.client. Portanto, este script supõe que você gapi.clientpode ser usado para enviar o arquivo. Por favor, tome cuidado com isso.

Script modificado:

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));
});
  • Quando você executa este script, o seguinte resultado pode ser visto no console. (Quando o URL é o link direto do arquivo de imagem Jpeg.)

      {
        "kind": "drive#file",
        "id": "###",
        "name": "sample filename",
        "mimeType": "image/jpeg"
      }
    

Nota:

  • Nesse caso, uploadType=multiparté usado. Portanto, o tamanho máximo do arquivo é 5 MB. Por favor, tome cuidado com isso. Quando você quiser usar mais de 5 MB, marque Upload retomável. Ref

Referências:

  • Usando Fetch
  • Carregar dados do arquivo

Adicionado:

Para evitar o erro relacionado ao CORS, como outro método, gostaria de propor o uso de Web Apps como wrapper. Neste caso, o lado do cliente é Javascript. Este Javascript pode ser usado fora do Google.

Uso:

Faça o seguinte fluxo.

1. Crie um novo projeto do Google Apps Script.

O script de amostra do Web Apps é um Script do Google Apps. Portanto, crie um projeto do Google Apps Script.

Se você deseja criá-lo diretamente, acesse https://script.new/. Nesse caso, se você não estiver conectado ao Google, a tela de login será aberta. Portanto, faça login no Google. Com isso, o editor de script do Google Apps Script é aberto.

2. Prepare o script.

Copie e cole o seguinte script (Google Apps Script) no editor de script. Este script é para os aplicativos da Web.

Lado do servidor: Script do Google Apps

Este script é usado para aplicativos da web. Nesse caso, os Web Apps são usados ​​como 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. Implantar aplicativos da Web.

  1. No editor de script, abra uma caixa de diálogo por "Publicar" -> "Implementar como aplicativo da web".
  2. Selecione "Eu" para "Executar o aplicativo como:" .
    • Por isso, o script é executado como o proprietário.
  3. Selecione "Qualquer pessoa, mesmo anônima" para "Quem tem acesso ao aplicativo:" .
  4. Clique no botão "Implementar" como uma nova "Versão do projeto".
  5. Abra automaticamente uma caixa de diálogo de "Autorização necessária".
    1. Clique em "Permissões de revisão".
    2. Selecione sua própria conta.
    3. Clique em "Avançado" em "Este aplicativo não foi verificado".
    4. Clique em "Ir para ### nome do projeto ### (inseguro)"
    5. Clique no botão "Permitir".
  6. Clique OK".
  7. Copie o URL dos aplicativos da web. É como https://script.google.com/macros/s/###/exec.
    • Quando você modificou o Google Apps Script, reimplante como nova versão. Com isso, o script modificado é refletido para Web Apps. Por favor, tome cuidado com isso.

4. Carregue um arquivo do lado do cliente para o lado do servidor.

Lado do cliente: HTML e Javascript

Defina o URL de seus aplicativos da web para o seguinte script. E defina o nome do arquivo e o ID da pasta.

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);
Resultado:

Quando o script acima é executado, o seguinte valor é retornado. Você pode ver o valor retornado no console.

{
  "id": "###",
  "name": "###",
  "mimeType": "###"
}

Nota:

  • Quando você modificou o script de Web Apps, reimplante os Web Apps como uma nova versão. Com isso, o script mais recente é refletido nos Web Apps. Por favor, tome cuidado com isso.

Referências:

  • Aplicativos da web
  • Aproveitando as vantagens do Web Apps com o Google Apps Script
1 JeffRush Aug 18 2020 at 21:23

Tente fazer upload de seu arquivo de foto usando este 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)
  })

}

Documentação

  • Arquivos: criar