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

Шаги по созданию соединителя сообщества:

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

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

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

Напишите код разъема

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

Определите тип аутентификации в 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) . Если вы используете службу кэширования сценариев приложений или любой другой метод кэширования, временная метка lastRefresh может помочь вам определить, следует ли сделать новый запрос на выборку к источнику данных или предоставить данные из кэша.

  • dateRange
    Если для dateRangeRequired в getConfig() установлено значение 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 .