콘텐츠 형식 첨부파일

클래스룸 부가기능의 네 번째 둘러보기입니다. 오신 것을 환영합니다

이 둘러보기에서는 Google Classroom API와 상호작용하여 첨부파일을 들을 수 있습니다. 사용자가 첨부파일 콘텐츠를 볼 수 있는 경로를 제공합니다. 이 클래스의 사용자 역할에 따라 달라질 수 있습니다. 이 둘러보기에서는 다음을 다룹니다. 콘텐츠 유형 첨부파일: 학생 제출이 필요하지 않습니다.

이 둘러보기 과정에서 다음을 완료합니다.

  • 다음 부가기능 쿼리 매개변수를 검색하고 사용합니다.
    • addOnToken: 첨부파일 검색에 전달되는 승인 토큰입니다. 보기.
    • itemId: CourseWork, CourseWorkMaterial 또는 부가기능 첨부파일을 수신하는 공지사항입니다.
    • itemType: 'courseWork', 'courseWorkMaterials' 중 하나 또는 '공지사항'입니다.
    • courseId: Google 클래스룸 과정의 고유 식별자입니다. 확인할 수 있습니다.
    • attachmentId: Google 클래스룸에서 부가기능 첨부파일을 만듭니다.
  • 콘텐츠 유형 첨부파일을 위한 영구 저장소를 구현합니다.
  • 첨부파일을 만들고 교사 뷰 및 학생 뷰 iframe.
  • Google Classroom add-ons API에 다음 요청을 실행합니다.
    • 새 첨부파일을 만듭니다.
    • 로그인한 사용자가 현재 활성 상태인지 여부를 식별하는 부가기능 컨텍스트를 가져옵니다. 액세스할 수 있습니다

완료되면 다음을 통해 과제에 콘텐츠 형식 첨부파일을 만들 수 있습니다. Google 클래스룸 UI를 사용하는 것이 좋습니다. 교육 지역 교사 및 학생 클래스도 콘텐츠를 볼 수 있습니다.

Classroom API 사용 설정

이 단계부터 Classroom API를 호출합니다. API는 사용 설정해야 합니다. 탐색 Google Classroom API 라이브러리 항목에 추가하고 사용을 선택합니다.

첨부파일 검색 뷰 쿼리 매개변수 처리

앞서 설명한 것처럼 Google 클래스룸은 iframe에서 첨부파일 검색 보기를 로드하기:

  • courseId: 현재 클래스룸 과정의 ID입니다.
  • itemId: CourseWork, CourseWorkMaterial 또는 부가기능 첨부파일을 수신하는 공지사항입니다.
  • itemType: 'courseWork', 'courseWorkMaterials' 중 하나 '공지사항'입니다.
  • addOnToken: 특정 권한을 승인하는 데 사용되는 토큰 클래스룸 부가기능 작업
  • login_hint: 현재 사용자의 Google ID입니다.

이 둘러보기에서는 courseId, itemId, itemType, addOnToken를 다룹니다. Classroom API 호출을 실행할 때 이를 유지하고 전달합니다.

이전 둘러보기 단계에서와 같이 전달된 쿼리 매개변수 값을 시청해주시기 바랍니다 첨부파일 검색 보기가 이는 클래스룸이 이러한 쿼리 매개변수를 전달합니다

Python

