Criar um conector da comunidade

Estas são as etapas para criar um conector da comunidade:

  1. Crie um novo projeto do Apps Script.
  2. Escreva o código do conector.
  3. Preencha o manifesto do projeto.

Criar um novo projeto do Apps Script

Acesse o Google Apps Script para criar um novo projeto. O Apps Script criará um script padrão para você. Você pode remover a função myFunction e renomear o projeto. Saiba mais sobre o Apps Script.

Escrever o código do conector

Todo conector precisa ter definido um conjunto específico de funções. O aplicativo de hospedagem (por exemplo, o Looker Studio) vai executar essas funções. Espera-se que seu conector cuide das solicitações recebidas e responda conforme descrito na Referência da API do conector da comunidade. Se você tiver problemas durante o desenvolvimento do seu código, leia o guia de depuração para receber ajuda.

Definir o tipo de autenticação em getAuthType()

Esta função é chamada para identificar o método de autenticação usado no serviço de terceiros. Veja a referência do getAuthType() para mais detalhes. Os métodos de autenticação compatíveis são exibidos na referência do AuthType.

Por exemplo, o conector a seguir não requer autenticação:

npm-downloads/src/auth.js
var cc = DataStudioApp.createCommunityConnector();

// https://developers.google.com/datastudio/connector/reference#getauthtype
function getAuthType() {
  var AuthTypes = cc.AuthType;
  return cc
    .newAuthTypeResponse()
    .setAuthType(AuthTypes.NONE)
    .build();
}

Se a sua fonte de dados precisar da autenticação do OAuth 2.0, consulte o guia de autenticação do OAuth 2.0 e adicione as outras funções necessárias ao seu conector.

Definir configuração pelo getConfig()

A função getConfig() é chamada para definir a configuração do conector, incluindo os valores informados pelo usuário que seu conector exige. Consulte a referência do getConfig() para mais detalhes.

Com base na resposta enviada por getConfig(), o Looker Studio renderiza a tela de configuração do conector. Os elementos de configuração compatíveis são exibidos na referência do ConfigType.

Se a sua fonte de dados precisar usar a data como parâmetro, chame config.setDateRangeRequired(true). Caso você tenha que fazer perguntas de configuração condicionais ou dinâmicas, veja a configuração por etapas.

Confira a seguir o exemplo de um conector que exige a inserção de um código do nome do pacote NPM pelo usuário. Uma informação e um campo de entrada são definidos na função getConfig():

npm-downloads/src/main.js
// https://developers.google.com/datastudio/connector/reference#getconfig
function getConfig() {
  var config = cc.getConfig();

  config
    .newInfo()
    .setId('instructions')
    .setText(
      'Enter npm package names to fetch their download count. An invalid or blank entry will revert to the default value.'
    );

  config
    .newTextInput()
    .setId('package')
    .setName(
      'Enter a single package name or multiple names separated by commas (no spaces!)'
    )
    .setHelpText('e.g. "googleapis" or "package,somepackage,anotherpackage"')
    .setPlaceholder(DEFAULT_PACKAGE)
    .setAllowOverride(true);

  config.setDateRangeRequired(true);

  return config.build();
}

Definir os campos com getSchema()

Essa função é chamada para definir o esquema da solicitação específica. Os parâmetros de configuração estabelecidos pela função getConfig() serão informados no argumento request. Consulte a referência do getSchema() para mais detalhes.

Dependendo da fonte de dados do seu conector e da configuração escolhida pelo usuário, o esquema poderá ser corrigido ou será necessário informá-lo dinamicamente no momento da solicitação.

Por exemplo, se um conector estiver buscando dados do relatório com base em um ID de relatório, os dados retornados para esse relatório e o esquema talvez não sejam conhecidos com antecedência. Nesse caso, getSchema() poderá exigir uma busca de dados, e o esquema terá que ser calculado.

npm-downloads/src/main.js
function getFields() {
  var fields = cc.getFields();
  var types = cc.FieldType;
  var aggregations = cc.AggregationType;

  fields
    .newDimension()
    .setId('packageName')
    .setName('Package')
    .setType(types.TEXT);

  fields
    .newDimension()
    .setId('day')
    .setName('Date')
    .setType(types.YEAR_MONTH_DAY);

  fields
    .newMetric()
    .setId('downloads')
    .setName('Downloads')
    .setType(types.NUMBER)
    .setAggregation(aggregations.SUM);

  return fields;
}

// https://developers.google.com/datastudio/connector/reference#getschema
function getSchema(request) {
  return {schema: getFields().build()};
}

Buscar e retornar dados com getData()

Essa função é chamada para ver dados da solicitação específica. Os parâmetros de configuração definidos pela função getConfig() serão informados no argumento request. Consulte a referência do getData() para mais detalhes.

