إنشاء إضافة Classroom

هذا هو أول دليل إرشادي في سلسلة الأدلة الإرشادية حول إضافات Classroom.

في هذا الدليل الإرشادي، يمكنك وضع الأساس لتطوير تطبيق ويب ونشره كإضافة في Classroom. وتوسّع الخطوات المستقبلية في الأدلة الإرشادية هذا التطبيق.

أثناء هذا الدليل الإرشادي، يمكنك إكمال ما يلي:

  • إنشاء مشروع جديد على Google Cloud لإضافتك
  • إنشاء تطبيق ويب أساسي باستخدام أزرار تسجيل دخول مؤقتة
  • نشر بطاقة بيانات المتجر في Google Workspace Marketplace لإضافتك

بعد الانتهاء، يمكنك تثبيت إضافتك وتحميلها في iframe الخاص بإضافات Classroom.

المتطلبات الأساسية

اختَر لغة للاطّلاع على المتطلبات الأساسية المناسبة:

Python

يستخدم مثال Python إطار عمل Flask. يمكنك تنزيل رمز المصدر الكامل لجميع الأدلة الإرشادية من صفحة "نظرة عامة". ويمكن العثور على رمز هذا الدليل الإرشادي تحديدًا في الدليل /flask/01-basic-app/.

إذا لزم الأمر، ثبِّت الإصدار 3.7 من Python أو إصدارًا أحدث وتأكَّد من توفُّر pip.

python -m ensurepip --upgrade

ننصحك أيضًا بإعداد بيئة Python افتراضية جديدة وتفعيلها.

python3 -m venv .classroom-addon-env
source .classroom-addon-env/bin/activate

يحتوي كل دليل فرعي من الأدلة الإرشادية في الأمثلة التي تم تنزيلها على ملف requirements.txt. يمكنك تثبيت المكتبات المطلوبة بسرعة باستخدام pip. استخدِم ما يلي لتثبيت المكتبات المطلوبة لهذا الدليل الإرشادي.

cd flask/01-basic-app
pip install -r requirements.txt

Node.js

يستخدم مثال Node.js إطار عمل Express. يمكنك تنزيل رمز المصدر الكامل لجميع الأدلة الإرشادية من صفحة "نظرة عامة".

إذا لزم الأمر، ثبِّت NodeJS v16.13 أو إصدارًا أحدث.

ثبِّت وحدات العُقد المطلوبة باستخدام npm.

npm install

جافا

يستخدم مثال Java إطار عمل Spring Boot. يمكنك تنزيل رمز المصدرالكامل لجميع الأدلة الإرشادية من صفحة "نظرة عامة".

ثبِّت Java 11 أو إصدارًا أحدث إذا لم يكن مثبَّتًا على جهازك.

يمكن لتطبيقات Spring Boot استخدام Gradle أو Maven للتعامل مع الإصدارات وإدارة التبعيات. يتضمّن هذا المثال برنامج Maven المغلّف الذي يضمن إنشاء إصدار ناجح بدون الحاجة إلى تثبيت Maven نفسه.

لتتمكّن من تشغيل المثال الذي نوفّره، نفِّذ الأوامر التالية في الدليل الذي نزّلت فيه المشروع للتأكّد من توفُّر المتطلبات الأساسية لتشغيل المشروع.

java --version
./mvnw --version

أو على نظام التشغيل Windows:

java -version
mvnw.cmd --version

إعداد مشروع على Google Cloud

يتم التحكّم في إمكانية الوصول إلى Classroom API وطُرق المصادقة المطلوبة من خلال مشاريع Google Cloud. سترشدك التعليمات التالية خلال الحد الأدنى من الخطوات لإنشاء مشروع جديد وضبطه لاستخدامه مع إضافتك.

إنشاء المشروع

أنشئ مشروعًا جديدًا على Google Cloud من خلال الانتقال إلى صفحة إنشاء المشروع. يمكنك اختيار أي اسم للمشروع الجديد. انقر على إنشاء.

تستغرق عملية إنشاء المشروع الجديد بالكامل بضع لحظات. بعد الانتهاء، احرص على اختيار المشروع؛ يمكنك اختياره في القائمة المنسدلة لاختيار المشروع أعلى الشاشة، أو النقر على اختيار مشروع في قائمة الإشعارات أعلى يسار الشاشة.

