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

Các bước để tạo 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 một dự án mới. Apps Script sẽ tạo một tập lệnh mặc định cho bạn. Bạn có thể 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 đều phải có một bộ hàm cụ thể được xác định. Ứ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 theo mô tả trong Tài liệu tham khảo về Community Connector API. 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 được dùng cho dịch vụ bên thứ ba. Hãy xem tài liệu tham khảo về getAuthType() để biết thêm thông tin chi tiết. Các phương thức xác thực hiện được hỗ trợ có trong tài liệu tham khảo AuthType.

Ví dụ: trình kết nối sau đây 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 thông 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. Các phần tử cấu hình được hỗ trợ được liệt kê trong tài liệu tham khảo ConfigType.

Nếu nguồn dữ liệu của bạn yêu cầu ngày làm tham 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 động, hãy xem phần cấu hình từng bước.

Sau đây là ví dụ về một trình kết nối yêu cầu người dùng nhập mã tên gói npm. Một trường thông tin và một trường nhập 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 đã 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 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 cố định hoặc bạn có thể phải cung cấp giản đồ này một cách linh hoạt 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ã báo cáo, thì dữ liệu được trả về cho báo cáo đó và do đó, lược đồ có thể không được biết trước. Trong trường hợp này, getSchema() có thể yêu cầu tìm nạp dữ liệu và bạn sẽ phải tính toán giả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 thông 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 getData() để biết thông tin chi tiết.

Các tham số sau đây trong yêu cầu getData() cần được chú ý thêm:

  • lastRefresh
    lastRefresh biểu thị dấu thời gian đánh dấu thời gian của yêu cầu gần đây nhất để làm mới dữ liệu. Bạn có thể phân tích cú pháp giá trị bằng new Date(timestampString). Nếu đ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 có nên đưa ra 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. Hãy xem phần Xử lý phạm vi ngày để biết thêm thông tin 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 của bạn. Đây là thông tin bắt buộc để 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 Xem rồi nhấp vào 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 để thêm 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 của 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.