sexta-feira, 14 de abril de 2017

Utilizando a API do Google Drive no C# e VB.NET - Parte 1

Por André Lima em 12/04/2017.

Hoje em dia é muito difícil encontrar algum aplicativo que não salve algum tipo de informação na nuvem. Com serviços como Dropbox, Google Drive e OneDrive ficando cada vez mais baratos e acessíveis, a nossa vida acaba sendo muito facilitada caso precisemos subir um arquivo para a nuvem a partir da nossa aplicação.
Para facilitar ainda mais a nossa vida, esses serviços sempre contam com APIs que podem ser acessadas nas mais diversas plataformas de desenvolvimento. O Google Drive, por exemplo, conta com uma API bem extensa, possibilitando a manipulação completa dos seus serviços a partir de aplicações de terceiros.
No artigo de hoje eu vou mostrar para você como fazer todo tipo de interação com o Google Drive no C# e VB.NET. Primeiramente nós veremos como habilitar a API do Google Drive na nossa conta e como gerar o arquivo de credenciais que é necessário para o seu acesso. Em seguida, nós aprenderemos todas as operações que podemos executar com a API: listagem, criação, exclusão e download de arquivos.

A API do Google Drive

O Google Drive conta com uma extensa API que possibilita a manipulação do conteúdo das suas contas em projetos que utilizem qualquer linguagem de programação com suporte a serviços REST. No momento da escrita deste artigo, a API está na sua terceira versão.
Se procurarmos na Internet por exemplos da manipulação do Google Drive com .NET, encontraremos uma boa quantidade de artigos que utilizam a segunda versão da API (como essa excelente série que eu utilizei de inspiração para escrever este artigo). Porém, se quisermos utilizar a versão mais nova da API (que já foi lançada há um bom tempo, no final de 2015), acabamos ficando na mão. Existem diversas diferenças entre a versão 2 e a versão 3 da API, que estão todas documentadas aqui.
A própria página da API conta com alguns exemplos em C# (como, por exemplo, este quickstart). Porém, esses exemplos são muito simples e com pouca explicação do que está sendo feito em cada etapa. Além disso, eles estão todos quebrados em funcionalidades, ou seja, nós não conseguimos encontrar um exemplo que aborde todas as principais interações que podemos fazer com o Google Drive através da nossa aplicação. Neste artigo eu vou juntar todas essas informações em um só lugar e vou explicar para você o que está sendo feito em cada etapa.

Gerando o arquivo com as credenciais

Antes de tentarmos desenvolver qualquer funcionalidade na nossa aplicação utilizando a API do Google Drive, nós precisamos habilitar o suporte à API na nossa conta e temos que gerar também um arquivo com as nossas credenciais. Se você ainda não tiver seguido esses passos com a sua conta, este é o link para o assistente.
O primeiro passo é muito simples. Nós só temos que concordar com os termos do serviço (obviamente, nós não temos outra escolha):
Ao concordarmos com os termos, a API será ativada na nossa conta e nós conseguiremos continuar com o próximo passo, que é a criação do nosso arquivo de credenciais:
Na próxima etapa, escolha a API do Google Drive e a opção “Other UI“, uma vez que nós criaremos uma aplicação console Windows:
Em seguida, nós temos a possibilidade de fazer uma configuração muito interessante para o arquivo de credenciais, que basicamente responde à seguinte pergunta: esse arquivo de credenciais dará acesso a todos os arquivos e pastas do Google Drive ou somente a arquivos e pastas gerados por essa aplicação específica? Escolha a opção que melhor se enquadra no cenário da sua aplicação e prossiga para a próxima etapa. No meu caso, eu escolhi a opção “User data“, que dá acesso a todos os arquivos e pastas da conta:
Agora chegou a hora de escolher um nome para o Client ID e produto. Além disso, caso a sua conta esteja conectada com outras contas do Google, você terá que selecionar o e-mail da conta que você quer utilizar:
Pronto! Finalmente chegamos na última etapa do assistente, onde conseguimos fazer o download do arquivo com as credenciais. Clique no botão “Download” e salve o arquivo “client_id.json” em um local que seja acessível pela aplicação:

Adicionando a referência da API no projeto

Para a nossa sorte, a própria Google implementou um conjunto de classes “helpers” em .NET que fazem o encapsulamento das chamadas da API de maneira mais amigável. Se essas classes não existissem, nós teríamos que fazer as chamadas manualmente através de requisições HTTP.
Esse conjunto de classes está publicado no NuGet com o nome “Google.Apis.Drive.v3“, ou seja, para adicionar a referência no nosso projeto basta procurarmos por esse termo na janela “NuGet Package Manager” ou podemos executar também o comando “Install-Package Google.Apis.Drive.v3” no “Package Manager Console“:
Para facilitar a nossa vida, os exemplos desse artigo serão construídos em um projeto do tipo “Console Application“. Porém, nada impede que você aplique os mesmos conceitos em outros tipos de projeto, como Windows Forms, WPF ou ASP.NET.