اختيار المشروع في Google Cloud Console

إرفاق حزمة تطوير البرامج (SDK) في Google Workspace Marketplace بمشروع على السحابة الإلكترونية من Google

انتقِل إلى متصفّح "مكتبة واجهات برمجة التطبيقات". ابحث عن Google Workspace Marketplace SDK. من المفترض أن تظهر حزمة تطوير البرامج (SDK) في قائمة النتائج.

بطاقة حزمة تطوير البرامج (SDK) في Google Workspace Marketplace

اختَر بطاقة حزمة تطوير البرامج (SDK) في Google Workspace Marketplace، ثم انقر على تفعيل.

ضبط حزمة تطوير البرامج (SDK) في Google Workspace Marketplace

يوفر Google Workspace Marketplace بطاقة البيانات التي يثبِّت المستخدمون والمشرفون من خلالها إضافتك. للمتابعة، اضبط إعدادات التطبيق وبطاقة بيانات المتجر وشاشة طلب الموافقة المتعلّقة ببروتوكول OAuth في حزمة تطوير البرامج (SDK) في Marketplace.

إعدادات التطبيق

انتقِل إلى صفحة إعدادات التطبيق في حزمة تطوير البرامج (SDK) في Marketplace. قدِّم المعلومات التالية:

  • اضبط إذن الوصول إلى التطبيق على Public أو Private.

    • الإعداد "علني" مخصّص للتطبيقات التي سيتم طرحها في النهاية للمستخدمين النهائيين. يجب أن يخضع التطبيق المُتاح للجميع لعملية موافقة قبل نشره للمستخدمين النهائيين، ولكن يمكنك تحديد المستخدمين الذين يمكنهم تثبيته واختباره كـ مسودة. هذه حالة ما قبل النشر ستسمح لك باختبار إضافتك وتطويرها قبل إرسالها للموافقة عليها.
    • الإعداد "خاص" مناسب للاختبار والتطوير الداخليين. لا يمكن تثبيت التطبيق الخاص إلا من قِبل المستخدمين في النطاق نفسه الذي تم إنشاء المشروع فيه. لذلك، عليك ضبط مستوى الرؤية على "خاص" فقط إذا تم إنشاء المشروع في نطاق يتضمّن اشتراكًا في Google Workspace for Education، وإلا لن يتمكّن المستخدمون الاختباريون من إطلاق إضافات Classroom.
  • اضبط إعدادات التثبيت على Admin Only install إذا كنت تريد حصر عملية التثبيت على مشرفي النطاق.

  • ضمن دمج التطبيق، اختَر إضافة Classroom. ستُطلب منك عنوان URI لإعداد المرفق الآمن، وهو عنوان URL الذي تتوقّع تحميله عندما يفتح المستخدم إضافتك. لأغراض هذا الدليل الإرشادي، يجب أن يكون هذا https://<your domain>/addon-discovery.

  • تُستخدَم بادئات عناوين URI المسموح بها للمرفقات للتحقّق من صحة عناوين URI التي تم ضبطها في AddOnAttachment باستخدام الطريقتَين courses.*.addOnAttachments.create و courses.*.addOnAttachments.patch. تكون عملية التحقّق مطابقة حرفية لبادئة السلسلة ولا تسمح باستخدام أحرف البدل في الوقت الحالي. أضِف على الأقل النطاق الجذر لخادم المحتوى، مثل https://localhost:5000/ أو https://cdn.myedtech.com/.

  • أضِف نطاقات OAuth نفسها التي تم تقديمها في شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth في الخطوة السابقة.

  • املأ الحقول بما يناسب مؤسستك ضمن روابط المطوّرين.

بطاقة بيانات المتجر

انتقِل إلى صفحة "بطاقة بيانات المتجر" في حزمة تطوير البرامج (SDK) في Marketplace. قدِّم المعلومات التالية:

  • ضمن تفاصيل التطبيق، أضِف لغة أو وسِّع القائمة المنسدلة بجانب اللغة المدرَجة حاليًا. قدِّم اسمًا للطلب وأوصافًا، وستظهر هذه المعلومات في صفحة بطاقة بيانات المتجر في Google Workspace Marketplace لإضافتك. انقر على تم للحفظ.
  • اختَر فئة لإضافتك.
  • ضمن مواد العرض الرسومية، قدِّم صورًا للحقول المطلوبة. يمكن تغيير هذه الصور لاحقًا، ويمكن أن تكون صورًا مؤقتة في الوقت الحالي.
  • ضمن روابط الدعم، قدِّم عناوين URL المطلوبة. يمكن أن تكون هذه العناوين مؤقتة إذا ضبطت إذن الوصول إلى التطبيق على خاص في الخطوة السابقة.

إذا ضبطت إذن الوصول إلى التطبيق على خاص في الخطوة السابقة، انقر على نشر، وسيصبح تطبيقك متاحًا للتثبيت على الفور. إذا ضبطت إذن الوصول إلى التطبيق على علني، أضِف عناوين البريد الإلكتروني لأي مستخدمين تجريبيين في منطقة المختبِرون للمسودة وانقر على حفظ المسودة.

تظهر شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth عندما يمنح المستخدمون إذن الوصول إلى تطبيقك لأول مرة. وتطلب منهم السماح لتطبيقك بالوصول إلى معلوماتهم الشخصية ومعلومات حساباتهم، وفقًا لما تمليه النطاقات التي تفعِّلها.

انتقِل إلى صفحة إنشاء شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth. قدِّم المعلومات التالية:

  • اضبط نوع المستخدم على خارجي. انقر على إنشاء.
  • في الصفحة التالية، املأ تفاصيل التطبيق ومعلومات الاتصال المطلوبة. قدِّم أي نطاقات تستضيف تطبيقك ضمن النطاقات المفوّضة. انقر على حفظ ومتابعة.
  • أضِف أي نطاقات OAuth يتطلبها تطبيق الويب. يمكنك الاطّلاع على دليل إعداد OAuth configuration guide للحصول على مناقشة متعمّقة حول النطاقات والغرض منها.

    يجب طلب نطاق واحد على الأقل من النطاقات التالية لكي ترسل Google مَعلمة طلب البحث login_hint. يتوفّر شرح أكثر تفصيلاً لهذا السلوك في دليل إعداد OAuth:

    • https://www.googleapis.com/auth/userinfo.email (مضمّنة حاليًا)
    • https://www.googleapis.com/auth/userinfo.profile (مضمّنة حاليًا)

    النطاقات التالية خاصة بإضافات Classroom:

    • https://www.googleapis.com/auth/classroom.addons.teacher
    • https://www.googleapis.com/auth/classroom.addons.student

    أضِف أيضًا أي نطاقات أخرى لواجهات برمجة تطبيقات Google يتطلبها تطبيقك من المستخدمين النهائيين.

    انقر على حفظ ومتابعة.

  • أدرِج عناوين البريد الإلكتروني لأي حسابات اختبار في صفحة المستخدمون التجريبيون. انقر على حفظ ومتابعة.

تأكَّد من أنّ إعداداتك صحيحة، ثم ارجع إلى لوحة البيانات.

تثبيت الإضافة

يمكنك الآن تثبيت إضافتك باستخدام الرابط أعلى صفحة بطاقة بيانات المتجر في حزمة تطوير البرامج (SDK) في Marketplace. انقر على عرض في Marketplace أعلى الصفحة للاطّلاع على بطاقة البيانات، ثم اختَر تثبيت.

إنشاء تطبيق ويب أساسي

يمكنك إعداد تطبيق ويب أساسي يتضمّن مسارَين. ستوسّع الخطوات المستقبلية في الأدلة الإرشادية هذا التطبيق، لذا أنشئ الآن صفحة مقصودة للإضافة /addon-discovery وصفحة فهرس وهمية / لموقع شركتنا الإلكتروني.

مثال على تطبيق ويب في إطار iframe

استخدِم نقطتَي النهاية التاليتَين:

  • /: تعرض رسالة ترحيب وزرًا لإغلاق كل من علامة التبويب الحالية وiframe الخاص بالإضافة.
  • /addon-discovery: تعرض رسالة ترحيب وزرَّين: أحدهما لإغلاق iframe الخاص بالإضافة والآخر لفتح موقع إلكتروني في علامة تبويب جديدة.

