Создайте соединитель сообщества

Шаги по созданию Community Connector:

  1. Создайте новый проект Apps Script.
  2. Напишите код соединителя.
  3. Заполните манифест проекта.

Создайте новый проект Apps Script

Откройте Google Apps Script , чтобы создать новый проект. Apps Script создаст для вас скрипт по умолчанию. Вы можете удалить функцию myFunction и переименовать проект. ( Подробнее об Apps Script ).

Напишите код соединителя

Для каждого коннектора должен быть определён определённый набор функций. Эти функции будет выполнять приложение хостинга (например, Looker Studio). Ваш коннектор должен обрабатывать входящие запросы и отвечать, как описано в справочнике по API коннектора сообщества . Если при разработке кода у вас возникнут проблемы, обратитесь к руководству по отладке .

Определить тип аутентификации в getAuthType()

Эта функция вызывается для определения метода аутентификации, используемого для стороннего сервиса. Подробности см. в справочнике getAuthType() . Поддерживаемые в настоящее время методы аутентификации перечислены в справочнике AuthType .

Например, следующий коннектор не требует аутентификации:

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

Если для вашего источника данных требуется аутентификация OAuth 2.0, ознакомьтесь с руководством по аутентификации OAuth 2.0 и добавьте необходимые дополнительные функции в ваш коннектор.

Определить конфигурацию через getConfig()

Функция getConfig() вызывается для получения конфигурации коннектора, включая предоставленные пользователем значения, необходимые для вашего коннектора. Подробности см. в справочнике по getConfig() .

На основе ответа getConfig() Looker Studio отобразит экран конфигурации коннектора. Поддерживаемые элементы конфигурации перечислены в справочнике ConfigType .

Если ваш источник данных требует дату в качестве параметра, вызовите config.setDateRangeRequired(true) . Если вам нужно задать вопросы об условной или динамической конфигурации, см. пошаговую настройку .

Ниже приведён пример коннектора, требующего от пользователя ввода кода имени пакета npm. Информация и поле ввода определены в функции 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();
}

Определите поля с помощью getSchema()

Эта функция вызывается для получения схемы для данного запроса. Все параметры конфигурации, определённые функцией getConfig() будут переданы в аргументе request . Подробнее см. в справочнике getSchema() .

В зависимости от источника данных вашего коннектора и конфигурации, предоставленной пользователем, схема может быть фиксированной или вам, возможно, придется предоставлять ее динамически во время запроса.

Например, если коннектор извлекает данные отчёта на основе идентификатора отчёта, возвращаемые данные для этого отчёта, а следовательно, и схема, могут быть заранее неизвестны. В этом случае getSchema() может потребовать извлечения данных, и схему придётся рассчитать.

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

Извлечение и возврат данных с помощью getData()

Эта функция вызывается для получения данных по заданному запросу. Все параметры конфигурации, заданные функцией getConfig() будут переданы в аргументе request . Подробнее см. в справочнике getData() .

Следующие параметры запроса getData() требуют дополнительного внимания:

  • lastRefresh
    lastRefresh представляет собой временную метку, отмечающую время последнего запроса на обновление данных. Вы можете проанализировать это значение с помощью new Date(timestampString) . Если вы используете Apps Script Cache Service или любой другой метод кэширования, временная метка lastRefresh может помочь вам определить, следует ли выполнять новый запрос к источнику данных или использовать данные из кэша.

  • dateRange
    Если в getConfig() dateRangeRequired установлен в true , каждый вызов getData() будет содержать выбранный диапазон дат в запросе. Подробнее см. в разделе Работа с диапазонами дат .

Следующий пример извлекает данные на основе входящего запроса и возвращает статистику пакета:

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

Заполните манифест проекта

Файл манифеста содержит информацию о вашем коннекторе сообщества, необходимую для развертывания и использования вашего коннектора в Looker Studio.

Чтобы отредактировать файл манифеста в среде разработки Apps Script, выберите меню «Вид» и выберите «Показать файл манифеста» . Это создаст новый файл манифеста appsscript.json .

Обновите манифест, включив в него следующие данные:

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

Подробную информацию о манифесте Looker Studio см. в справочнике по манифесту .

Следующие шаги

Следующим шагом будет развертывание вашего Community Connector .