Anexos externos e entregas

Este é o sétimo tutorial da série de complementos do Google Sala de Aula.

Neste tutorial, você vai adicionar um comportamento a um aplicativo da Web para criar anexos de complementos fora do Google Sala de Aula. Use esse comportamento para permitir que os usuários criem anexos de complementos do seu produto ou site. Essa também é uma ótima adição a uma integração com CourseWork, porque você direciona o tráfego existente para a experiência do usuário aprimorada oferecida pelo seu complemento sem alterar o fluxo. O processo sugerido é apresentado na página do guia Criar anexos fora do Google Sala de Aula.

Você também adiciona um comportamento ao complemento para modificar uma atribuição com anexos de complementos de maneira programática. É possível modificar qualquer atribuição que tenha um dos anexos de complemento, independentemente de quem a criou. Isso é especialmente útil para entregar atividades depois que um estudante concluir uma atividade, sinalizando para o professor que as tarefas atribuídas foram concluídas e o trabalho do estudante está pronto para revisão.

Estenda a versão final do complemento com suporte a content-type ou anexos de tipo de atividade. O anexo de tipo de conteúdo é usado neste guia.

Adicionar o escopo do OAuth de gerenciamento de atribuições

Verifique se o aplicativo solicita os seguintes escopos:

  • https://www.googleapis.com/auth/classroom.addons.teacher
  • https://www.googleapis.com/auth/classroom.addons.student
  • https://www.googleapis.com/auth/classroom.coursework.students

O escopo classroom.coursework.students não era necessário anteriormente e é usado para criar ou modificar atribuições CourseWork. Adicione esse escopo às listas de escopos no SDK do Google Workspace Marketplace, na tela de consentimento do OAuth e no código do servidor do seu projeto do Cloud.

Python

  SCOPES = [
    "https://www.googleapis.com/auth/classroom.addons.teacher",
    "https://www.googleapis.com/auth/classroom.addons.student",
    "https://www.googleapis.com/auth/classroom.coursework.students",
  ]

Criar uma atividade no Google Sala de Aula

Adicionar botões a uma página da Web sem iframe

O fluxo descrito neste tutorial permite que um usuário crie atividades e anexos do Google Sala de Aula usando um produto de terceiros. Na prática, é provável que seja seu site ou aplicativo atual. Neste exemplo, você precisa criar uma página da Web fictícia para atuar como um site externo. Você precisa de um botão ou link que, quando clicado, abre uma nova rota que execute o fluxo CourseWork sugerido para criar uma nova atribuição.

Você também precisará adicionar um botão ou link para permitir que o usuário faça login, caso ainda não tenha um. Você precisará de credenciais de usuário para fazer as solicitações subsequentes da API. Portanto, elas precisarão concluir o handshake do OAuth 2.0. Consulte as instruções de login para orientações específicas.

Python

O exemplo de Python fornecido modifica a rota /index que foi introduzida na primeira etapa do tutorial.

<!-- /webapp/templates/index.html -->
<a href="clear-credentials.html">Logout</a>
<a href="start-auth-flow.html">Login</a>

<br>

<a href="create-coursework-assignment.html">Create a CourseWork Assignment</a>

Adicione um modelo HTML para representar um destino no seu site. Essa página representará o conteúdo que será anexado à sua atribuição CourseWork.

<!-- /webapp/templates/example-coursework-assignment.html -->
<h1>CourseWork assignment loaded!</h1>
<p>You've loaded a CourseWork assignment! It was created from an external web page.</p>

Crie um arquivo do módulo Python para gerenciar as rotas relacionadas ao CourseWork. Esse é coursework_routes.py no exemplo fornecido. Adicione as três rotas a seguir. Observe que você preencherá parte do conteúdo mais tarde.

# /webapp/coursework_routes.py
@app.route("/create-coursework-assignment")
def create_coursework_assignment():
  """
  Completes the assignment creation flow.
  """

  # Check that the user is signed in. If not, perform the OAuth 2.0
  # authorization flow.
  credentials = get_credentials()

  if not credentials:
    return start_auth_flow("coursework_assignment_callback")

  # Construct the Google Classroom service.
  classroom_service = get_classroom_service()

  pass  # To be completed later.

@app.route("/example-coursework-assignment/<assignment_type>")
def example_coursework_assignment(assignment_type):
  """
  Renders the "example-coursework-assignment.html" template.
  """
  return flask.render_template(
      "example-coursework-assignment.html", assignment_type=assignment_type
  )

