Integrando sua aplicação com DropBox

Integrar sua aplicação com o dropbox para salvar arquivos na nuvem é super fácil.

Existem diversas formas de armazenar arquivos manipulados pela sua aplicação, o mais comum é o tradicional upload para o filesystem de sua aplicação, mas existem outras formas com suas vantagens e desvantagens, como por exemplo, o Amazon S3 da Amazon AWS, que uso frequentemente em meus projetos devido a facilidade de integração, performance e sinergia entre outros servicos da AWS.

Como a vida de desenvolvedor traz uma novidade a cada dia, recentemente um dos meus clientes precisou gravar arquivos em uma conta do dropbox, ele utilizava esse repositório internamente para acesso a imagens importantes do seu negocio, só que agora elas precisavam ser enviadas a partir de um formulário na web.

Para quem não conhece ou passou os últimos 10 anos numa peregrinação ao nepal, dropbox é um serviço de armazenamento e compartilhamento de arquivos na nuvem, semelhante ao google drive.

Como já estamos contextualizados, é hora de fazer a alegria do nosso cliente e se aventurar no dropbox.

Criando seu APP no dropbox

O primeiro passo para realizar a integração é criar um app do dropbox utilizando a sua conta. O conceito de app no dropbox é similar aos aplicativos do facebook, é através dele que você poderá utilizar os recursos de desenvolvimento e fazer a integração com a plataforma.

Para começar, acesse a página de desenvolvedores do dropbox. Caso não esteja logado, na sua conta do dropbox, efetue o login no canto superior direito.

Na pagina acima, você pode clicar no link Create Your App, ou clicar em My Apps no menu a esquerda e selecionar a mesma opção. Será apresentada a tela abaixo


No nosso caso, vamos utilizar a API padrão, que ao contrário da API Business, não precisa de uma conta paga. Selecione também o tipo de acesso para completo, para que o APP possa ter acesso livre a pastas e arquivos dentro da conta.

A versão do dropbox for business possui diversos recursos extras como versionamento, dashboard, gerenciamento de times e outros. Talvez para o seu caso seja a melhor opção. Caso queira conhecer um pouco mais, segue o link: https://www.dropbox.com/business/tour

Apos a criação do app, você será direcionado para a tela de configuração dele. Você só precisa se preocupar com uma única informação nesta tela,
Generated access token.

Clique em Generate e guarde o token de acesso, ele será utilizado para acessar a API do dropbox.

Chamando a API através do seu APP

Como vocês podem ver, no menu a esquerda da pagina de desenvolvedores do dropbox, existe um item para documentação e abaixo dele existem diversas opções de linguagem como .NET, Java e Python. Claro que se você desenvolve em uma dessas linguagens, o caminho natural é utilizar a SDK para fazer a integração, mas não é o nosso caso.

Alem das linguagens descritas, existe a opção HTTP, que vai funcionar para qualquer linguagem que consiga fazer uma requisição ao protocolo, inclusive para o seu caso, mesmo que utilize uma linguagem que possui SDK própria.

Postman

Vamos fazer um teste inicial com a API e para isso, vamos utilizar um aplicativo que funciona como um cliente para chamadas REST e que uso frequentemente para organizar as chamadas a API de diversos projetos, o POSTMAN.

Se você não está familiarizado com esta ferramenta, sugiro que de uma boa olhada, pois todas as integrações que realizo no meu dia a dia, seja como cliente ou como servidor, são organizadas por este APP, é uma mão na roda, muito bom mesmo!.

Caso queira acelerar um pouco, todas as chamadas através do postman que vamos fazer neste artigo, estão disponíveis no repositório git. Importe a coleção e todas as requisições já estarão prontas para execução.

Authorization

Para todas as chamadas as API que vamos fazer, será utilizado o mesmo método de autenticação, que é o bearer token. O token deve ser enviado no header da requisição com o nome Authorization e com o valor “Bearer” + ESPAÇO + access_token. Veja o exemplo abaixo:

Criando Pastas

A primeira chamada é um teste simples para ver se a integração com a API está funcionando corretamente, vamos criar uma pasta na conta do dropbox onde o app foi criado.

Abaixo está a conta no dropbox sem nenhum arquivo ou pasta criado

Vamos então chamar a API create_folder para criar a pasta Teste/Imagens.

Endpoint: https://api.dropboxapi.com/2/files/create_folder_v2
Method: POST
Content-Type: application/json
Body:  {“path”: “/Teste/Imagens”, “autorename”: false }

Veja o resultado abaixo no postman

O retorno 200 indica o sucesso na criação da pasta e temos também algumas informações retornadas pela API no formato JSON. Abaixo temos a pasta criada no dropbox

Enviando Arquivo

O passo anterior foi apenas um teste de integração e para o meu caso, não vi muita utilidade no uso da API, pois ao criar arquivo, podemos criar a pasta ao mesmo tempo

vamos então enviar nosso arquivo ao dropbox através das API.

Endpoint: https://content.dropboxapi.com/2/files/upload
Method: POST
Content-Type:  application/octet-stream
Body:  [binary data]

Para fazer uma requisição no postman enviando um arquivo no formato binário (mais na frente falamos um pouco sobre isso), clique em Body, binary e selecione o arquivo desejado.

Veja o resultado da execução no postman

Novamente, o retorno 200 indica o sucesso na requisição e temos informações importantes retornadas pela API, como o hash do arquivo, que permite que seja verificada sua integridade.

