קבצים מצורפים מסוג תוכן

זוהי ההדרכה המפורטת הרביעית בנושא תוספים ל-Classroom של הדרכות מפורטות.

בהדרכה המפורטת הזו, תוכלו להשתמש ב-Google Classroom API כדי ליצור קבצים מצורפים. אתם מספקים למשתמשים מסלולים לצפייה בתוכן של הקבצים המצורפים. מספר הצפיות משתנה בהתאם לתפקיד של המשתמש בכיתה. ההדרכה המפורטת הזו כוללת קבצים מצורפים מסוג תוכן, שלא מצריכים הגשה של תלמיד.

ההדרכה המפורטת כוללת את הדברים הבאים:

  • מאחזרים את הפרמטרים הבאים של שאילתות לתוסף ומשתמשים בהם:
    • addOnToken: אסימון הרשאה שמועבר לחיפוש הקבצים המצורפים צפייה.
    • itemId: מזהה ייחודי של CourseWork, CourseWorkMaterial או הודעה עם הקובץ המצורף של התוסף.
    • itemType: "courseWork" , "courseWorkMaterials" או "annonce".
    • courseId: מזהה ייחודי של הקורס ב-Google Classroom ב- שבה המטלה נוצרת.
    • attachmentId: מזהה ייחודי שהוקצה על ידי Google Classroom קובץ מצורף של תוסף לאחר היצירה.
  • הטמעת אחסון מתמיד לקבצים מצורפים מסוג תוכן.
  • מתן מסלולים ליצירת קבצים מצורפים ולהצגה של 'תצוגה למורים' iframes של תצוגת תלמידים.
  • לשלוח את הבקשות הבאות ל-Google Classroom לתוספים:
    • יצירת קובץ מצורף חדש.
    • לקבל את ההקשר של התוסף, שמזהה אם המשתמש שמחובר לחשבון לתלמיד/ה או למורה.

כשתסיימו, תוכלו ליצור קבצים מצורפים מסוג תוכן במטלות באמצעות את ממשק המשתמש של Google Classroom כשהם מחוברים כמורים. מורים ותלמידים ב הכיתה גם תוכל לצפות בתוכן.

הפעלה של Classroom API

צריך לבצע קריאות ל-Classroom API החל מהשלב הזה. על ה-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.

כמו בשלב הקודם בהדרכה המפורטת, שומרים את ערכי הפרמטרים של השאילתה שהועברו את הסשן שלנו. חשוב לעשות זאת כשתצוגת גילוי הקבצים המצורפים נפתחה לראשונה, כי זו ההזדמנות היחידה של Classroom להעביר את הפרמטרים האלה של השאילתה.

Python

עוברים לקובץ שרת Flask שמספק מסלולים לקובץ המצורף Discovery View (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.

הוספת אחסון מתמיד לקבצים מסוג תוכן

צריכה להיות לכם רשומה מקומית של כל הקבצים המצורפים שנוצרו. כך אפשר לחפש תוכן שהמורה בחר באמצעות מזהים שסופקו על ידי Google 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 כדי להציג אפשרויות תוכן שהמורה יכול/ה לבחור. נדרשות גם תבניות לבחירת התוכן דפי אישור יצירה. הדוגמאות שסיפקנו כוללות תבניות עבור והוא גם יכול להציג את הבקשות והתשובות API של Classroom.

לתשומת ליבך, אפשר במקום זאת לשנות את תצוגת הגילוי של הקבצים המצורפים דף נחיתה כדי להציג את אפשרויות התוכן במקום ליצור את דף /attachment-options. מומלץ ליצור דף חדש למטרות בתרגיל הזה כדי לשמר את התנהגות ה-SSO שמוטמעת הדרכה מפורטת, כמו ביטול ההרשאות לאפליקציה. הם אמורים להוכיח שיעזרו לכם לבנות ולבדוק את התוסף.

מורה יכולה לבחור מתוך קבוצה קטנה של תמונות עם כתוביות לדוגמה. סיפקנו ארבע תמונות של ציוני דרך מפורסמים שהכתוביות שלהם נגזר משמות הקבצים.

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' בהגדרת האפליקציה של Google Workspace Marketplace SDK הדף הזה. התוסף יכול ליצור קבצים מצורפים רק מאחת מהקידומות של ה-URI שמפורטים בדף הזה. זהו אמצעי אבטחה שנועד לצמצם את הסיכוי של התקפות אדם בתווך.

הגישה הפשוטה ביותר היא לציין את הדומיין ברמה העליונה בשדה הזה, לדוגמה https://example.com. https://localhost:<your port number>/ ירצה פועל אם אתם משתמשים במחשב המקומי כשרת האינטרנט.

הוספת מסלולים לתצוגה של 'מורים' ושל 'תלמידים'

יש ארבעה רכיבי iframe שבהם ניתן לטעון תוסף של Google Classroom. יש לכם רק מסלולים שנוצרו ל-iframe של תצוגת Discovery של קבצים מצורפים רחוק. בשלב הבא מוסיפים מסלולים כדי להציג גם את מסגרות ה-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 ולנתב את המשתמש אל את תהליך ההרשאה, אם יש צורך. עיין בפרטי ההנחיות להתחברות שעליהם דיברנו בהדרכות מפורטות קודמות כדי לקבל מידע נוסף על התהליך הזה.

לאחר מכן צריך לשלוח בקשה לנקודת הקצה (endpoint) 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 של הגדרת הקובץ המצורף שאתם שמצוין בדף הגדרת האפליקציה של Google Workspace Marketplace SDK.
  • בוחרים קטע תוכן שיצורף למטלה.
  • סוגרים את ה-iframe בסיום תהליך יצירת הקובץ המצורף.

כרטיס מצורף אמור להופיע בממשק המשתמש ליצירת מטלה ב-Google. Google Classroom לוחצים על הכרטיס כדי לפתוח את ה-iframe של תצוגת המורים ולאשר כדי שיופיע הקובץ המצורף הנכון. לוחצים על הלחצן הקצאה.

כך בודקים את חוויית התלמידים:

  • לאחר מכן נכנסים ל-Classroom בתור משתמש מבחן של התלמידים בתור משתמש מבחן של מורה.
  • מוצאים את המטלה בכרטיסייה 'עבודות'.
  • כדי לפתוח את התצוגה לתלמידים, מרחיבים את המטלה ולוחצים על הכרטיס של הקובץ המצורף. iframe.

מוודאים שהקובץ המצורף הנכון מופיע עבור התלמיד/ה.

מעולה! עכשיו אפשר להמשיך לשלב הבא: יצירת קבצים מצורפים מסוג פעילות.