مرفقات نوع المحتوى

هذه هي الجولة التفصيلية الرابعة في إضافات Classroom. لسلسلة الجولات التفصيلية.

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

خلال هذه الجولة التفصيلية، يمكنك إكمال ما يلي:

  • استرداد مَعلمات طلب البحث الإضافية التالية واستخدامها:
    • addOnToken: تم تمرير رمز تفويض مميز إلى "اكتشاف المرفقات" عرض.
    • itemId: معرّف فريد لـ CourseWork أو CourseWorkMaterial أو إشعار يتلقّى مرفق الإضافة
    • itemType: إما "courseWork" أو "courseWorkMaterials" أو "إشعار".
    • courseId: معرّف فريد لدورة Google Classroom في الذي يتم إنشاء المهمة الدراسية.
    • attachmentId: معرّف فريد يعيّنه Google Classroom لأحد الطلاب مرفق إضافة بعد الإنشاء.
  • تنفيذ التخزين الدائم للمرفقات من نوع المحتوى.
  • توفير مسارات لإنشاء المرفقات وعرض صور المعلّمين إطارات iframe في العرض للطلاب
  • يمكنك إصدار الطلبات التالية لواجهة برمجة تطبيقات إضافات Google Classroom:
    • إنشاء مرفق جديد
    • احصل على سياق الإضافة، الذي يحدد ما إذا كان المستخدم الذي سجّل الدخول الطالب أو المعلم.

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

تفعيل Classroom API

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

التعامل مع مَعلمات طلب البحث لعرض استكشاف المرفقات

كما ذكرنا سابقًا، يعمل Google Classroom على تمرير معلَمات طلب البحث عند تحميل طريقة عرض استكشاف المرفقات في إطار iframe:

  • courseId: رقم تعريف الدورة التدريبية الحالية في Classroom.
  • itemId: معرّف فريد لـ CourseWork أو CourseWorkMaterial أو إشعار يتلقّى مرفق الإضافة
  • itemType: إما "courseWork" أو "courseWorkMaterials" أو "إشعار"
  • addOnToken: رمز مميز يُستخدم لتفويض بعض إجراءات إضافة Classroom
  • login_hint: رقم تعريف Google للمستخدم الحالي

تتناول هذه الجولة التفصيلية courseId وitemId وitemType وaddOnToken. الاحتفاظ بهذه الرموز وتمريرها عند إصدار الطلبات في Classroom API.

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

Python

انتقِل إلى ملف خادم Flask الذي يوفّر مسارات للمرفق طريقة عرض Discovery (attachment-discovery-routes.py إذا كنت تتابع المثال المقدم). في أعلى المسار المقصود للإضافة (/classroom-addon في المثال المقدَّم)، يتم استرداد وتخزين مَعلمات طلب البحث courseId وitemId وitemType وaddOnToken

# Retrieve the itemId, courseId, and addOnToken query parameters.
if flask.request.args.get("itemId"):
    flask.session["itemId"] = flask.request.args.get("itemId")
if flask.request.args.get("itemType"):
    flask.session["itemType"] = flask.request.args.get("itemType")
if flask.request.args.get("courseId"):
    flask.session["courseId"] = flask.request.args.get("courseId")
if flask.request.args.get("addOnToken"):
    flask.session["addOnToken"] = flask.request.args.get("addOnToken")

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

إضافة مساحة تخزين دائمة للمرفقات من نوع المحتوى

يجب توفُّر سجلّ محلي لأي مرفقات تم إنشاؤها. يتيح لك هذا البحث عن المحتوى الذي اختاره المعلّم باستخدام المعرّفات المقدَّمة من Classroom.

عليك إعداد مخطّط قاعدة بيانات لـ Attachment. يوضح المثال الذي نقدمه المرفقات التي تعرض صورةً وشرحًا يحتوي Attachment على السمات التالية:

  • attachment_id: معرّف فريد لمرفق. تم التعيين من قِبل Classroom وظهرت في الرد عند إنشاء المرفق.
  • image_filename: اسم الملف المحلي للصورة التي تريد عرضها
  • image_caption: الشرح الذي سيتم عرضه مع الصورة