Autenticando e conectando no serviço

A primeira coisa que temos que fazer antes de acessarmos a API do Google Drive é nos autenticarmos utilizando aquele arquivo que geramos nas etapas anteriores. Dito isso, vamos criar um método que retornará uma instância da classe “UserCredential” da API do Google Drive. Esse método fará toda a “mágica” da autenticação sempre que precisarmos nos conectar na API.
Dentro desse método nós precisaremos informar três parâmetros importantes: uma stream apontando para o arquivo com as credenciais (“client_id.json” que geramos anteriormente), o escopo das permissões que serão dadas para execução de comandos na API e o caminho para uma pasta onde será armazenado o token da autenticação. Esse token servirá como um “cache” das nossas credenciais, evitando que tenhamos que digitar o nosso usuário e senha novamente todas as vezes que o aplicativo for executado.
Veja como fica o código desse método:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// C#
private static Google.Apis.Auth.OAuth2.UserCredential Autenticar()
{
    Google.Apis.Auth.OAuth2.UserCredential credenciais;
    using (var stream = new System.IO.FileStream("client_id.json", System.IO.FileMode.Open, System.IO.FileAccess.Read))
    {
        var diretorioAtual = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        var diretorioCredenciais = System.IO.Path.Combine(diretorioAtual, "credential");
        credenciais = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
            Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(stream).Secrets,
            new[] { Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly },
            "user",
            System.Threading.CancellationToken.None,
            new Google.Apis.Util.Store.FileDataStore(diretorioCredenciais, true)).Result;
    }
    return credenciais;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
' VB.NET
Private Function Autenticar() As Google.Apis.Auth.OAuth2.UserCredential
    Dim Credenciais As Google.Apis.Auth.OAuth2.UserCredential
    Using Stream = New System.IO.FileStream("client_id.json", System.IO.FileMode.Open, System.IO.FileAccess.Read)
        Dim DiretorioAtual = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
        Dim DiretorioCredenciais = System.IO.Path.Combine(DiretorioAtual, "credential")
        Credenciais = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
            Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(Stream).Secrets,
            New String() {Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly},
            "user",
            System.Threading.CancellationToken.None,
            New Google.Apis.Util.Store.FileDataStore(DiretorioCredenciais, True)).Result
    End Using
    Return Credenciais
End Function
À primeira vista esse código parece bem complicado. Porém, ele é mais simples do que parece. Primeiramente nós abrimos um FileStream somente leitura apontando para o arquivo “client_id.json“, que você terá que copiar para o diretório “bin/debug” do projeto. Em seguida, nós criamos uma variável que armazenará o caminho completo para um subdiretório da aplicação, chamado de “credential“. Esse é o diretório onde o token com as credenciais será armazenado. Por fim, nós fazemos a chamada ao método “GoogleWebAuthorizationBroker.AuthorizeAsync“, que deverá receber esses e outros parâmetros.
Note que a princípio estamos pedindo somente a permissão de leitura para a API (DriveReadonly). Ou seja, com essas permissões nós só conseguiremos listar as informações do nosso Google Drive. Mais para a frente nós veremos como essa permissão se comportará ao tentarmos escrever alguma alteração nos objetos da nossa conta.
Os parâmetros “user” e “CancellationToken.None” eu sinceramente não sei para que servem. Eu copiei essa chamada do exemplo oficial da própria Google e não consegui entender a utilidade desses parâmetros. Se alguém souber ou descobrir, avisa nos comentários.
Enfim, uma vez autenticado no serviço, nós temos que iniciar uma conexão. Para isso, nós temos que criar uma nova instância da classe “DriveService” passando um “Initializer” com as nossas credenciais. Entendeu? Pois é, eu sei que é complicado, então vamos ao código:
1
2
3
4
5
6
7
8
// C#
private static Google.Apis.Drive.v3.DriveService AbrirServico(Google.Apis.Auth.OAuth2.UserCredential credenciais)
{
    return new Google.Apis.Drive.v3.DriveService(new Google.Apis.Services.BaseClientService.Initializer()
    {
        HttpClientInitializer = credenciais
    });
}
1
2
3
4
5
6
' VB.NET
Private Function AbrirServico(Credenciais As Google.Apis.Auth.OAuth2.UserCredential) As Google.Apis.Drive.v3.DriveService
    Return New Google.Apis.Drive.v3.DriveService(New Google.Apis.Services.BaseClientService.Initializer() With {
        .HttpClientInitializer = Credenciais
    })
