コミュニティ コネクタの作成

コミュニティ コネクタを作成する手順は次のとおりです。

  1. 新しい Apps Script プロジェクトを作成します。
  2. コネクタコードを記述します。
  3. プロジェクト マニフェストを作成します。

新しい Apps Script プロジェクトを作成する

Google Apps Script にアクセスし、新しいプロジェクトを作成します。Apps Script によってデフォルトのスクリプトが作成されます。必要に応じて myFunction 関数を削除し、プロジェクトの名前を変更してください(Apps Script の詳細)。

コネクタコードを記述する

すべてのコネクタには、特定の関数セットが定義されている必要があります。「 ホスト アプリケーション(Looker Studio など)がこれらの機能を実行します。コミュニティ コネクタ API リファレンスで説明されているように、コネクタは受信リクエストを処理してレスポンスを返します。コードの開発中に問題が発生した場合は、デバッグガイドをご覧ください。

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() のリファレンスをご覧ください。

コネクタのデータソースとユーザー指定の設定に応じて、スキーマは固定される場合と、リクエスト時に動的に指定しなければならない場合があります。

たとえば、コネクタがレポート ID に基づいてレポートデータを取得する場合、そのレポートに返されるデータ、つまりスキーマは事前にわからないことがあります。 そのような場合、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)Apps Script キャッシュ サービスまたは 他のキャッシュ方法の場合、lastRefresh タイムスタンプを使用すると、 新しい取得リクエストをデータソースに提供するのか、それともデータソースに提供するのかを決める キャッシュからデータを抽出できます

  • dateRange
    getConfig()dateRangeRequiredtrue に設定した場合、各 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 マニフェストの詳細については、マニフェスト リファレンスをご覧ください。

次のステップ

次のステップでは、コミュニティ コネクタをデプロイします。