Python

توسيع تنفيذ SQLite وflask_sqlalchemy من الخطوات السابقة

انتقِل إلى الملف الذي حدّدت جدول المستخدمين فيه (models.py). إذا كنت تتبع المثال المقدم). إضافة ما يلي في أسفل الصفحة من الملف ضمن الفئة User.

class Attachment(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The image filename to store.
    image_filename = db.Column(db.String(120))

    # The image caption to store.
    image_caption = db.Column(db.String(120))

قم باستيراد فئة المرفقات الجديدة إلى ملف الخادم الذي يحتوي على المرفق مسارات المناولة.

إعداد مسارات جديدة

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

إضافة مسارات إنشاء المرفقات

تحتاج إلى صفحات ليختار المعلّم المحتوى وينشئ المرفقات. الطلبات. تنفيذ المسار /attachment-options لعرض خيارات المحتوى ليختارها المعلّم. تحتاج أيضًا إلى قوالب لاختيار المحتوى صفحات تأكيد الإنشاء. تحتوي أمثلتنا المقدمة على نماذج لهذه ويمكنك أيضًا عرض الطلبات والردود من Classroom API.

لاحظ أنه يمكنك بدلاً من ذلك تعديل طريقة عرض استكشاف المرفقات الحالية المقصودة لعرض خيارات المحتوى بدلاً من إنشاء الصفحة صفحة واحدة (/attachment-options). ننصحك بإنشاء صفحة جديدة لأغراض هذا التمرين حتى تحافظ على تنفيذ سلوك الدخول الموحّد الذي تم تنفيذه في للحصول على جولة تفصيلية، مثل إبطال أذونات التطبيق يجب أن تثبت هذه فائدة أثناء إنشاء الإضافة واختبارها.

يمكن للمعلم الاختيار من بين مجموعة صغيرة من الصور التي تتضمن ترجمة وشرحًا في مثال. لقد قدمنا أربع صور لمعالم شهيرة المستمدة من أسماء الملفات.

Python

في المثال الذي قدمناه، تجد ذلك في ملف webapp/attachment_routes.py.

@app.route("/attachment-options", methods=["GET", "POST"])
def attachment_options():
    """
    Render the attachment options page from the "attachment-options.html"
    template.

    This page displays a grid of images that the user can select using
    checkboxes.
    """

    # A list of the filenames in the static/images directory.
    image_filenames = os.listdir(os.path.join(app.static_folder, "images"))

    # The image_list_form_builder method creates a form that displays a grid
    # of images, checkboxes, and captions with a Submit button. All images
    # passed in image_filenames will be shown, and the captions will be the
    # title-cased filenames.

    # The form must be built dynamically due to limitations in WTForms. The
    # image_list_form_builder method therefore also returns a list of
    # attribute names in the form, which will be used by the HTML template
    # to properly render the form.
    form, var_names = image_list_form_builder(image_filenames)

    # If the form was submitted, validate the input and create the attachments.
    if form.validate_on_submit():

        # Build a dictionary that maps image filenames to captions.
        # There will be one dictionary entry per selected item in the form.
        filename_caption_pairs = construct_filename_caption_dictionary_list(
            form)

        # Check that the user selected at least one image, then proceed to
        # make requests to the Classroom API.
        if len(filename_caption_pairs) > 0:
            return create_attachments(filename_caption_pairs)
        else:
            return flask.render_template(
                "create-attachment.html",
                message="You didn't select any images.",
                form=form,
                var_names=var_names)

    return flask.render_template(
        "attachment-options.html",
        message=("You've reached the attachment options page. "
                "Select one or more images and click 'Create Attachment'."),
        form=form,
        var_names=var_names,
    )

وينتج عن ذلك "إنشاء مرفقات" تشبه ما يلي:

مثال على عرض اختيار المحتوى في Python

يمكن للمعلّم اختيار عدة صور. إنشاء مرفق واحد لكل صورة التي اختارها المعلّم في طريقة create_attachments

مشاكل في طلبات إنشاء المرفقات

الآن بعد أن عرفت أجزاء المحتوى التي يرغب المعلم في إرفاقها، الطلبات في Classroom API لإنشاء المرفقات على مهمة معينة. تخزين تفاصيل المرفق في قاعدة البيانات الخاصة بك بعد تلقي الرد من Classroom API.

ابدأ بالحصول على مثيل لخدمة Classroom:

Python

في المثال الذي قدمناه، تجد ذلك في ملف webapp/attachment_routes.py.

def create_attachments(filename_caption_pairs):
    """
    Create attachments and show an acknowledgement page.

    Args:
        filename_caption_pairs: A dictionary that maps image filenames to
            captions.
    """
    # Get the Google Classroom service.
    classroom_service = googleapiclient.discovery.build(
        serviceName="classroom",
        version="v1",
        credentials=credentials)

إرسال طلب "CREATE" إلى courses.courseWork.addOnAttachments النهائية. لكل صورة يحددها المدرس، أنشئ أولاً كائن AddOnAttachment:

Python

في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments. .

# Create a new attachment for each image that was selected.
attachment_count = 0
for key, value in filename_caption_pairs.items():
    attachment_count += 1

    # Create a dictionary with values for the AddOnAttachment object fields.
    attachment = {
        # Specifies the route for a teacher user.
        "teacherViewUri": {
            "uri":
                flask.url_for(
                    "load_content_attachment", _scheme='https', _external=True),
        },
        # Specifies the route for a student user.
        "studentViewUri": {
            "uri":
                flask.url_for(
                    "load_content_attachment", _scheme='https', _external=True)
        },
        # The title of the attachment.
        "title": f"Attachment {attachment_count}",
    }

يجب أن تكون الحقول teacherViewUri وstudentViewUri وtitle على الأقل: المقدمة لكل مرفق. teacherViewUri وstudentViewUri لتمثيل عناوين URL التي تم تحميلها عند فتح المرفق من خلال ونوع المستخدم المعني.

إرسال عنصر AddOnAttachment في نص الطلب إلى الجهة المناسبة نقطة نهاية addOnAttachments. أدخِل courseId وitemId وitemType addOnToken معرّفات لكل طلب.

Python

في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments. .

# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
    case "announcements":
        parent = classroom_service.courses().announcements()
    case "courseWorkMaterials":
        parent = classroom_service.courses().courseWorkMaterials()
    case _:
        parent = classroom_service.courses().courseWork()

# Issue a request to create the attachment.
resp = parent.addOnAttachments().create(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    addOnToken=flask.session["addOnToken"],
    body=attachment).execute()

أنشئ إدخالاً لهذا المرفق في قاعدة البيانات المحلية الخاصة بك حتى تتمكن من ذلك لاحقًا لتحميل المحتوى الصحيح. يعرض Classroom قيمة فريدة للسمة id في الرد على طلب الإنشاء، لذا استخدمه كمفتاح أساسي في قاعدة البيانات. تجدر الإشارة أيضًا إلى أنّ Classroom يجتاز attachmentId. معلَمة طلب البحث عند فتح طرق عرض المعلم والطالب:

Python

في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments. .

# Store the value by id.
new_attachment = Attachment(
    # The new attachment's unique ID, returned in the CREATE response.
    attachment_id=resp.get("id"),
    image_filename=key,
    image_caption=value)
db.session.add(new_attachment)
db.session.commit()

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

السماح بالمرفقات من الإضافة

الوقت مناسب الآن لإضافة أي عناوين مناسبة إلى المرفق المسموح به حقل بادئات معرِّف الموارد المنتظم (URI) في إعداد التطبيق ضمن حزمة تطوير البرامج (SDK) في Google Workspace Marketplace . يمكن لإضافتك إنشاء مرفقات من إحدى بادئات معرّف الموارد المنتظم (URI) فقط. مدرجة في هذه الصفحة. هذا إجراء أمني للمساعدة في تقليل احتمالية من هجمات الوسيط.

وأبسط طريقة هي تقديم نطاق المستوى الأعلى في هذا الحقل، مثال https://example.com الإجراء الذي سينفّذه https://localhost:<your port number>/ إذا كنت تستخدم جهازك المحلي كخادم الويب.

إضافة مسارات لطرق عرض المعلّمين والطلاب

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

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

طريقة عرض الطالب هي الصفحة التي يتم تقديمها لكل طالب عند فتحه. مرفق إضافة.

لأغراض هذا التمرين، أنشئ /load-content-attachment واحدًا. الذي يخدم كلاً من طريقة عرض المعلم والطلاب. استخدام Classroom API لتحديد ما إذا كان المستخدم مدرسًا أو طالبًا عند عرض صفحة التحميل.

Python

في المثال الذي قدمناه، ستجد ذلك في ملف webapp/attachment_routes.py.

@app.route("/load-content-attachment")
def load_content_attachment():
    """
    Load the attachment for the user's role."""

    # Since this is a landing page for the Teacher and Student View iframes, we
    # need to preserve the incoming query parameters.
    if flask.request.args.get("itemId"):
        flask.session["itemId"] = flask.request.args.get("itemId")
    if flask.request.args.get("itemType"):
        flask.session["itemType"] = flask.request.args.get("itemType")
    if flask.request.args.get("courseId"):
        flask.session["courseId"] = flask.request.args.get("courseId")
    if flask.request.args.get("attachmentId"):
        flask.session["attachmentId"] = flask.request.args.get("attachmentId")

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

بعد ذلك، يمكنك إرسال طلب إلى نقطة النهاية getAddOnContext التي تتطابق مع العنصر. الكتابة.

Python

في المثال الذي قدمناه، يعد ذلك استمرارًا طريقة load_content_attachment.

# Create an instance of the Classroom service.
classroom_service = googleapiclient.discovery.build(
    serviceName="classroom"
    version="v1",
    credentials=credentials)

# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
    case "announcements":
        parent = classroom_service.courses().announcements()
    case "courseWorkMaterials":
        parent = classroom_service.courses().courseWorkMaterials()
    case _:
        parent = classroom_service.courses().courseWork()

addon_context_response = parent.getAddOnContext(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"]).execute()

تعرض هذه الطريقة معلومات حول دور المستخدم الحالي في الفئة. ويمكنك تغيير طريقة العرض المعروضة للمستخدم حسب دوره. واحد بالضبط من تعبئة حقل studentContext أو teacherContext في الرد . افحصها لتحديد كيفية التعامل مع المستخدم.

على أي حال، استخدِم قيمة مَعلمة طلب البحث attachmentId لمعرفة أيّ مرفق لاستردادها من قاعدة البيانات لدينا. يتم توفير معلمة طلب البحث هذه عندما فتح معرفات الموارد المنتظمة (URI) لعرض المعلم أو الطالب.

Python

في المثال الذي قدمناه، يعد ذلك استمرارًا طريقة load_content_attachment.

# Determine which view we are in by testing the returned context type.
user_context = "student" if addon_context_response.get(
    "studentContext") else "teacher"

# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])

# Set the text for the next page depending on the user's role.
message_str = f"I see that you're a {user_context}! "
message_str += (
    f"I've loaded the attachment with ID {attachment.attachment_id}. "
    if user_context == "teacher" else
    "Please enjoy this image of a famous landmark!")

# Show the content with the customized message text.
return flask.render_template(
    "show-content-attachment.html",
    message=message_str,
    image_filename=attachment.image_filename,
    image_caption=attachment.image_caption,
    responses=response_strings)

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

أكمِل الخطوات التالية لاختبار إنشاء المرفق:

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

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

أكمِل الخطوات التالية لاختبار تجربة الطالب:

  • بعد ذلك، سجِّل الدخول إلى Classroom كمستخدم اختباري للطلاب على الصف كمستخدم اختبار المعلم.
  • ابحث عن المهمة الدراسية في علامة التبويب "الواجب الدراسي".
  • توسيع المهمة والنقر على البطاقة المُرفقة لفتح "طريقة عرض الطالب" iframe.

تأكَّد من ظهور المرفق الصحيح للطالب.

تهانينا! يمكنك الآن المتابعة إلى الخطوة التالية: إنشاء المرفقات من نوع النشاط