@app.route("/coursework-assignment-callback")
def coursework_assignment_callback():
  """
  Completes the OAuth 2.0 handshake and stores credentials in the session.
  This is identical to the callback introduced in the sign-in walkthrough,
  but redirects the user to the index page instead of the attachment
  discovery page.
  """
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE,
      scopes=SCOPES,
      state=flask.session["state"],
      redirect_uri=flask.url_for("coursework_assignment_callback", _external=True),
  )

  flow.fetch_token(authorization_response=flask.request.url)

  credentials = flow.credentials
  flask.session["credentials"] = session_credentials_to_dict(
      credentials
  )

  # Close the current window and redirect the user to the index page.
  return flask.render_template("close-me.html", redirect_destination="index")

Verificar a qualificação para a criação de complementos de um usuário

Há vários pré-requisitos que um usuário precisa atender para que você possa criar anexos de complementos em nome dele. Por conveniência, o Google oferece o método courses.checkAddOnCreationEligibility para determinar se um usuário atende a esses pré-requisitos. Um usuário que atenda aos pré-requisitos é chamado de usuário qualificado.

Adicione a verificação de qualificação à implementação da rota de criação do CourseWork. Em seguida, teste o campo isCreateAttachmentEligible na resposta. Para usuários qualificados, siga a lógica para criar uma atribuição com anexo de complemento. Caso contrário, crie um Link Material. Você precisa saber o ID do curso em que o usuário quer criar uma atividade. Normalmente, você solicita que o usuário especifique qual curso usar. Para simplificar, usamos um valor codificado neste exemplo.

Python

# /webapp/coursework_routes.py
@app.route("/create-coursework-assignment")
def create_coursework_assignment():
  """
  Completes the assignment creation flow.
  """
  # ... Check that the user is signed in and get the Classroom service ...

  # The ID of the course to which the assignment will be added.
  course_id = 1234567890  # TODO(developer) Replace with an actual course ID.

  # Check whether the user can create add-on attachments.
  eligibility_response = (
      classroom_service.courses()
      .checkAddOnCreationEligibility(courseId=course_id)
      .execute()
  )
  is_create_attachment_eligible = eligibility_response.get("isCreateAttachmentEligible")

  if is_create_attachment_eligible:
    # See the "Create an assignment with add-on attachment for eligible users" section for implementation.
  if not is_create_attachment_eligible:
    # See the "Create a Link Material" section for implementation.

Criar uma atividade com anexo de complemento para usuários qualificados

Se o usuário estiver qualificado para criar anexos de complementos, faça o seguinte:

  1. Envie uma solicitação de API para criar uma atividade courseWork no Google Sala de Aula sem anexos.
  2. Extraia o id da atribuição recém-criada.
  3. Criar um novo CourseWork AddOnAttachment.
  4. Envie uma solicitação para criar um anexo de complemento na atividade recém-criada no Google Sala de Aula.

Python

# /webapp/coursework_routes.py
if is_create_attachment_eligible:
  # Create an assignment.
  coursework = {
      "title": "My CourseWork Assignment with Add-on Attachment",
      "description": "Created using the Classroom CourseWork API.",
      "workType": "ASSIGNMENT",
      "state": "DRAFT",  # Set to 'PUBLISHED' to assign to students.
  }

  # Issue a request to create the assignment.
  create_assignment_response = (
      classroom_service.courses()
      .courseWork()
      .create(courseId=course_id, body=coursework)
      .execute()
  )

  # Create an add-on attachment that links to the selected content and
  # associate it with the new assignment.
  content_url = flask.url_for(
      "example_coursework_assignment",
      assignment_type="add-on-attachment",
      _scheme="https",
      _external=True,
  )

  # Construct an AddOnAttachment instance.
  attachment = {
      "teacherViewUri": {"uri": content_url},
      "studentViewUri": {"uri": content_url},
      "title": f'Test Attachment for Assignment {create_assignment_response.get("id")}',
  }

  # Issue a request to create the attachment.
  add_on_attachment_response = (
      classroom_service.courses()
      .courseWork()
      .addOnAttachments()
      .create(
          courseId=course_id,
          itemId=create_assignment_response.get("id"),  # ID of the new assignment.
          body=attachment,
      )
      .execute()
  )

Se o usuário não estiver qualificado para criar anexos de complementos, crie um Material de link fazendo o seguinte:

Python

if not is_create_attachment_eligible:
    coursework = {
        "title": "My CourseWork Assignment with Link Material",
        "description": "Created using the Classroom CourseWork API.",
        "workType": "ASSIGNMENT",
        "state": "DRAFT",  # Set to 'PUBLISHED' to assign to students.
        # Specify the URL for your content as a Link Material.
        "materials": [
            {
                "link": {
                    "url": flask.url_for(
                        "example_coursework_assignment",
                        assignment_type="link-material",
                        _scheme="https",
                        _external=True,
                    )
                }
            }
        ],
    }

    # Issue a request to create the assignment.
    assignment_response = (
        classroom_service.courses()
        .courseWork()
        .create(courseId=course_id, body=coursework)
        .execute()
    )

Modificar uma atribuição já criada

Você pode acessar, modificar, entregar, recuperar ou devolver qualquer item de fluxo do Google Sala de Aula que tenha pelo menos um anexo de complemento, independentemente de quem criou o item do stream. Os itens de stream são qualquer atribuição Announcement, CourseWork ou CourseWorkMaterial.

Para demonstrar isso, adicione uma rota para modificar um determinado item de stream. Use esse método para verificar se você pode acessar e modificar itens do mural criados por você usando a API e criados por um professor na interface do Google Sala de Aula.

Adicione mais um link ou botão à página da Web editada pela primeira vez neste tutorial. Ele precisa abrir uma nova rota para modificar uma atribuição CourseWork.

Python

O exemplo de Python fornecido modifica a rota /index que foi modificada anteriormente neste tutorial.

<!-- /webapp/templates/index.html -->
<a href="modify-coursework-assignment.html">Create a CourseWork Assignment</a>

Crie uma rota para os trajetos relacionados ao CourseWork. Isso está no arquivo coursework_routes.py do exemplo fornecido.

# Check that the user is signed in.
credentials = get_credentials()

if not credentials:
  return start_auth_flow("coursework_assignment_callback")

# Get the Google Classroom service.
classroom_service = get_classroom_service()

# The ID of the course to which the assignment will be added.
# Ordinarily, you'll prompt the user to specify which course to use. For
# simplicity, we use a hard-coded value in this example.
course_id = 1234567890  # TODO(developer) Replace with an actual course ID.
assignment_id = 1234567890  # TODO(developer) Replace with an actual assignment ID.

# Retrieve details about the CourseWork assignment.
get_coursework_response = (
    classroom_service.courses()
    .courseWork()
    .get(courseId=course_id, id=assignment_id)
    .execute()
)

# Alter the current title.
assignment_title = f"{get_coursework_response.get('title')} (Modified by API request)"

# Issue a request to modify the assignment.
modify_coursework_response = (
    classroom_service.courses()
    .courseWork()
    .patch(
        courseId=course_id,
        id=assignment_id,
        updateMask="title",
        body={"title": assignment_title},
    )
    .execute()
)

Testar o complemento

Para simplificar, os exemplos fornecidos usam identificadores codificados de curso e de atribuição. Para receber esses identificadores, faça solicitações com credenciais de professor aos métodos get e list dos recursos courses e courseWork. Elas também são retornadas na resposta ao criar atribuições courseWork.

Execute seu servidor, navegue até a página de índice e faça login como usuário professor sem uma licença Teaching & Learning ou Plus do Google Workspace for Education. Você pode alternar o status da licença de um usuário no Admin Console do domínio de teste.Clique no botão Criar uma atividade do curso, abra a interface do Google Sala de Aula e verifique se uma atividade com um anexo do Material Design foi criada. O anexo deve mostrar o título da página da Web vinculada e um URL.

Testar a criação do anexo de complementos

Volte à página de índice e faça login como usuário professor com uma licença Teaching & Learning ou Plus do Google Workspace for Education. Clique no botão Create a CourseWork Assignment, abra a interface do Google Sala de Aula e verifique se uma atividade com um anexo de complemento foi criada. O anexo deve mostrar o nome do aplicativo complementar e o título especificado no código.

Testar modificação da atribuição

Volte à página de índice e verifique se você fez login como usuário professor com uma licença do Teaching & Learning ou Plus. Clique no botão Modificar uma tarefa do curso, volte à interface do Google Sala de Aula e verifique se o título da atividade foi alterado.

Parabéns! Você concluiu a série de tutoriais.