إنشاء رابط في المنتدى

في ما يلي خطوات إنشاء أداة ربط خاصة بالمنتدى:

  1. أنشئ مشروعًا جديدًا في "برمجة تطبيقات Google".
  2. اكتب رمز الموصل.
  3. أكمِل بيان المشروع.

إنشاء مشروع جديد في "برمجة تطبيقات Google"

انتقِل إلى برمجة تطبيقات Google لإنشاء مشروع جديد. ستنشئ "برمجة تطبيقات Google" نصًا برمجيًا تلقائيًا لك. يمكنك إزالة الدالة myFunction وإعادة تسمية المشروع. (مزيد من المعلومات عن "برمجة تطبيقات Google")

كتابة رمز الموصّل

يجب أن يتضمّن كل موصّل مجموعة محدّدة من الدوال. سيتم تنفيذ هذه الدوال من خلال التطبيق المضيف (مثل Looker Studio). من المتوقّع أن يتعامل الموصّل مع الطلبات الواردة ويردّ عليها كما هو موضّح في مرجع Community Connector 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() لمعرفة التفاصيل.

استنادًا إلى مصدر بيانات الموصل والإعدادات التي يقدّمها المستخدم، قد يكون المخطط ثابتًا أو قد تحتاج إلى تقديمه بشكل ديناميكي عند وقت الطلب.

على سبيل المثال، إذا كان أحد الموصلات يستردّ بيانات التقارير استنادًا إلى معرّف تقرير، قد لا تكون البيانات التي يتم عرضها لهذا التقرير وبالتالي المخطط معروفة مسبقًا. في هذه الحالة، قد يتطلّب 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
    إذا تم ضبط dateRangeRequired على true في getConfig()، سيتضمّن كل طلب 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، يُرجى الاطّلاع على مرجع البيان.

الخطوات التالية

تتمثل الخطوة التالية في نشر موصّل Community Connector.