يُرجى العِلم أنّنا نضيف أزرارًا لإنشاء النوافذ أو iframe وإغلاقهما. توضّح هذه الأزرار طريقة لنقل المستخدم بأمان إلى علامة تبويب جديدة للحصول على إذن في الدليل الإرشادي التالي.

إنشاء نص برمجي للأدوات المساعدة

أنشئ دليل static/scripts. أنشئ ملفًا جديدًا باسم addon-utils.js. أضِف الدالتَين التاليتَين.

/**
 *   Opens a given destination route in a new window. This function uses
 *   window.open() so as to force window.opener to retain a reference to the
 *   iframe from which it was called.
 *   @param {string} destinationURL The endpoint to open, or "/" if none is
 *   provided.
 */
function openWebsiteInNewTab(destinationURL = '/') {
  window.open(destinationURL, '_blank');
}

/**
 *   Close the iframe by calling postMessage() in the host Classroom page. This
 *   function can be called directly when in a Classroom add-on iframe.
 *
 *   Alternatively, it can be used to close an add-on iframe in another window.
 *   For example, if an add-on iframe in Window 1 opens a link in a new Window 2
 *   using the openWebsiteInNewTab function, you can call
 *   window.opener.closeAddonIframe() from Window 2 to close the iframe in Window
 *   1.
 */
function closeAddonIframe() {
  window.parent.postMessage({
    type: 'Classroom',
    action: 'closeIframe',
  }, '*');
};

إنشاء المسارات

استخدِم نقطتَي النهاية /addon-discovery و/.

Python

إعداد دليل التطبيق

لأغراض هذا المثال، يمكنك تنظيم منطق التطبيق كوحدة Python. هذا هو دليل webapp في المثال الذي نوفّره.

أنشئ دليلاً لوحدة الخادم، مثل webapp. انقِل دليل static إلى دليل الوحدة. أنشئ أيضًا دليلاً باسم template في دليل الوحدة، وسيتم وضع ملفات HTML هنا.

إنشاء وحدة الخادم*

أنشئ الملف __init__.py في دليل الوحدة وأضِف عمليات الاستيراد والإعلانات التالية.

from flask import Flask
import config

app = Flask(__name__)
app.config.from_object(config.Config)

# Load other module script files. This import statement refers to the
# 'routes.py' file described below.
from webapp import routes

بعد ذلك، أنشئ ملفًا للتعامل مع مسارات تطبيق الويب. هذا هو webapp/routes.py في المثال الذي نوفّره. استخدِم المسارَين في هذا الملف.

from webapp import app
import flask

@app.route("/")
def index():
    return flask.render_template("index.html",
                                message="You've reached the index page.")

@app.route("/classroom-addon")
def classroom_addon():
    return flask.render_template(
        "addon-discovery.html",
        message="You've reached the addon discovery page.")

يُرجى العِلم أنّ كلا المسارَين يمرِّران متغيّر message إلى نموذجَي Jinja الخاصَين بهما. ويفيد ذلك في تحديد الصفحة التي وصل إليها المستخدم.

إنشاء ملفات الإعداد والتشغيل

في الدليل الجذر لتطبيقك، أنشئ الملفَين main.py وconfig.py. اضبط مفتاحك السري في config.py.

import os

class Config(object):
    # Note: A secret key is included in the sample so that it works.
    # If you use this code in your application, replace this with a truly secret
    # key. See https://flask.palletsprojects.com/quickstart/#sessions.
    SECRET_KEY = os.environ.get(
        'SECRET_KEY') or "REPLACE ME - this value is here as a placeholder."

في ملف main.py، استورِد وحدتك وابدأ خادم Flask.

from webapp import app

if __name__ == "__main__":
    # Run the application over HTTPs with a locally stored certificate and key.
    # Defaults to https://localhost:5000.
    app.run(
        host="localhost",
        ssl_context=("localhost.pem", "localhost-key.pem"),
        debug=True)

Node.js

يتم تسجيل المسارات في ملف app.js باستخدام السطرَين التاليَين.

