یک اتصال دهنده جامعه بسازید

مراحل ساخت کانکتور انجمن عبارتند از:

  1. یک پروژه Apps Script جدید ایجاد کنید.
  2. کد رابط را بنویسید.
  3. مانیفست پروژه را تکمیل کنید.

یک پروژه Apps Script جدید ایجاد کنید

برای ایجاد یک پروژه جدید، از Google Apps Script دیدن کنید. Apps Script یک اسکریپت پیش فرض برای شما ایجاد می کند. با خیال راحت تابع myFunction را حذف کرده و نام پروژه را تغییر دهید. ( در مورد Apps Script بیشتر بدانید )

کد کانکتور را بنویسید

هر کانکتور باید مجموعه خاصی از عملکردها را تعریف کند. برنامه میزبانی (به عنوان مثال استودیو Looker) این توابع را اجرا خواهد کرد. انتظار می رود رابط شما به درخواست های ورودی رسیدگی کند و همانطور که در مرجع API Connector Community توضیح داده شده است پاسخ دهد. اگر هنگام توسعه کد خود با مشکل مواجه شدید، راهنمای اشکال زدایی را برای کمک بخوانید.

تعریف نوع احراز هویت در 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() مراجعه کنید.

بسته به منبع داده کانکتور شما و پیکربندی ارائه شده توسط کاربر، این طرح ممکن است ثابت شده باشد یا ممکن است مجبور باشید در زمان درخواست به صورت پویا این را ارائه دهید.

برای مثال، اگر یک رابط در حال واکشی داده‌های گزارش بر اساس شناسه گزارش باشد، ممکن است داده‌های بازگردانده شده برای آن گزارش و بنابراین طرحواره از قبل مشخص نباشد. در این مورد 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 Cache Service یا هر روش ذخیره سازی دیگری استفاده می کنید، برچسب زمانی lastRefresh می تواند به شما کمک کند تا تعیین کنید که آیا درخواست واکشی جدیدی را به منبع داده ارسال کنید یا داده ها را از حافظه پنهان ارائه دهید.

  • dateRange
    اگر dateRangeRequired در getConfig() روی true تنظیم شده باشد، هر فراخوان 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;
}

مانیفست پروژه را تکمیل کنید

فایل مانیفست حاوی اطلاعاتی درباره Connector Community شما است که برای استقرار و استفاده از رابط شما در Looker Studio لازم است.

برای ویرایش فایل مانیفست در محیط توسعه Apps Script، روی منوی View کلیک کنید و روی Show manifest file کلیک کنید. با این کار یک فایل مانیفست جدید 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، به مرجع مانیفست مرجع مراجعه کنید.

مراحل بعدی

گام بعدی این است که Connector Community خود را استقرار دهید .