Como fazer upload de arquivos para o Google Drive em Node.js – Parte 2

No tutorial anterior a este, eu mostrei como fazer uma aplicação console que se autentica e sobe um arquivo para o Google Drive. Nesta parte 2, vou lhe mostrar como fazer uma aplicação web que sobe e exibe arquivos de mídia variados como imagens, vídeos e até áudios para o Google Drive, exibindo em um front bem simples.

Isso pode ser extremamente útil para que você possa usar a sua conta do Google Drive como um disco para armazenar arquivos multimídia do seu site ou aplicação web escrita em Node.js.

Antes de começarmos, crie uma aplicação de exemplo com o express-generator, como mostro no vídeo abaixo, usando o EJS como view-engine.

É nela que vamos construir a nossa aplicação que se integra com o Google Drive.

Falando nele, obviamente para que você consiga acompanhar este tutorial você deve ter uma conta no Google Drive. Se você possui um Gmail, automaticamente possui uma pois seus emails são armazenados na mesma que, em seu nível gratuito, fornece 15GB de armazenamento na nuvem. Por cerca de R$70/ano você faz um upgrade para 100GB o que lhe permite salvar muita coisa de maneira rápida e segura.

Caso não possua uma, crie em drive.google.com

Depois, visite este painel do Google Drive APIs  e clique no botão “Enable Drive API” para que seja possível se integrar com a sua conta do GDrive, conforme a imagem abaixo.

Google Drive APIs
Google Drive APIs

Ao ativar a API, você deve informar uma URL de retorno na sua aplicação, que receberá o acess token quando o usuário fizer a integração com a conta dele. Use localhost:3000 em nosso tutorial e selecione o tipo Web Server.

Você também receberá um Client ID e um Client Secret, que serão necessários para a autenticação na aplicação Node.js. Baixe o arquivo credentials.json e salve-o na pasta do projeto que criou com o express-generator, mas não esqueça de colocar ele no seu gitignore.

Atenção: este é um projeto intermediário em Node.js. Recomendo tutoriais mais básicos caso esteja começando agora.

Configurando o projeto

Agora que temos as credenciais para acessar a nossa conta do Google Drive e um projeto Express funcional, vamos começar instalando as dependências que vamos precisar.

O Formidable é um pacote que eu já ensinei a usar antes aqui no blog, neste tutorial. Ele serve para fazer upload de arquivos facilmente para um backend Node.js

O GoogleAPIs é o pacote oficial do Google para integração com seus produtos, abstraindo toda a comunicação com as APIs Restful deles através de classes e funções.

Para facilitar o desenvolvimento, também recomendo a instalação do nodemon.

Agora vamos configurar o nosso front-end. Abra views/index.ejs e altere o HTML para que tenhamos 3 formulários: um para envio de imagens, outro para envio de vídeos e outro para envio de áudios.

Aqui não temos nada demais, do ponto de vista de EJS: uma página HTML com alguns formulários, botões, inputs de arquivos, etc. Mas alguns pontos merecem atenção.

Primeiro, repare que usei alguns selects com o nome de uma pasta e um código no value do option. O nome da pasta deve ser uma que você crie na sua conta do Google Drive, a minha se chamada Teste. Já o código que vai no value do option é o ID da pasta que o Google Drive gera pra você. É bem simples de descobrir o ID de uma pasta, basta entrar nela e reparar na URL.

O que vem depois de folders/ é o ID da pasta em questão. Copie esse ID e coloque no option do seu select. Mais tarde, vamos fazer upload do arquivo para dentro desta pasta específica.

Outro ponto que merece atenção são as variáveis que devem vir do servidor e temos cinco delas: audio, video, image, auth e a title, que já vem por padrão. Para conseguirmos fazer um primeiro teste, precisamos ir no arquivo routes/index.js e alterar a rota GET padrão.

Se você rodar seu projeto agora, ele deve abrir uma página index com os formulários e a imagem, vídeo e áudio não carregarão, pois os valores dessas variáveis vieram vazios do servidor.

Opcionalmente, você pode retornar valores arbitrários, para que já venha algo carregado.

Agora temos o projeto minimamente preparado para criarmos a integração com o Google Drive.

Autenticação no Google Drive

O primeiro passo é fazermos funcionar o botão de autenticação que deixamos bem no topo da página. Ele é justamente pra conectar a nossa web application na conta do Google Drive de quem estiver utilizando ela.

Para isso, vamos criar um módulo gdrive.js na raiz do nosso projeto, que vai encapsular todas as funções de integração com o Google Drive.

A autenticação que vamos usar é a baseada em OAuth, ou seja, delegação de acesso. Assim, para nos autenticarmos vamos enviar o usuário para uma página do Google e, se ele autorizar a integração, seremos devolvidos de volta pra nossa aplicação com um access token que deveremos armazenar para uso posterior nas requests.

Assim, começamos declarando uma constante de escopo necessária para a autenticação, o caminho do arquivo de token onde vamos salvar o access token, o módulo fs para ler/escrever em arquivos, carregamos o arquivo de credenciais (que baixamos ao criar nosso projeto no painel do Google, lembra?) e o módulo da Google em Node.js.

