Usar recursos da API Google Picker em apps da Web

Este documento explica como usar os recursos da API Google Picker, como ativar a seleção múltipla, ocultar o painel de navegação e escolher a conta de usuário com o token OAuth 2.0 atual do app.

Pré-requisitos

Para este exemplo, é necessário configurar o seguinte no seu projeto do Google Cloud:

  • Ativar as APIs: ative a API Google Picker e a API Google Drive:

    1. No console do Google Cloud, acesse Menu > APIs e serviços > Biblioteca.

      Acessar a biblioteca

    2. Pesquise e ative a API Google Picker e a API Google Drive.

  • Criar uma chave de API :

    1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

      Ir para Credenciais

    2. Clique em Criar credenciais > Chave de API.

    3. (Recomendado) Para proteger sua chave de API com restrições, clique Editar chave de API:

      • Restrições de aplicativo: em Definir uma restrição de aplicativo, selecione Sites. Em Restrições de site, adicione a origem do seu app (por exemplo, https://example.com/* ou http://localhost/*) e https://docs.google.com/* à lista de sites especificados. Como o Google Picker é renderizado em um iframe hospedado em docs.google.com, as solicitações falham com um API developer key is invalid erro se https://docs.google.com/* não for permitido.

      • Restrições de API: em Restrições de API, selecione Restringir chave e, em seguida, selecione a API Google Picker e a API Google Drive.

  • Criar um ID do cliente OAuth 2.0 :

    1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    2. Clique em Criar credenciais > ID do cliente OAuth.

    3. Selecione Aplicativo da Web e adicione as origens JavaScript autorizadas.

  • Localizar o ID do app :

    1. No console do Google Cloud, acesse Menu > IAM e administrador > Configurações.

      Acesse configurações

    2. Use o número do projeto para o ID do app.

O mesmo projeto na nuvem do Google Cloud precisa conter o ID do cliente e o ID do app, já que ele é usado para autorizar o acesso aos arquivos de um usuário.

Criar um app seletor de imagens em um documento HTML

O exemplo de código a seguir mostra como usar um seletor de imagens ou uma página de upload que os usuários podem abrir em um botão em um app da Web.

Crie um documento HTML padrão para hospedar o Google Picker:

<!DOCTYPE html>
<html>
<head>
  <title>Google Picker API Quickstart</title>
  <meta charset="utf-8" />
</head>
<body>
<p>Google Picker API Quickstart</p>

<!--Add buttons to initiate auth sequence and sign out.-->
<button id="authorize_button" onclick="handleAuthClick()">Authorize</button>
<button id="signout_button" onclick="handleSignoutClick()">Sign Out</button>

<pre id="content" style="white-space: pre-wrap;"></pre>

Use JavaScript para chamar a API Google Picker:

<script type="text/javascript">
  /* exported gapiLoaded */
  /* exported gisLoaded */
  /* exported handleAuthClick */
  /* exported handleSignoutClick */

  // Authorization scopes required by the API; multiple scopes can be
  // included, separated by spaces.
  const SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';

  // Replace with your client ID and API key from https://console.cloud.google.com/.
  const CLIENT_ID = 'CLIENT_ID';
  const API_KEY = 'API_KEY';

  // Replace with your project number from https://console.cloud.google.com/.
  const APP_ID = 'APP_ID';

  let tokenClient;
  let accessToken = null;
  let pickerInited = false;
  let gisInited = false;

  document.getElementById('authorize_button').style.visibility = 'hidden';
  document.getElementById('signout_button').style.visibility = 'hidden';

  /**
   * Callback after api.js is loaded.
   */
  function gapiLoaded() {
    gapi.load('client:picker', initializePicker);
  }

  /**
   * Callback after the API client is loaded. Loads the
   * discovery doc to initialize the API.
   */
  async function initializePicker() {
    await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');
    pickerInited = true;
    maybeEnableButtons();
  }

  /**
   * Callback after Google Identity Services are loaded.
   */
  function gisLoaded() {
    tokenClient = google.accounts.oauth2.initTokenClient({
      client_id: CLIENT_ID,
      scope: SCOPES,
      callback: '', // defined later
    });
    gisInited = true;
    maybeEnableButtons();
  }

  /**
   * Enables user interaction after all libraries are loaded.
   */
  function maybeEnableButtons() {
    if (pickerInited && gisInited) {
      document.getElementById('authorize_button').style.visibility = 'visible';
    }
  }

  /**
   *  Sign in the user upon button click.
   */
  function handleAuthClick() {
    tokenClient.callback = async (response) => {
      if (response.error !== undefined) {
        throw (response);
      }
      accessToken = response.access_token;
      document.getElementById('signout_button').style.visibility = 'visible';
      document.getElementById('authorize_button').innerText = 'Refresh';
      await createPicker();
    };

    if (accessToken === null) {
      // Prompt the user to select a Google Account and ask for consent to share their data
      // when establishing a new session.
      tokenClient.requestAccessToken({prompt: 'consent'});
    } else {
      // Skip display of account chooser and consent dialog for an existing session.
      tokenClient.requestAccessToken({prompt: ''});
    }
  }

  /**
   *  Sign out the user upon button click.
   */
  function handleSignoutClick() {
    if (accessToken) {
      google.accounts.oauth2.revoke(accessToken);
      accessToken = null;
      document.getElementById('content').innerText = '';
      document.getElementById('authorize_button').innerText = 'Authorize';
      document.getElementById('signout_button').style.visibility = 'hidden';
    }
  }

  /**
   *  Create and render a Google Picker object for searching images.
   */
  function createPicker() {
    const view = new google.picker.View(google.picker.ViewId.DOCS);
    view.setMimeTypes('image/png,image/jpeg,image/jpg');
    const picker = new google.picker.PickerBuilder()
        .enableFeature(google.picker.Feature.NAV_HIDDEN)
        .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
        .setDeveloperKey(API_KEY)
        .setAppId(APP_ID)
        .setOAuthToken(accessToken)
        .addView(view)
        .addView(new google.picker.DocsUploadView())
        .setCallback(pickerCallback)
        .build();
    picker.setVisible(true);
  }

  /**
   * Displays the file details of the user's selection.
   * @param {object} data - Contains the user selection from the Google Picker.
   */
  async function pickerCallback(data) {
    if (data.action === google.picker.Action.PICKED) {
      let text = `Google Picker response: \n${JSON.stringify(data, null, 2)}\n`;
      const selectedDoc = data[google.picker.Response.DOCUMENTS][0];
      const fileId = selectedDoc[google.picker.Document.ID];
      console.log(fileId);
      const res = await gapi.client.drive.files.get({
        'fileId': fileId,
        'fields': '*',
      });
      text += `Drive API response for first document: \n${JSON.stringify(res.result, null, 2)}\n`;
      window.document.getElementById('content').innerText = text;
    }
  }
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>

Substitua:

A função setOAuthToken permite que um app use o token de autenticação atual para determinar qual Conta do Google o Google Picker usa para mostrar os arquivos. Se um usuário fizer login com várias Contas do Google, o Google Picker poderá mostrar os arquivos da conta autorizada apropriada.

Feche o documento HTML:

</body>
</html>

Depois de receber o ID do arquivo do Google Picker ao abrir arquivos, um app pode buscar os metadados do arquivo e fazer o download do conteúdo do arquivo, conforme descrito no método get do recurso files.

Criar um objeto seletor de imagens

O exemplo de código a seguir mostra a lógica principal para criar, renderizar e processar a API Google Picker para criar um seletor de imagens.

Use JavaScript para chamar a API Google Picker:

/**
 * Create and render a Google Picker object for searching images.
 */
function createPicker() {
  // Define what types of files the Picker should show (e.g., images)
  const view = new google.picker.View(google.picker.ViewId.DOCS);
  view.setMimeTypes('image/png,image/jpeg,image/jpg');

  // Build and display the picker.
  const picker = new google.picker.PickerBuilder()
      .enableFeature(google.picker.Feature.NAV_HIDDEN)
      .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
      .setDeveloperKey('API_KEY')
      .setAppId('APP_ID')
      .setOAuthToken('ACCESS_TOKEN')
      .addView(view)
      .addView(new google.picker.DocsUploadView()) // Adds an upload tab
      .setCallback(pickerCallback)
      .build();

  picker.setVisible(true);
}

/**
 * Displays the file details of the user's selection.
 * @param {object} data - Contains the user selection from the Google Picker.
 */
async function pickerCallback(data) {
  if (data.action === google.picker.Action.PICKED) {
    let text = `Google Picker response: \n${JSON.stringify(data, null, 2)}\n`;

    // Extract the ID of the first selected document.
    const selectedDoc = data[google.picker.Response.DOCUMENTS][0];
    const fileId = selectedDoc[google.picker.Document.ID];
    console.log("Selected File ID:", fileId);

    // Optional: Fetch metadata using the Drive API based on the selected file ID.
    const res = await gapi.client.drive.files.get({
      'fileId': fileId,
      'fields': '*',
    });

    text += `Drive API response for first document: \n${JSON.stringify(res.result, null, 2)}\n`;
    // Update your UI with the results
    console.log(text);
  }
}

Substitua: