Crea un conector de comunidad

Estos son los pasos para compilar un conector de comunidad:

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

Crea un nuevo proyecto de Apps Script

Visita Google Apps Script para crear un proyecto nuevo. Apps Script creará una secuencia de comandos predeterminada por ti. Puedes quitar la función myFunction y cambiarle el nombre al proyecto. (Más información sobre Apps Script)

Escribe el código del conector

Cada conector debe tener un conjunto específico de funciones definidas. La aplicación de hosting (p.ej., Data Studio) ejecutará estas funciones. Se espera que tu conector controle las solicitudes entrantes y responda como se describe en la referencia de la API de Community Connector. Si tienes problemas mientras desarrollas tu código, lee la guía de depuración para obtener ayuda.

Define el tipo de autenticación en getAuthType()

Se llama a esta función para identificar el método de autenticación que se usa para el servicio de terceros. Consulta la referencia de getAuthType() para obtener más detalles. Los métodos de autenticación compatibles actualmente se enumeran en la referencia de AuthType.

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 autenticación de OAuth 2.0, consulta la guía de autenticación de OAuth 2.0 y agrega las funciones adicionales requeridas a tu conector.

Define la configuración a través de getConfig()

Se llama a la función getConfig() para obtener la configuración del conector, incluidos los valores proporcionados por el usuario que requiere tu conector. Consulta la getConfig() referencia para obtener más detalles.

Según la respuesta proporcionada por getConfig(), Data Studio renderizará la pantalla de configuración del conector. Los elementos de configuración compatibles se enumeran en ConfigType referencia.

Si tu fuente de datos requiere una fecha como parámetro, llama a config.setDateRangeRequired(true). Si necesitas hacer preguntas de configuración condicionales o dinámicas consulta la configuración por pasos.

El siguiente es un ejemplo de un conector que requiere que el usuario ingrese un código de nombre de paquete npm. Se definen un campo de información y un campo de entrada en la función 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();
}

Define los campos con getSchema()

Se llama a esta función para obtener el esquema de la solicitud dada. Cualquier parámetro de configuración definido por la función getConfig() se proporcionará en el argumento request. Consulta la referencia de getSchema() para obtener más detalles.

Según la fuente de datos de tu conector y la configuración proporcionada por el usuario, el esquema puede ser fijo o es posible que debas proporcionarlo de forma dinámica en el momento de la solicitud.

Por ejemplo, si un conector recupera datos de informes según un ID de informe, es posible que los datos que se muestran para ese informe y, por lo tanto, el esquema no se conozcan de antemano. En este caso, getSchema() puede requerir una recuperación de datos, y se deberá calcular 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()};
}

Recupera y muestra datos con getData()

Se llama a esta función para obtener datos de la solicitud dada. Cualquier parámetro de configuración definido por la función getConfig() se proporcionará en el argumento request. Consulta la referencia de getData() para obtener más detalles.

Los siguientes parámetros de la solicitud getData() requieren atención adicional:

  • lastRefresh
    lastRefresh representa una marca de tiempo que indica la hora de la solicitud más reciente para actualizar los datos. Deberías poder analizar el valor con new Date(timestampString). Si usas el servicio de caché de Apps Script o cualquier otro método de almacenamiento en caché, la marca de tiempo lastRefresh puede ayudarte a determinar si debes realizar una nueva solicitud de recuperación a la fuente de datos o publicar datos desde la caché.

  • dateRange
    Si dateRangeRequired se establece en true en getConfig(), cada llamada getData() contendrá el período seleccionado en la solicitud. Consulta Cómo trabajar con períodos para obtener más detalles.

En el siguiente ejemplo, se recuperan datos según la solicitud entrante y se muestran 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;
}

Completa el manifiesto del proyecto

El archivo de manifiesto contiene información sobre tu conector de comunidad que es necesaria para implementar y usar tu conector en Data Studio.

Para editar 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. De esta forma, se creará un nuevo archivo de manifiesto appsscript.json.

Actualiza el manifiesto para incluir 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"
  ]
}

Para obtener detalles sobre el manifiesto de Data Studio, consulta la referencia del manifiesto.

Próximos pasos

El siguiente paso es implementar tu conector de comunidad.