const websiteRouter = require('./routes/index');
const addonRouter = require('./routes/classroom-addon');

app.use('/', websiteRouter);
app.use('/addon-discovery', addonRouter);

افتح /01-basic-app/routes/index.js وراجِع الرمز. يتم الوصول إلى هذا المسار عندما ينتقل المستخدم النهائي إلى الموقع الإلكتروني للشركة. يعرض المسار ردًا باستخدام نموذج Handlebars index ويمرِّر إلى النموذج عنصر بيانات يحتوي على المتغيّرَين title وmessage.

router.get('/', function (req, res, next) {
  res.render('index', {
    title: 'Education Technology',
    message: 'Welcome to our website!'
  });
});

افتح المسار الثاني /01-basic-app/routes/classroom-addon.js وراجِع الرمز. يتم الوصول إلى هذا المسار عندما ينتقل المستخدم النهائي إلى الإضافة. يُرجى العِلم أنّ هذا المسار يستخدم نموذج Handlebars discovery بالإضافة إلى تنسيق addon.hbs لعرض الصفحة بشكل مختلف عن الموقع الإلكتروني للشركة.

router.get('/', function (req, res, next) {
  res.render('discovery', {
    layout: 'addon.hbs',
    title: 'Education Technology Classroom add-on',
    message: `Welcome.`
  });
});

جافا

يستخدم مثال رمز Java وحدات لتجميع خطوات الدليل الإرشادي المتسلسلة. بما أنّ هذا هو الدليل الإرشادي الأول، يكون الرمز ضمن وحدة step_01_basic_app. وليس من المتوقّع أن تستخدِم الوحدات لتنفيذ مشروعك، بل ننصحك بالبناء على مشروع واحد أثناء اتّباع كل خطوة في الدليل الإرشادي.

أنشئ فئة وحدة تحكّم، مثل Controller.java في مشروع المثال هذا، لتحديد نقاط النهاية. في هذا الملف، استورِد التعليق التوضيحي @GetMapping من الاعتمادية spring-boot-starter-web.

import org.springframework.web.bind.annotation.GetMapping;

أدرِج التعليق التوضيحي لوحدة تحكّم إطار عمل Spring أعلى تعريف الفئة للإشارة إلى الغرض من الفئة.

@org.springframework.stereotype.Controller
public class Controller {

بعد ذلك، استخدِم المسارَين ومسارًا إضافيًا للتعامل مع الأخطاء.

/** Returns the index page that will be displayed when the add-on opens in a
*   new tab.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the index page template if successful, or the onError method to
*   handle and display the error message.
*/
@GetMapping(value = {"/"})
public String index(Model model) {
  try {
    return "index";
  } catch (Exception e) {
    return onError(e.getMessage(), model);
  }
}

/** Returns the add-on discovery page that will be displayed when the iframe
*   is first opened in Classroom.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the addon-discovery page.
*/
@GetMapping(value = {"/addon-discovery"})
public String addon_discovery(Model model) {
  try {
    return "addon-discovery";
  } catch (Exception e) {
    return onError(e.getMessage(), model);
  }
}

/** Handles application errors.
*   @param errorMessage message to be displayed on the error page.
*   @param model the Model interface to pass error information to display on
*   the error page.
*   @return the error page.
*/
@GetMapping(value = {"/error"})
public String onError(String errorMessage, Model model) {
  model.addAttribute("error", errorMessage);
  return "error";
}

اختبار الإضافة

ابدأ تشغيل خادمك. بعد ذلك، سجِّل الدخول إلى Google Classroom بصفتك أحد المستخدمين التجريبيين المعلّمين. انتقِل إلى علامة التبويب الواجب الدراسي وأنشئ مهمة جديدة. اختَر إضافتك من أداة اختيار الإضافات. يُفتح iframe وتحمِّل الإضافة عنوان URI لإعداد المرفق الذي حدّدته في صفحة إعدادات التطبيق في حزمة تطوير البرامج (SDK) في Marketplace.

تهانينا! أنت مستعد للمتابعة إلى الخطوة التالية: تسجيل دخول المستخدمين باستخدام ميزة "الدخول المُوحَّد" من Google.