Os seguintes parâmetros da solicitação getData() exigem atenção especial:

  • lastRefresh
    lastRefresh representa um carimbo de data/hora que marca o horário da solicitação mais recente de uma atualização de dados. Você pode analisar o valor com new Date(timestampString). Se estiver usando o serviço de cache do Apps Script ou qualquer outro método de armazenamento em cache, o carimbo de data/hora lastRefresh poderá ajudar a determinar se é necessário fazer uma nova solicitação de busca para a fonte de dados ou disponibilizar dados do cache.

  • dateRange
    Se dateRangeRequired for definido como true em getConfig(), cada chamada de getData() conterá o período selecionado na solicitação. Veja mais detalhes em Como trabalhar com períodos.

O exemplo a seguir busca os dados com base na solicitação recebida e retorna as estatísticas do pacote:

npm-downloads/src/main.js
// https://developers.google.com/datastudio/connector/reference#getdata
function getData(request) {
  request.configParams = validateConfig(request.configParams);

  var requestedFields = getFields().forIds(
    request.fields.map(function(field) {
      return field.name;
    })
  );

  try {
    var apiResponse = fetchDataFromApi(request);
    var normalizedResponse = normalizeResponse(request, apiResponse);
    var data = getFormattedData(normalizedResponse, requestedFields);
  } catch (e) {
    cc.newUserError()
      .setDebugText('Error fetching data from API. Exception details: ' + e)
      .setText(
        'The connector has encountered an unrecoverable error. Please try again later, or file an issue if this error persists.'
      )
      .throwException();
  }

  return {
    schema: requestedFields.build(),
    rows: data
  };
}

/**
 * Gets response for UrlFetchApp.
 *
 * @param {Object} request Data request parameters.
 * @returns {string} Response text for UrlFetchApp.
 */
function fetchDataFromApi(request) {
  var url = [
    'https://api.npmjs.org/downloads/range/',
    request.dateRange.startDate,
    ':',
    request.dateRange.endDate,
    '/',
    request.configParams.package
  ].join('');
  var response = UrlFetchApp.fetch(url);
  return response;
}

/**
 * Parses response string into an object. Also standardizes the object structure
 * for single vs multiple packages.
 *
 * @param {Object} request Data request parameters.
 * @param {string} responseString Response from the API.
 * @return {Object} Contains package names as keys and associated download count
 *     information(object) as values.
 */
function normalizeResponse(request, responseString) {
  var response = JSON.parse(responseString);
  var package_list = request.configParams.package.split(',');
  var mapped_response = {};

  if (package_list.length == 1) {
    mapped_response[package_list[0]] = response;
  } else {
    mapped_response = response;
  }

  return mapped_response;
}

/**
 * Formats the parsed response from external data source into correct tabular
 * format and returns only the requestedFields
 *
 * @param {Object} parsedResponse The response string from external data source
 *     parsed into an object in a standard format.
 * @param {Array} requestedFields The fields requested in the getData request.
 * @returns {Array} Array containing rows of data in key-value pairs for each
 *     field.
 */
function getFormattedData(response, requestedFields) {
  var data = [];
  Object.keys(response).map(function(packageName) {
    var package = response[packageName];
    var downloadData = package.downloads;
    var formattedData = downloadData.map(function(dailyDownload) {
      return formatData(requestedFields, packageName, dailyDownload);
    });
    data = data.concat(formattedData);
  });
  return data;
}

Preencher o manifesto do projeto

O arquivo de manifesto contém informações sobre o conector da comunidade que são necessárias para implantar e usar o conector no Looker Studio.

Se você quiser editar o arquivo de manifesto no ambiente de desenvolvimento do Apps Script, clique no menu Ver e em Mostrar arquivo de manifesto. Isso criará um novo arquivo appsscript.json.

Atualize o manifesto para incluir os seguintes dados:

npm-downloads/src/appsscript.json
{
  "dependencies": {
    "libraries": []
  },
  "dataStudio": {
    "name": "npm Downloads",
    "logoUrl": "https://raw.githubusercontent.com/npm/logos/master/npm%20square/n-64.png",
    "company": "Google Data Studio Developer Relations",
    "companyUrl": "https://developers.google.com/datastudio/",
    "addonUrl": "https://github.com/googledatastudio/community-connectors/tree/master/npm-downloads#readme",
    "supportUrl": "https://github.com/googledatastudio/community-connectors/issues",
    "description": "Get npm package download counts.",
    "sources": ["npm"],
    "templates": {
      "default": "1twu0sHjqR5dELAPyGJcw4GS3-D0_NTrQ"
    }
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

Saiba mais sobre o manifesto do Looker Studio na referência do manifesto.

Próximas etapas

A próxima etapa é implantar seu conector da comunidade.