ไฟล์แนบประเภทเนื้อหา

นี่คือคำแนะนำแบบทีละขั้นที่ 4 ในส่วนเสริมของ Classroom คำแนะนำแบบทีละขั้น

ในคำแนะนำแบบทีละขั้นนี้ คุณจะต้องโต้ตอบกับ Google Classroom API เพื่อสร้าง ไฟล์แนบ คุณสามารถระบุเส้นทางให้ผู้ใช้ดูเนื้อหาไฟล์แนบได้ ยอดดูจะแตกต่างกันไปตามบทบาทของผู้ใช้ในชั้นเรียน คำแนะนำแบบทีละขั้นนี้ครอบคลุม ไฟล์แนบที่เป็นประเภทเนื้อหา ซึ่งไม่ต้องให้นักเรียนส่ง

ในคำแนะนำแบบทีละขั้นนี้ คุณจะต้องทำดังนี้

  • ดึงข้อมูลและใช้พารามิเตอร์การค้นหาส่วนเสริมต่อไปนี้
    • addOnToken: โทเค็นการให้สิทธิ์ที่ส่งไปยังการค้นพบไฟล์แนบ View นั้น
    • itemId: ตัวระบุที่ไม่ซ้ำกันสำหรับ CourseWork, CourseWorkMaterial หรือ ประกาศที่ได้รับไฟล์แนบของส่วนเสริม
    • itemType: ไม่ว่าจะเป็น "courseWork", "courseWorkMaterials" หรือ "announcement"
    • courseId: ตัวระบุที่ไม่ซ้ำกันสำหรับหลักสูตร Google Classroom ใน ที่กำลังสร้างงานอยู่
    • attachmentId: ตัวระบุที่ไม่ซ้ำกันซึ่ง Google Classroom กำหนดให้ใช้กับ ไฟล์แนบของส่วนเสริมหลังการสร้าง
  • ใช้พื้นที่เก็บข้อมูลถาวรสำหรับไฟล์แนบประเภทเนื้อหา
  • ระบุเส้นทางในการสร้างไฟล์แนบและนำเสนอมุมมองของครูและ iframe มุมมองของนักเรียน
  • ส่งคำขอต่อไปนี้ไปยัง API ส่วนเสริมของ Google Classroom
    • สร้างไฟล์แนบใหม่
    • รับบริบทของส่วนเสริม ซึ่งจะระบุว่าผู้ใช้ที่เข้าสู่ระบบเป็น นักเรียนหรือครู

เมื่อเสร็จแล้ว คุณสามารถสร้างไฟล์แนบประเภทเนื้อหาในงานได้ผ่าน UI ของ 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 ที่ระบุเส้นทางสำหรับไฟล์แนบ มุมมองการสำรวจ (attachment-discovery-routes.py หากคุณกำลังติดตาม ตัวอย่างที่ให้ไว้) ที่ด้านบนของเส้นทาง Landing Page ของส่วนเสริม (/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

โปรดทราบว่าคุณสามารถเลือกแก้ไขมุมมองการค้นพบไฟล์แนบที่มีอยู่ หน้า Landing Page เพื่อแสดงตัวเลือกเนื้อหา แทนการสร้าง ใหม่ /attachment-options หน้า เราขอแนะนำให้สร้างหน้าเว็บใหม่เพื่อวัตถุประสงค์ แบบฝึกหัดนี้เพื่อให้คุณเก็บลักษณะการใช้งาน SSO ที่นำไปใช้ใน คำแนะนำแบบทีละขั้น เช่น การเพิกถอนสิทธิ์ของแอป สิ่งเหล่านี้ควรพิสูจน์ได้ มีประโยชน์ในการสร้างและทดสอบส่วนเสริม

ครูสามารถเลือกจากชุดรูปภาพสั้นๆ ที่มีคำบรรยายในรูปภาพ เราให้รูปภาพของจุดสังเกตที่มีชื่อเสียง 4 ภาพ ซึ่งมีคำอธิบายภาพ ที่มาจากชื่อไฟล์

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

ครูสามารถเลือกรูปภาพหลายรูป สร้างไฟล์แนบ 1 ไฟล์สำหรับแต่ละรูปภาพ ที่ครูเลือกไว้ในเมธอด 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 4 รายการที่ระบบอาจโหลดส่วนเสริมของ Google Classroom คุณได้สร้างเฉพาะเส้นทางที่แสดง iframe ของมุมมองการค้นพบไฟล์แนบ ดังนั้น ไกล จากนั้นเพิ่มเส้นทางเพื่อแสดง iframe มุมมองของครูและนักเรียนด้วย

ต้องใช้ iframe ของ Teacher View เพื่อแสดงตัวอย่างของนักเรียน แต่อาจรวมถึงข้อมูลเพิ่มเติมหรือการแก้ไข ใหม่ๆ

มุมมองของนักเรียนคือหน้าที่แสดงต่อนักเรียนแต่ละคนเมื่อเปิด ไฟล์แนบของส่วนเสริม

สำหรับวัตถุประสงค์ของแบบฝึกหัดนี้ ให้สร้าง /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 การตั้งค่าไฟล์แนบที่คุณ ที่ระบุไว้ในหน้าการกำหนดค่าแอปของ Google Workspace Marketplace SDK
  • เลือกเนื้อหาที่จะแนบไปกับงาน
  • ปิด iframe หลังจากขั้นตอนการสร้างไฟล์แนบเสร็จสมบูรณ์

คุณควรเห็นการ์ดไฟล์แนบปรากฏใน UI การสร้างงานใน Google Google Classroom คลิกการ์ดเพื่อเปิด iframe ของ Teacher View และยืนยัน ไฟล์แนบที่ถูกต้องจะปรากฏขึ้น คลิกปุ่มมอบหมาย

ทำตามขั้นตอนต่อไปนี้เพื่อทดสอบประสบการณ์ของนักเรียน

  • จากนั้นลงชื่อเข้าใช้ Classroom ในฐานะผู้ใช้ทดสอบของนักเรียนใน ชั้นเรียนในฐานะผู้ใช้ทดสอบของครู
  • ค้นหางานทดสอบในแท็บงานของชั้นเรียน
  • ขยายงานและคลิกการ์ดไฟล์แนบเพื่อเปิดมุมมองของนักเรียน iframe

ตรวจสอบว่าไฟล์แนบที่ถูกต้องปรากฏสำหรับนักเรียน

ยินดีด้วย คุณพร้อมที่จะไปยังขั้นตอนถัดไปแล้ว: การสร้าง ไฟล์แนบประเภทกิจกรรม