Crear conectores comunitarios

Si quieres crear un conector comunitario, sigue estos pasos:

  1. Crea un proyecto de Apps Script.
  2. Escribe el código del conector.
  3. Completa el archivo de manifiesto del proyecto.

Crear un proyecto de Apps Script

Accede a Google Apps Script para crear un proyecto. Apps Script creará una secuencia de comandos predeterminada. Puedes quitar la función myFunction y cambiar el nombre del proyecto. Más información sobre Apps Script

Escribir el código de los conectores

Todos los conectores deben tener un conjunto específico de funciones que ejecutará la aplicación de alojamiento (por ejemplo, Data Studio). Tu conector debería gestionar las solicitudes que recibe y responderlas tal y como se describe en la referencia de la API de conectores comunitarios. Si a la hora de desarrollar el código te surge algún problema, consulta la ayuda que se ofrece en la guía para depurar código.

Definir los tipos de autenticación en getAuthType()

Se llama a esta función para identificar el método de autenticación que se utiliza con el servicio de terceros. Consulta más información en la referencia de getAuthType(). En la referencia de AuthType se indican los métodos de autenticación compatibles.

Por ejemplo, el siguiente conector no requiere autenticación:

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();
}

Si tu fuente de datos requiere la autenticación mediante OAuth 2.0, consulta la guía de autenticación con OAuth 2.0 y añade las funciones adicionales necesarias al conector.

Definir la configuración mediante getConfig()

Se llama a la función getConfig() para obtener la configuración del conector, incluidos los valores que este necesita y que proporcionan los usuarios. Consulta más información en la referencia de getConfig().

Data Studio mostrará la pantalla de configuración del conector en función de la respuesta que proporcione getConfig(). En la referencia de ConfigType se enumeran los elementos de configuración admitidos.

Si la fuente de datos requiere una fecha como parámetro, llama a config.setDateRangeRequired(true). Si tienes que hacer preguntas sobre la configuración condicional o dinámica, consulta el artículo sobre la configuración escalonada.

En el siguiente ejemplo, el conector exige que el usuario escriba un código de nombre de paquete de NPM. En la función getConfig() se definen un campo de información y un campo de entrada:

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 los campos con getSchema()

Se llama a esta función para obtener el esquema de la solicitud especificada. Los parámetros de configuración que se hayan definido con la función getConfig() se incluirán en el argumento request. Consulta más información en la referencia de getSchema().

En función de la fuente de datos del conector y de la configuración que haya indicado el usuario, el esquema se podrá corregir o tendrás que proporcionarlo de forma dinámica en el momento de la solicitud.

Por ejemplo, si un conector obtiene datos de un informe en función de un ID de informe, es posible que los datos que se devuelvan del informe y, por lo tanto, del esquema, se desconozcan de antemano. En ese caso, la función getSchema() podría exigir la obtención de datos, por lo que tendría que calcularse el esquema.

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()};
}

Obtener y devolver datos con getData()

Se llama a esta función para obtener los datos de la solicitud especificada. Los parámetros de configuración que se hayan definido con la función getConfig() se incluirán en el argumento request. Consulta más información en la referencia de getData().

Presta especial atención a los siguientes parámetros de la solicitud getData():

  • lastRefresh
    lastRefresh representa la fecha y hora de la última vez que se ha solicitado actualizar los datos. Deberías poder analizar el valor con new Date(timestampString). Si utilizas el servicio de almacenamiento en caché de Apps Script o cualquier otro método para almacenar datos en la memoria caché, a partir de la fecha y hora que indica lastRefresh puedes decidir si enviar una nueva solicitud de obtención de datos a la fuente de datos o servir datos desde la memoria caché.

  • dateRange
    Si a dateRangeRequired se le asigna el valor true en getConfig(), cada llamada a getData() incluirá el periodo seleccionado en la solicitud. Consulta más información en la sección Filtrar por periodo.

En el siguiente ejemplo se obtienen datos en función de la solicitud que se ha recibido y se devuelven las estadísticas del paquete:

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;
}

Completar el archivo de manifiesto del proyecto

En el archivo de manifiesto debes incluir la información del conector comunitario necesaria para implementarlo y usarlo en Data Studio.

Para modificar el archivo de manifiesto en el entorno de desarrollo de Apps Script, haz clic en el menú Ver y luego en Mostrar archivo de manifiesto. Se creará un archivo de manifiesto appsscript.json.

Modifica el archivo de manifiesto para que incluya los siguientes datos:

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"
  ]
}

Si quieres saber más sobre el archivo de manifiesto de Data Studio, consulta la referencia del archivo de manifiesto.

Conectores comunitarios de código abierto

En el artículo Conectores comunitarios de código abierto encontrarás más código de ejemplo. Los ejemplos ilustran varios casos prácticos e incluyen prácticas recomendadas para desarrollar conectores comunitarios.

Pasos siguientes

El siguiente paso es implementar el conector comunitario.