커뮤니티 커넥터 구축

커뮤니티 커넥터를 만드는 단계는 다음과 같습니다.

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

프로젝트 매니페스트 완료

매니페스트 파일에는 해야 합니다.

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 매니페스트에 대한 자세한 내용은 참조 매니페스트 참조를 확인하세요.

다음 단계

다음 단계는 커뮤니티 커넥터를 배포하는 것입니다.