첨부파일의 경로를 제공하는 Flask 서버 파일로 이동합니다. 디스커버리 뷰 (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을 닫지 않고 나중에 닫을 수 있습니다.

콘텐츠 유형 첨부파일을 위한 영구 스토리지 추가

생성된 첨부파일의 로컬 레코드가 필요합니다. 이렇게 하면 교사가 제공한 식별자를 사용해 선생님이 선택한 콘텐츠에서 클래스룸.

Attachment의 데이터베이스 스키마를 설정합니다. 제공된 예시는 이미지와 캡션을 보여주는 첨부파일입니다. Attachment에는 다음이 포함됩니다. 다음과 같은 속성이 포함됩니다.

  • attachment_id: 첨부파일의 고유 식별자입니다. 할당자 클래스룸을 만들 때 응답으로 반환됨 첨부 파일
  • 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 페이지 용도에 맞게 새 페이지를 만드는 것이 좋습니다. 두 번째 단계에서 구현된 SSO 동작을 보존할 수 있습니다. 둘러보기 단계(예: 앱 권한 취소) 이러한 연구 결과는 유용한 도구가 될 수 있습니다

교사는 Google에서 제공한 몇 가지 캡션이 있는 이미지 중에서 선택할 수 있습니다. 예로 들 수 있습니다 캡션이 표시되는 유명한 랜드마크의 이미지 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 예시 콘텐츠 선택 뷰

교사는 여러 이미지를 선택할 수 있습니다. 이미지마다 첨부파일 하나씩 만들기 교사가 create_attachments 메서드에서 선택한 값입니다.

첨부파일 생성 요청 실행

이제 교사가 첨부하고자 하는 콘텐츠를 알았으니 클래스룸 API에 요청을 보내 Google 클래스룸에서 있습니다. 파일을 받은 후 첨부파일 세부정보를 데이터베이스에 저장합니다. 클래스룸 API의 응답입니다.

먼저 클래스룸 서비스의 인스턴스를 가져옵니다.

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.addOnAttachmentsCREATE 요청을 실행합니다. 할 수 있습니다 교사가 선택한 각 이미지에 대해 먼저 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 필드는 최소한 다음과 같아야 합니다. 각 첨부파일에 제공됩니다. teacherViewUristudentViewUri 는 첨부파일을 열 때 로드되는 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()

나중에 수행할 수 있도록 로컬 데이터베이스에 이 연결의 항목을 만듭니다. 로드해야 합니다. 클래스룸에서 고유한 id 값을 반환합니다. 이(가) 있을 수 있으므로 이 키를 Google의 기본 키로 데이터베이스입니다. 또한 클래스룸은 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.com 예. https://localhost:<your port number>/ 권한 로컬 머신을 웹 서버로 사용하는 경우 작동합니다.

교사 및 학생 뷰 경로 추가

Google 클래스룸 부가기능이 로드될 수 있는 4개의 iframe이 있습니다. 첨부파일 검색 보기 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 클래스룸] 에 교사 테스트 사용자
  • 수업 과제 탭으로 이동하여 새 과제를 만듭니다.
  • 텍스트 영역 아래에서 부가기능 버튼을 클릭한 후 부가기능을 선택합니다. iframe이 열리고 부가기능에서 설정한 첨부파일 설정 URI를 로드합니다. Google Workspace Marketplace SDK의 앱 구성 페이지에 지정되어 있습니다.
  • 과제에 첨부할 콘텐츠를 선택합니다.
  • 첨부파일 만들기 과정이 완료되면 iframe을 닫습니다.

Google의 과제 만들기 UI에 첨부파일 카드가 표시됩니다. Google 클래스룸 카드를 클릭하여 교사 보기 iframe을 열고 확인합니다. 올바른 첨부파일이 표시되는지 확인합니다. 할당 버튼을 클릭합니다.

학생 환경을 테스트하려면 다음 단계를 완료하세요.

  • 그런 다음 클래스룸에 학생 테스트 사용자로 동일하게 로그인합니다. 선생님 테스트 사용자로 참여할 수 있습니다.
  • 수업 과제 탭에서 테스트 과제를 찾습니다.
  • 과제를 펼치고 첨부파일 카드를 클릭하여 학생 뷰를 엽니다. 있습니다.

학생에게 첨부파일이 올바르게 표시되는지 확인합니다.

축하합니다. 다음 단계인 만들기로 진행할 준비가 되었습니다. 활동 유형 첨부파일을 포함합니다.