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 như sau:

  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 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. 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 cần phải xác định một bộ hàm cụ thể. Chiến lược phát hành đĩa đơn ứng dụng lưu trữ (ví dụ: Looker Studio) sẽ thực thi các hàm này. Thông tin trình kết nối được dự kiến sẽ xử lý các yêu cầu được gửi đến và phản hồi như được mô tả trong tài liệu tham khảo về Community Connector API. Nếu bạn gặp phải vấn đề trong khi phát triển mã của bạn, 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 pháp xác thực được sử dụng cho Dịch vụ bên thứ ba. Xem tài liệu tham khảo getAuthType() để biết thông tin chi tiết. Hiện tại các phương pháp xác thực được hỗ trợ có trong tài liệu tham khảo về 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 chức năng bắt buộc bổ sung để 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 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. Xem 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. Liệt kê các thành phần 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 làm tham số, hãy gọi config.setDateRangeRequired(true). Nếu bạn cần hỏi câu hỏi có điều kiện hoặc câu hỏi linh hoạt câu hỏi về cấu hình, hãy xem nội dung cấu hình 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. Một trường 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 đã cho. Bất kỳ hạng nào các 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 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, giản đồ có thể được sửa hoặc bạn có thể phải tự động cung cấp giản đồ này tại thời gian 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 đó, do đó có thể không biết trước giản đồ. 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 được 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 cấu hình các tham số 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.

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

  • lastRefresh
    lastRefresh là dấu thời gian đánh dấu thời điểm xảy ra gần đây nhất làm mới dữ liệu. Bạn phải 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, dấu thời gian lastRefresh có thể giúp bạn xác định xem nên thực hiện một yêu cầu tìm nạp mới đến nguồn dữ liệu hay phân phát dữ liệu từ bộ nhớ đệm.

  • dateRange
    Nếu bạn đặt dateRangeRequired thành true trong getConfig() thì mỗi getData() cuộc gọi sẽ chứa phạm vi ngày đã chọn trong yêu cầu. Xem 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 của bạn, cần thiết để 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 thị tệp kê khai). Thao tác này sẽ tạo một Tệp kê khai appsscript.json.

Cập nhật tệp kê khai để bao gồ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 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 sẽ là triển khai Trình kết nối cộng đồng.