內容類型附件

這是 Classroom 外掛程式的第第四個逐步操作說明 這一系列的影片

在本逐步操作說明中,您將與 Google Classroom API 互動以建立 附件。您可以為使用者提供查看附件內容的路徑。 檢視畫面會視使用者在類別中的角色而定。這份逐步操作說明會介紹 內容類型附件,不要求學生繳交。

在這份逐步操作說明中,您將完成下列步驟:

  • 擷取並使用下列外掛程式查詢參數:
    • addOnToken:傳遞至連結探索的授權權杖 View。
    • itemId:CourseWork、CourseWorkMaterial 或 接收外掛程式附件的公告。
    • itemType:"courseWork"、"courseWorkMaterials"或 「公告」。
    • courseId:Google Classroom 課程的專屬 ID 正在建立作業
    • attachmentId:Google Classroom 指派給 外掛程式附件
  • 針對內容類型附件實作永久儲存空間。
  • 提供建立附件的路徑,以及提供老師檢視畫面 學生檢視 iframe。
  • 向 Google Classroom 外掛程式 API 發出下列要求:
    • 建立新附件。
    • 取得外掛程式內容,識別登入的使用者是否為 學生或老師。

完成後,您就可以透過以下方式為作業建立內容類型附件: Google Classroom UI。以下課程的老師和學生: 也可以查看課程內容。

啟用 Classroom API

如要呼叫 Classroom API,請先完成這個步驟。API 必須 必須先啟用 Google Cloud 專案,才能開始呼叫導航 Google Classroom API 程式庫項目,然後選擇「啟用」

處理附件探索檢視查詢參數

先前所述,Google Classroom 會在 在 iframe 中載入附件探索檢視:

  • courseId:目前 Classroom 課程的 ID。
  • itemId:CourseWork、CourseWorkMaterial 或 接收外掛程式附件的公告。
  • itemType:"courseWork"、"courseWorkMaterials"或「公告」
  • addOnToken:用來授權特定人員的符記 Classroom 外掛程式動作。
  • login_hint:目前使用者的 Google ID。

這份逐步操作說明會介紹 courseIditemIditemTypeaddOnToken 等資訊。 發出呼叫 Classroom API 時保留並傳送這些記錄。

如先前的逐步操作步驟所示,將傳遞的查詢參數值儲存在 課程。請務必在「附件探索檢視」功能下 因為這是 Classroom 的唯一機會 傳送這些查詢參數

Python

前往提供附件路徑的 Flask 伺服器檔案 探索檢視模式 (如果您正在追蹤我們的「attachment-discovery-routes.py」 提供的範例)。外掛程式登陸路線頂端 (目前提供的範例中為 /classroom-addon),請擷取並儲存 courseIditemIditemTypeaddOnToken 查詢參數。

# 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

為內容類型附件新增永久儲存空間

你需要留存任何已建立附件的本機記錄。以便查詢 教師使用 提供的 ID 所選的內容 Classroom。

設定 Attachment 的資料庫結構定義。提供的範例 含有圖片和說明文字的附件Attachment 包含 以下屬性:

  • attachment_id:附件的專屬 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)

courses.courseWork.addOnAttachments 發出 CREATE 要求 端點先為老師選取的每張圖片建構 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}",
    }

至少要有 teacherViewUristudentViewUrititle 欄位 。《teacherViewUri》和《studentViewUri》 代表該檔案開啟附件時載入的網址 每種使用者類型

將要求主體中的 AddOnAttachment 物件傳送至適當的 addOnAttachments 端點。請提供 courseIditemIditemTypeaddOnToken ID。

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()

建議您在這個階段將使用者引導至確認頁面,進行確認 已成功建立附件

允許透過外掛程式存取附件

建議您趁現在將任何適當的位址新增至允許的附件 Google Workspace Marketplace SDK「應用程式設定」中的「URI 前置字串」欄位 頁面。外掛程式只能從其中一個 URI 前置字串建立連結 並列在本頁面這項安全措施有助於降低 中間人攻擊

最簡單的方法是在此欄位中輸入頂層網域,以 範例 https://example.comhttps://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()

這個方法會傳回目前使用者在類別中的角色相關資訊。 根據使用者的角色,修改顯示的檢視畫面。恰好是其中一個 系統會在回應中填入 studentContextteacherContext 欄位 物件。請檢查這些問題,判斷如何回應使用者。

無論如何,使用 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 的「App Configuration」頁面指定)。
  • 選擇要附加到作業中的一段內容。
  • 附件建立流程完成後,請關閉 iframe。

您應該會在 Google 的作業建立 UI 中看到附件資訊卡 Google Classroom點選資訊卡即可開啟教師檢視畫面 iframe 畫面上會顯示正確的附件按一下「指派」按鈕。

如要測試學生的學習體驗,請完成下列步驟:

  • 然後,以學生測試使用者身分登入 Classroom 課程。
  • 在「課堂作業」分頁中找出測試作業。
  • 展開作業,然後按一下附件資訊卡,開啟學生檢視畫面 iframe。

確認系統為學生顯示正確的附件。

恭喜!您已準備好繼續進行下一個步驟:建立 活動類型附件