Crea un conector de comunidad

Los pasos para crear un conector de comunidad son los siguientes:

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

Cree 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 definido un conjunto específico de funciones. La aplicación de hosting (p.ej., Looker Studio) ejecutará estas funciones. Se espera que tu conector maneje 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. Para obtener más información, consulta la referencia de getAuthType(). Los métodos de autenticación admitidos 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 OAuth 2.0, consulta la guía de autenticación de OAuth 2.0 y agrega las funciones adicionales requeridas al conector.

Define la configuración mediante getConfig()

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

En función de la respuesta que proporcione getConfig(), Looker Studio renderizará la pantalla de configuración del conector. Los elementos de configuración admitidos se enumeran en la referencia de ConfigType.

Si tu fuente de datos requiere la fecha como parámetro, llama a config.setDateRangeRequired(true). Si necesitas hacer preguntas de configuración condicional o dinámica, consulta la configuración escalonada.

El siguiente es un ejemplo de un conector que requiere que el usuario ingrese un código de nombre de paquete de npm. En la función getConfig(), se definen una 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();
}
.

Cómo definir los campos con getSchema()

Se llama a esta función a fin de obtener el esquema para la solicitud determinada. Cualquier parámetro de configuración definido por la función getConfig() se proporcionará en el argumento request. Para obtener más información, consulta la referencia de getSchema().

Según la fuente de datos de tu conector y la configuración que proporcione el usuario, el esquema puede quedar 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 informe en función de 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 los datos de la solicitud dada. Todos los parámetros de configuración definidos por la función getConfig() se proporcionarán en el argumento request. Para obtener más información, consulta la referencia de getData().

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 una actualización de 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 entregar datos desde la caché.

  • dateRange
    Si dateRangeRequired se configura como 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 el conector de la comunidad que se requiere para implementar y usar el conector en Looker 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. 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 Looker Studio, consulta la referencia del manifiesto.

Próximos pasos

El siguiente paso será implementar el conector de la comunidad.