Logo abaixo temos 3 funções, sendo que duas delas serão exportadas mais tarde, para uso na aplicação e a outra é para uso interno, a getOAuthClient, que nada mais faz do que instanciar um objeto oauth2Client com as credenciais geradas no painel do Google.

As outras duas funções, uma é para solicitar o acesso (getAuthorization) e a outra é para receber o Access Token depois do acesso concedido (getAccessToken).

A getAuthorization verifica se já temos um token de acesso. Se não tivermos, gera a URL para obter o access token e redireciona o usuário para lá. Se já tivermos, carrega junto das credenciais do nosso oauth2Client e o retorna, para usarmos nas demais funções.

Já o getAccessToken deve ser chamado no retorno da delegação de acesso, ele pega uma variável code que o Google nos envia na QueryString, gera o token a partir dela e o salva para uso posterior, chamando a getAuthorization que vai fazer o resto do trabalho.

Para ver se este nosso código está funcionando, vamos no nosso routes/index.js e vamos criar a rota de POST que vai receber o submit do formulário de autenticação que temos na nossa view.

Isso é o suficiente para, quando o usuário clicar no botão de Autorizar, ele será redirecionado para a página do Google para autorizar o uso do Google Drive dele.

Se você configurou sua aplicação corretamente no painel do Google, após a autorização ser concedida, o Google vai redirecionar o usuário de volta para a sua aplicação, com um monte de variáveis na query string. Então precisamos modificar o GET da rota raiz para pegar estas variáveis e finalizar a autenticação.

Com isso, se veio o code na querystring, chamamos a função de obter e armazenar o Access Token, caso contrário, tentamos obter a autorização a partir do token que já deve estar armazenado. Deste jeito, ao abrir a página inicial da aplicação, mesmo antes de clicar no botão de Autorizar, se a aplicação perceber a ausência do access token armazenado, já vai obrigar o usuário a se autenticar.

Note que alterei a lógica do res.render, para que a variável auth retorne true caso tenha conseguido carregar o objeto oauthClient corretamente.

Teste a aplicação agora, deve estar se autenticando corretamente. Repare que na raiz do seu projeto deve ter um arquivo token.json depois do acesso ter sido liberado. Também coloque esse arquivo no seu gitignore.

Curso FullStack
Curso FullStack

Upload de arquivos no Google Drive

Agora que já estamos conseguindo nos autenticar via OAuth no Google Drive do usuário, é hora de criar as funções de envio de arquivo no gdrive.js.

Esta função é bem direta e muito semelhante à que usamos na parte 1 deste tutorial, quando criamos aquela prova de conceito via console.

Começamos obtendo a autorização, depois um objeto de metadados do arquivo contendo o nome do arquivo (só o nome) e o ID da pasta dele no Google Drive.

Depois, criamos outro objeto para o arquivo em si, onde definimos seu mime-type (tipo de arquivo) e apontamos a stream de leitura para o caminho completo do arquivo, que deve estar no seu servidor antes de ser enviado para o Google Drive.

Por fim, carregamos um objeto google.drive com o nosso objeto oauthClient e chamamos a função drive.files.create para enviar o arquivo para o Google Drive do usuário, retornando o ID gerado pelo Google.

Note que esta função espera que nosso arquivo já esteja no servidor, ou seja, teremos de fazer upload do frontend para o backend e depois do backend para o Google Drive. Sendo assim, vamos voltar no routes/index.js e vamos criar a rota de POST de uma imagem, para testarmos este envio que é o mais simples dos 3.

Aqui, usamos o Formidable para pegar o formulário que foi enviado, separando o que é o arquivo que foi feito upload (files) dos campos do formulário (fields) e enviarmos estas informações para nosso módulo gdrive fazer o upload.

Como resultado, teremos o ID do arquivo gerado no Google Drive e com ele montamos uma URL pública para devolver pro front renderizar.

Isso deve permitir que, ao fazer upload da image, imediatamente ela será exibida no front end ao fim da request.

Note que o usuário vê esta imagem pois ele é dono dela, mas que se você quiser que outras pessoas também consigam ver ela, terá de tornar a pasta onde ela está armazenada, em uma pasta pública.

Outro ponto que vale mencionar é que a cópia do arquivo que ficou no nosso servidor vai ser apagada automaticamente depois de um tempo, pois por padrão o Formidable sobe os arquivos para a pasta temp do seu sistema operacional.

As rotas de POST para os vídeos e áudios funcionam da mesma forma e tenho certeza que você é capaz de criá-las. Caso tenha qualquer dificuldade, use o formulário ao final deste post para ter acesso ao código-fonte deste tutorial.

Um abraço e até a próxima!

Gostou deste tutorial? Quer aprender mais sobre construção de aplicações web em Node.js? Conheça o meu curso clicando no banner abaixo.

Curso Node.js e MongoDB
Curso Node.js e MongoDB

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, autor, Agile Coach e programador nas horas vagas.