Xây dựng trình kết nối cộng đồng

Các bước xây dựng Trình kết nối cộng đồng là:

  1. Tạo một dự án Apps Script mới.
  2. Viết mã trình kết nối.
  3. Hoàn tất tệp kê khai dự án.

Tạo một dự án Apps Script mới

Truy cập vào Google Apps Script để tạo dự án mới. Apps Script sẽ tạo một tập lệnh mặc định cho bạn. Vui lòng xoá hàm myFunction và đổi tên dự án. (Tìm hiểu thêm về Apps Script)

Viết mã trình kết nối

Mỗi trình kết nối cần phải xác định một tập hợp hàm cụ thể. Ứng dụng lưu trữ (ví dụ: Looker Studio) sẽ thực thi các hàm này. Trình kết nối của bạn dự kiến sẽ xử lý các yêu cầu đến và phản hồi như mô tả trong Tài liệu tham khảo API Trình kết nối cộng đồng. Nếu bạn gặp vấn đề trong khi phát triển mã, hãy đọc hướng dẫn gỡ lỗi để được trợ giúp.

Xác định loại xác thực trong getAuthType()

Hàm này được gọi để xác định phương thức xác thực dùng cho dịch vụ của bên thứ ba. Hãy xem tài liệu tham khảo về getAuthType() để biết chi tiết. Các phương thức xác thực hiện được hỗ trợ được liệt kê trong tài liệu tham khảo về AuthType.

Ví dụ: trình kết nối sau không yêu cầu xác thực:

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

Nếu nguồn dữ liệu của bạn yêu cầu xác thực OAuth 2.0, hãy xem hướng dẫn xác thực OAuth 2.0 và thêm các hàm bắt buộc khác vào trình kết nối của bạn.

Xác định cấu hình qua getConfig()

Hàm getConfig() được gọi để lấy cấu hình cho trình kết nối, bao gồm cả các giá trị do người dùng cung cấp mà trình kết nối của bạn yêu cầu. Hãy xem tài liệu tham khảo getConfig() để biết thông tin chi tiết.

Dựa trên phản hồi do getConfig() cung cấp, Looker Studio sẽ hiển thị màn hình cấu hình trình kết nối. Bạn có thể xem danh sách các phần tử cấu hình được hỗ trợ trong tài liệu tham khảo về ConfigType.

Nếu nguồn dữ liệu của bạn yêu cầu ngày dưới dạng thông số, hãy gọi config.setDateRangeRequired(true). Nếu bạn cần đặt câu hỏi về cấu hình có điều kiện hoặc cấu hình động, hãy xem phần cấu hình dạng bước.

Sau đây là ví dụ về trình kết nối yêu cầu người dùng nhập mã tên gói npm. Thông tin và trường nhập dữ liệu được xác định trong hàm 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();
}

Xác định các trường bằng getSchema()

Hàm này được gọi để lấy giản đồ cho yêu cầu nhất định. Mọi tham số cấu hình do hàm getConfig() xác định sẽ được cung cấp trong đối số request. Hãy xem tài liệu tham khảo về getSchema() để biết thông tin chi tiết.

Tuỳ thuộc vào nguồn dữ liệu của trình kết nối và cấu hình do người dùng cung cấp, giản đồ có thể được khắc phục hoặc bạn có thể phải tự động cung cấp giản đồ này tại thời điểm yêu cầu.

Ví dụ: nếu một trình kết nối đang tìm nạp dữ liệu báo cáo dựa trên một Mã báo cáo, thì dữ liệu được trả về cho báo cáo đó và do đó, giản đồ này có thể không được xác định trước. Trong trường hợp này, getSchema() có thể yêu cầu tìm nạp dữ liệu và giản đồ sẽ phải tính toán.

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

Tìm nạp và trả về dữ liệu bằng getData()

Hàm này được gọi để lấy dữ liệu cho yêu cầu đã cho. Mọi tham số cấu hình do hàm getConfig() xác định sẽ được cung cấp trong đối số request. Hãy xem tài liệu tham khảo về getData() để biết thông tin chi tiết.

Bạn cần chú ý thêm các tham số sau trong yêu cầu getData():

  • lastRefresh
    lastRefresh biểu thị dấu thời gian đánh dấu thời điểm của yêu cầu làm mới dữ liệu gần đây nhất. Bạn có thể phân tích cú pháp giá trị bằng new Date(timestampString). Nếu bạn đang sử dụng Dịch vụ bộ nhớ đệm của Apps Script hoặc bất kỳ phương thức lưu vào bộ nhớ đệm nào khác, thì dấu thời gian lastRefresh có thể giúp bạn xác định xem nên thực hiện yêu cầu tìm nạp mới cho nguồn dữ liệu hay phân phát dữ liệu từ bộ nhớ đệm.

  • dateRange
    Nếu dateRangeRequired được đặt thành true trong getConfig(), thì mỗi lệnh gọi getData() sẽ chứa phạm vi ngày đã chọn trong yêu cầu. Xem phần Làm việc với phạm vi ngày để biết thêm chi tiết.

Ví dụ sau đây tìm nạp dữ liệu dựa trên yêu cầu đến và trả về số liệu thống kê về gói:

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

Hoàn tất tệp kê khai dự án

Tệp kê khai chứa thông tin về Trình kết nối cộng đồng mà bạn phải cung cấp để triển khai và sử dụng trình kết nối trong Looker Studio.

Để chỉnh sửa tệp kê khai trong môi trường phát triển Apps Script, hãy nhấp vào trình đơn View (Xem) rồi nhấp vào Show manifest file (Hiện tệp kê khai). Thao tác này sẽ tạo một tệp kê khai appsscript.json mới.

Cập nhật tệp kê khai để bao gồm những dữ liệu sau:

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

Để biết thông tin chi tiết về tệp kê khai Looker Studio, hãy xem Tài liệu tham khảo về tệp kê khai.

Các bước tiếp theo

Bước tiếp theo là triển khai Trình kết nối cộng đồng.