End Function
Bem mais simples do que quando eu tentei explicar, não é mesmo?
OK. Agora nós já temos o código que faz a autenticação e o código que abre uma conexão com a API do Google Drive. O próximo passo é implementar os métodos que farão a interação com o conteúdo do nosso repositório. Porém, qualquer interação que queiramos fazer com a API, nós precisaremos de uma instância da classe “DriveService” pronta para uso. Dessa forma, no local onde faremos as chamadas à API (por exemplo, o método “main” de um projeto console), nós criaremos um bloco “using” que fará a abertura do serviço:
1
2
3
4
5
6
// C#
var credenciais = Autenticar();
using (var servico = AbrirServico(credenciais))
{
}
1
2
3
4
5
6
' VB.NET
Dim Credenciais = Autenticar()
Using Servico = AbrirServico(Credenciais)
End Using
Como a classe “DriveService” implementa a interface “IDisposable“, ao colocarmos o código dentro de um bloco “using“, a conexão com a API será devidamente fechada e descartada assim que o bloco “using” for terminado, evitando que nós tenhamos que implementar código extra para fecharmos a conexão. Todo o código que fará a manipulação do nosso Google Drive deverá ser implementado dentro desse bloco “using“.

Listagem de arquivos

Com o serviço inicializado, vamos partir para a interação com os arquivos e pastas do nosso Google Drive. Primeiramente, vamos listar todo o conteúdo do nosso repositório?
Todos os métodos de interação do Google Drive estão implementados na propriedade “Files” da classe “DriveService“. Por exemplo, para criarmos um request que fará a listagem dos arquivos, nós teremos que chamar o método “servico.Files.List“. Essa mesma ideia servirá como base para os outros tipos de operações nas próximas seções deste artigo. Vamos ver como é que fica o código, dessa forma fica mais fácil de explicar:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// C#
private static void ListarArquivos(Google.Apis.Drive.v3.DriveService servico)
{
    var request = servico.Files.List();
    request.Fields = "files(id, name)";
    var resultado = request.Execute();
    var arquivos = resultado.Files;
    if (arquivos != null && arquivos.Any())
    {
        foreach (var arquivo in arquivos)
        {
            Console.WriteLine(arquivo.Name);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
' VB.NET
Private Sub ListarArquivos(Servico As Google.Apis.Drive.v3.DriveService)
    Dim Request = Servico.Files.List()
    Request.Fields = "files(id, name)"
    Dim Resultado = Request.Execute()
    Dim Arquivos = Resultado.Files
    If Arquivos IsNot Nothing AndAlso Arquivos.Any() Then
        For Each Arquivo In Arquivos
            Console.WriteLine(Arquivo.Name)
        Next
    End If
End Sub
Como você pode ver, primeiro nós criamos um request para o método de listagem de arquivos (“Files.List“). Em seguida, nós especificamos quais são os campos dos arquivos e pastas que devem ser retornados pelo request. Essa é uma grande diferença entre a segunda e a terceira versões da API. Pelo que eu entendi, na segunda versão, todos os campos eram retornados automaticamente. Já na terceira versão, nós precisamos especificar quais campos devem ser retornados, senão a API só retornará o ID dos arquivos e pastas.
Por fim, nós executamos o request e percorremos o resultado (que é uma lista de arquivos e pastas que estão armazenados no nosso Google Drive), imprimindo o nome dos itens. Vamos chamar esse método dentro do nosso bloco “using” para vermos o resultado:
1
2
3
4
5
// C#
Console.WriteLine("Listagem");
ListarArquivos(servico);
Console.WriteLine("Fim Listagem");
Console.ReadLine();
1
2
3
4
5
' VB.NET
Console.WriteLine("Listagem")
ListarArquivos(Servico)
Console.WriteLine("Fim Listagem")
Console.ReadLine()
Aparentemente tudo funcionou perfeitamente, não é mesmo? Porém, essa metodologia só retornará os 100 primeiros itens que forem encontrados no nosso Google Drive. Se quisermos que mais itens sejam retornados, temos que alterar a propriedade “PageSize” do nosso request antes de executá-lo. Por exemplo:
1
2
3
// C#
request.PageSize = 1000;
var resultado = request.Execute();
1
2
3
' VB.NET
Request.PageSize = 1000
Dim Resultado = Request.Execute()
O valor padrão dessa propriedade é “100“, e o máximo é “1000“. Se tentarmos utilizar um valor maior do que 1000, receberemos o seguinte erro:



Nenhum comentário:

Postar um comentário