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 no Apps Script

Visite 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 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 Data Studio) 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 seguinte conector 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 fornecidos pelo usuário que seu conector exige. Consulte a referência do getConfig() para mais detalhes.

Com base na resposta fornecida por getConfig(), o Data Studio renderizará 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 de data como parâmetro, chame config.setDateRangeRequired (true). Se você tiver 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 fornecidos 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 de 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 fornecidos 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ê poderá 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 ajudará a determinar se é necessário fazer uma nova solicitação de busca para a fonte de dados ou disponibilizar informações do cache.

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

O seguinte exemplo 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 seu conector da comunidade que são necessárias para implantar e usar o conector no Data Studio.

Se você quiser editar o arquivo de manifesto no ambiente para desenvolvedores 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"
  ]
}

Para ver detalhes sobre o manifesto do Data Studio, consulte a referência do manifesto.

Conectores da comunidade de código aberto

Você pode explorar os conectores da comunidade de código aberto para ver outro código de exemplo. Os exemplos destacam vários casos de uso e as práticas recomendadas para o desenvolvimento do conector da comunidade.

Próximas etapas

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