Membangun Konektor Komunitas

Langkah-langkah untuk membuat Konektor Komunitas adalah:

  1. Buat project Apps Script baru.
  2. Tulis kode konektor.
  3. Lengkapi manifes proyek.

Membuat project Apps Script baru

Buka Google Apps Script untuk membuat project baru. Apps Script akan membuat skrip default untuk Anda. Jangan ragu untuk menghapus fungsi myFunction dan mengganti nama project. (Pelajari Apps Script lebih lanjut)

Tulis kode konektor

Setiap konektor diharuskan memiliki kumpulan fungsi tertentu. Aplikasi hosting (misalnya, Looker Studio) akan menjalankan fungsi ini. Konektor Anda diharapkan dapat menangani permintaan masuk dan merespons seperti yang dijelaskan dalam referensi Community Connector API. Jika Anda mengalami masalah saat mengembangkan kode, baca panduan proses debug untuk mendapatkan bantuan.

Menentukan jenis autentikasi di getAuthType()

Fungsi ini dipanggil untuk mengidentifikasi metode autentikasi yang digunakan untuk layanan pihak ketiga. Lihat referensi getAuthType() untuk mengetahui detailnya. Metode autentikasi yang saat ini didukung tercantum dalam referensi AuthType.

Misalnya, konektor berikut tidak memerlukan autentikasi:

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

Jika sumber data Anda memerlukan autentikasi OAuth 2.0, lihat panduan autentikasi OAuth 2.0 dan tambahkan fungsi tambahan yang diperlukan ke konektor Anda.

Menentukan konfigurasi melalui getConfig()

Fungsi getConfig() dipanggil untuk mendapatkan konfigurasi konektor, termasuk nilai yang disediakan pengguna yang diperlukan konektor Anda. Lihat referensi getConfig() untuk mengetahui detailnya.

Berdasarkan respons yang diberikan oleh getConfig(), Looker Studio akan merender layar konfigurasi konektor. Elemen konfigurasi yang didukung tercantum dalam referensi ConfigType.

Jika sumber data Anda memerlukan tanggal sebagai parameter, panggil config.setDateRangeRequired(true). Jika Anda perlu mengajukan pertanyaan terkait konfigurasi kondisional atau dinamis, lihat konfigurasi bertahap.

Berikut adalah contoh konektor yang mengharuskan pengguna memasukkan kode nama paket npm. Info dan kolom input ditentukan dalam fungsi 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();
}

Menentukan kolom dengan getSchema()

Fungsi ini dipanggil untuk mendapatkan skema bagi permintaan yang diberikan. Setiap parameter konfigurasi yang ditentukan oleh fungsi getConfig() akan diberikan dalam argumen request. Lihat referensi getSchema() untuk mengetahui detailnya.

Bergantung pada sumber data konektor Anda dan konfigurasi yang diberikan oleh pengguna, skema dapat diperbaiki atau Anda mungkin harus memberikannya secara dinamis pada waktu permintaan.

Misalnya, jika konektor mengambil data laporan berdasarkan ID Laporan, data yang ditampilkan untuk laporan tersebut dan karenanya skema mungkin tidak diketahui sebelumnya. Dalam hal ini, getSchema() mungkin memerlukan pengambilan data dan skema harus dihitung.

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

Mengambil dan menampilkan data dengan getData()

Fungsi ini dipanggil untuk mendapatkan data permintaan yang ditentukan. Setiap parameter konfigurasi yang ditentukan oleh fungsi getConfig() akan diberikan dalam argumen request. Lihat referensi getData() untuk mengetahui detailnya.

Parameter berikut dari permintaan getData() memerlukan perhatian tambahan:

  • lastRefresh
    lastRefresh mewakili stempel waktu yang menandai waktu permintaan terbaru untuk pembaruan data. Anda seharusnya dapat mengurai nilai dengan new Date(timestampString). Jika Anda menggunakan Apps Script Cache Service atau metode cache lainnya, stempel waktu lastRefresh dapat membantu Anda menentukan apakah akan membuat permintaan pengambilan baru ke sumber data atau menyalurkan data dari cache.

  • dateRange
    Jika dateRangeRequired ditetapkan ke true di getConfig(), setiap panggilan getData() akan berisi rentang tanggal yang dipilih dalam permintaan. Lihat Bekerja dengan Rentang Tanggal untuk detail selengkapnya.

Contoh berikut mengambil data berdasarkan permintaan masuk dan menampilkan statistik paket:

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

Melengkapi manifes proyek

File manifes berisi informasi tentang Konektor Komunitas Anda yang diperlukan untuk men-deploy dan menggunakan konektor di Looker Studio.

Untuk mengedit file manifes di lingkungan pengembangan Apps Script, klik menu View, lalu klik Show manifest file. Tindakan ini akan membuat file manifes appsscript.json baru.

Update manifes agar menyertakan data berikut:

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

Untuk mengetahui detail tentang manifes Looker Studio, lihat referensi manifes referensi.

Langkah berikutnya

Langkah berikutnya adalah menerapkan Konektor Komunitas.