Se vocês perceberam, no header desta requisição temos o campo
Dropbox-API-Arg. É nele que informamos os dados sobre o arquivo que estamos carregando. O valor deste campo deve ser apresentado no formato json, conforme o que enviamos na imagem:

{
"path":"/codechain/logo.png",
"mode":"add",
"autorename":true,
"mute":false
}

Cada um dos campos acima descrevem o comportamento da API ao receber o arquivo:

path

Caminho e nome do arquivo que será armazenado. Este será o nome do arquivo gravado no dropbox independente do nome do arquivo utilizado para upload.

mode

pode ser add ou overwrite. Caso seja add, não vai sobrescrever o arquivo no dropbox caso ocorra um conflito e sim, renomeá-lo.

autorename

indica que caso ocorra algum conflito, o dropbox vai tentar renomear o arquivo. O valor padrão é false para este campo

mute

O usuário da conta do dropbox recebe uma notificação sempre que um arquivo da sua conta é modificado, quando este campo informa true, indica que essa notificação não será enviada. O valor padrão é false.

Embora o coração da integração seja o upload de arquivos, existem diversos outros endpoints pra manipular todo tipo de informação no dropbox. Para visualizar os detalhes de toda a aAPI, assim como todos os possíveis campos e valores, acesse a documentação oficial.

Construindo nossa aplicação de teste

Com nosso teste de viabilidade já consolidado, vamos criar um backend em java utilizando spring boot, que vai enviar os arquivos recebidos através de um webservice, para o dropbox.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package br.com.triscal.ia.xp.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import br.com.triscal.ia.xp.service.DropBoxService;

@RestController
@RequestMapping("/dropbox")
public class DropboxController {

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE})
public String uploadFile(@RequestParam("file") MultipartFile file, @RequestHeader("Dropbox-API-Arg") final String dropboxAPIArg) {

    try {

        URL url = new URL("https://content.dropboxapi.com/2/files/upload");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);

        conn.setDoOutput(true);
        conn.setConnectTimeout(60000);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer zm-nQGAKfMAAAAAAAAAQdHTuOmPJU6DixkWUcwhY3MxqmAY02qqU6M5QWNuHxcJ8");
        conn.setRequestProperty("Dropbox-API-Arg", dropboxAPIArg);
        conn.setRequestProperty("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE);

        conn.connect();
        conn.getOutputStream().write(file.getBytes());
        conn.getOutputStream().flush();

        int status = conn.getResponseCode();

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line+"\n");
        }
        br.close();
        return sb.toString();

    } catch (Exception e) {
        return null;
    }
}

}

O código acima utiliza as bibliotecas nativas do java e faz a chamada a API do dropbox da forma mais simples possível, sem utilizar nenhum componente de framework.

A parte mais importante no código é a seguinte:

1
conn.getOutputStream().write(file.getBytes());

É comum construirmos serviços que consomem multipart/form-data, pois alem do arquivo, recebemos outras informações do formulário. Para o caso do dropbox, o serviço espera um único arquivo enviado ao payload da requisição, neste caso estamos falando de um outro content-type, o application/octet-stream e é exatamente nesta linha que fazemos isso. Copiamos todos os bytes do arquivo recebido no backend para o outputstream da requisição que vamos enviar ao dropbox.

Este backend é facilmente adaptado para qualquer outra linguagem. No meu caso tive que adaptar este código para o apex, linguagem de programação utilizado pelo salesforce, veja como ficou o código final

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Envia um arquivo para o dropbox
* token: access token da conta do dropbox que o arquivo será gravado
* nomeArquivo: path e nome do arquivo que será salvo no dropbox. Exemplo: "/pasta/file.txt"
* file: arquivo no formato blob para ser gravado no dropbox
* */

public void Upload(String token, String nomeArquivo, Blob file)
{
system.debug('Upload Dropbox Iniciado');
system.debug('token:' + token);
system.debug('nomeArquivo:' + nomeArquivo);

     HttpRequest req = new HttpRequest();
     req.setEndpoint(urlDropBoxApi);
     req.setMethod('POST');

    String authorizationHeader = 'Bearer ' + token;
    req.setHeader('Authorization', authorizationHeader);

    String dropboxAPIArg = generateDropBoxJson(nomeArquivo);
    req.setHeader('Dropbox-API-Arg', dropboxAPIArg);

    String contentType = 'application/octet-stream';
    req.setHeader('Content-Type', contentType);

    req.setBodyAsBlob(file);

      Http http = new Http();
    HTTPResponse res = http.send(req);
    System.debug(res.getBody());
}

Agora vamos testar nosso backend utilizando o postman novamente. Informe no header o atributo Dropbox-API-Arg e o content-type para uma chamada de form do tipo multipart/form-data (o backend recebe multipart/form-data e passa o dropbox, que recebe octet-stream).

selecione em seguida o arquivo que deseja enviar e pronto! Seu arquivo no dropbox.

Com isso encerramos esse artigo sobre integração com o dropbox. Se voce olhar a documentação, existem outras formas de autenticação para que você possa trabalhar com as contas de cada usuário e diversas outras opções, mas daqui pra frente é por sua conta 🙂


todo o material utilizado esta disponível no repositório git abaixo:

https://gitlab.com/cateno/codechain

Sobre Cateno Viglio Junior 19 Artigos
Carioca, arquiteto de software e entusiasta de tecnologia. Trabalho com java a 15 anos e atualmente coordeno uma área de inovação numa empresa do Rio de Janeiro. Sou fundador do codechain e participo de outras iniciativas por ai :).

Seja o primeiro a comentar

Faça um comentário

Seu e-mail não será divulgado.


*