Allegati per tipo di contenuti

Questa è la quarta procedura dettagliata della serie dettagliata dei componenti aggiuntivi di Classroom.

In questa procedura dettagliata, interagisci con l'API Google Classroom per creare allegati. Fornisci agli utenti percorsi per visualizzare i contenuti degli allegati. Le visualizzazioni variano a seconda del ruolo dell'utente nel corso. Questa procedura dettagliata riguarda gli allegati di tipo di contenuto, che non richiedono l'invio di contenuti da parte dello studente.

Nel corso di questa procedura dettagliata, completerai quanto segue:

  • Recupera e utilizza i seguenti parametri di query dei componenti aggiuntivi:
    • addOnToken: un token di autorizzazione passato alla visualizzazione di rilevamento degli allegati.
    • itemId: un identificatore univoco per il corso, il materiale del corso o l'annuncio che riceve l'allegato del componente aggiuntivo.
    • itemType: "courseWork", "courseWorkMaterials" o "annuncio".
    • courseId: un identificatore univoco per il corso di Google Classroom in cui viene creato il compito.
    • attachmentId: un identificatore univoco assegnato da Google Classroom a un allegato di un componente aggiuntivo dopo la creazione.
  • Implementa l'archiviazione permanente per gli allegati di tipo contenuto.
  • Fornisci percorsi per creare allegati e pubblicare gli iframe di Vista insegnante e Vista studente.
  • Invia le seguenti richieste all'API dei componenti aggiuntivi di Google Classroom:
    • Crea un nuovo allegato.
    • Ottieni il contesto del componente aggiuntivo, che identifica se l'utente che ha eseguito l'accesso è uno studente o un insegnante.

Al termine, puoi creare allegati di tipo contenuto nei compiti tramite l'UI di Google Classroom dopo aver eseguito l'accesso come insegnante. Anche gli insegnanti e gli studenti della classe possono vedere i contenuti.

Abilitare l'API Classroom

Effettua chiamate all'API Classroom iniziando con questo passaggio. L'API deve essere abilitata per il tuo progetto Google Cloud prima di potervi effettuare chiamate. Accedi alla voce della raccolta dell'API Google Classroom e seleziona Abilita.

Gestire i parametri di query della visualizzazione di rilevamento degli allegati

Come illustrato in precedenza, Google Classroom passa i parametri di query quando viene caricata la visualizzazione di rilevamento degli allegati nell'iframe:

  • courseId: l'ID dell'attuale corso di Classroom.
  • itemId: un identificatore univoco per il corso, il materiale del corso o l'annuncio che riceve l'allegato del componente aggiuntivo.
  • itemType: "courseWork", "courseWorkMaterials" o "annuncio".
  • addOnToken: un token utilizzato per autorizzare determinate azioni del componente aggiuntivo di Classroom.
  • login_hint: l'ID Google dell'utente corrente.

Questa procedura dettagliata riguarda courseId, itemId, itemType e addOnToken. Conservali e passali quando effettui chiamate all'API Classroom.

Come nel passaggio della procedura dettagliata precedente, archivia i valori dei parametri di query passati nella nostra sessione. È importante eseguire questa operazione alla prima apertura della visualizzazione di rilevamento degli allegati, poiché questa è l'unica possibilità per Classroom di passare questi parametri di query.

Python

Vai al file del server Flask che fornisce le route per la visualizzazione di rilevamento degli allegati (attachment-discovery-routes.py se stai seguendo l'esempio fornito). Nella parte superiore del percorso di destinazione del componente aggiuntivo (/classroom-addon nell'esempio fornito), recupera e memorizza i parametri di query courseId, itemId, itemType e 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")

Scrivi questi valori nella sessione solo se sono presenti; non vengono ritrasmessi di nuovo se l'utente torna alla visualizzazione di rilevamento degli allegati in seguito senza chiudere l'iframe.

Aggiungere spazio di archiviazione permanente per gli allegati di tipo contenuto

Devi avere un record locale di tutti gli allegati creati. In questo modo puoi cercare i contenuti selezionati dall'insegnante utilizzando gli identificatori forniti da Classroom.

Configura uno schema di database per un Attachment. L'esempio fornito presenta allegati che mostrano un'immagine e una didascalia. Un elemento Attachment contiene i seguenti attributi:

  • attachment_id: un identificatore univoco per un allegato. Assegnato da Classroom e restituito nella risposta durante la creazione di un allegato.
  • image_filename: il nome file locale dell'immagine da visualizzare.
  • image_caption: la didascalia da mostrare con l'immagine.

Python

Estendi l'implementazione di SQLite e flask_sqlalchemy dai passaggi precedenti.

Vai al file in cui hai definito la tabella Utenti (models.py se segui l'esempio fornito). Aggiungi quanto segue in fondo al file sotto la classe 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))

Importa la nuova classe dell'allegato nel file del server con le route di gestione degli allegati.

Configura nuove route

Inizia questa procedura dettagliata impostando alcune nuove pagine nella nostra applicazione. che consentono a un utente di creare e visualizzare contenuti tramite il nostro componente aggiuntivo.

Aggiungi route per la creazione degli allegati

Hai bisogno di pagine in cui l'insegnante possa selezionare i contenuti ed emettere richieste di creazione degli allegati. Implementa il percorso /attachment-options per mostrare i contenuti che l'insegnante può selezionare. Hai bisogno anche di modelli per la selezione dei contenuti e le pagine di conferma della creazione. Gli esempi forniti contengono modelli specifici e possono anche mostrare richieste e risposte dall'API Classroom.

Tieni presente che, in alternativa, puoi modificare la pagina di destinazione esistente di rilevamento degli allegati per mostrare le opzioni dei contenuti, anziché creare la nuova pagina /attachment-options. Ti consigliamo di creare una nuova pagina ai fini di questo esercizio, in modo da preservare il comportamento SSO implementato nel secondo passaggio della procedura dettagliata, come la revoca delle autorizzazioni dell'app. Dovrebbero rivelarsi utili durante lo sviluppo e il test del componente aggiuntivo.

Un insegnante può scegliere da un piccolo insieme di immagini sottotitolate nell'esempio fornito. Abbiamo fornito quattro immagini di punti di riferimento famosi le cui didascalie derivano dai nomi dei file.

Python

Nell'esempio fornito, si trova nel file 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,
    )

Viene visualizzata una pagina "Crea allegati" simile alla seguente:

Visualizzazione di selezione dei contenuti di esempio Python

L'insegnante può selezionare più immagini. Crea un allegato per ogni immagine selezionata dall'insegnante nel metodo create_attachments.

Problema nelle richieste di creazione degli allegati

Ora che sai quali contenuti l'insegnante vuole allegare, invia all'API Classroom richieste di creazione di allegati al nostro compito. Archivia i dettagli dell'allegato nel database dopo aver ricevuto una risposta dall'API Classroom.

Inizia ottenendo un'istanza del servizio Classroom:

Python

Nell'esempio fornito, si trova nel file 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)

Invia una richiesta CREATE all'endpoint courses.courseWork.addOnAttachments. Per ogni immagine selezionata dall'insegnante, prima costruisci un oggetto AddOnAttachment:

Python

Nell'esempio fornito, questa è una continuazione del metodo 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}",
    }

Per ogni allegato devono essere forniti almeno i campi teacherViewUri, studentViewUri e title. teacherViewUri e studentViewUri rappresentano gli URL caricati quando l'allegato viene aperto dal rispettivo tipo di utente.

Invia l'oggetto AddOnAttachment nel corpo di una richiesta all'endpoint addOnAttachments appropriato. Fornisci gli identificatori courseId, itemId, itemType e addOnToken con ogni richiesta.

Python

Nell'esempio fornito, questa è una continuazione del metodo 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()

Crea una voce per questo collegamento nel tuo database locale in modo da poter caricare in un secondo momento i contenuti corretti. Classroom restituisce un valore id univoco nella risposta alla richiesta di creazione, quindi usalo come chiave primaria nel nostro database. Inoltre, Classroom trasmette il parametro di query attachmentId quando apre le viste Insegnante e Studente:

Python

Nell'esempio fornito, questa è una continuazione del metodo 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()

A questo punto, valuta la possibilità di indirizzare l'utente a una pagina di conferma, confermando di aver creato correttamente gli allegati.

Consentire gli allegati dal componente aggiuntivo

Ora è il momento giusto per aggiungere gli indirizzi appropriati al campo Prefissi URI degli allegati consentiti nella pagina Configurazione app dell'SDK Google Workspace Marketplace. Il componente aggiuntivo può creare allegati solo da uno dei prefissi URI elencati in questa pagina. È una misura di sicurezza che riduce la possibilità di attacchi man in the middle.

L'approccio più semplice consiste nell'inserire il tuo dominio di primo livello in questo campo, ad esempio https://example.com. https://localhost:<your port number>/ può funzionare se utilizzi la tua macchina locale come server web.

Aggiunta di percorsi per le viste insegnanti e studenti

Esistono quattro iframe in cui potrebbe essere caricato un componente aggiuntivo di Google Classroom. Finora hai creato solo route che pubblicano l'iframe della vista di rilevamento degli allegati. In seguito, aggiungi percorsi per pubblicare anche gli iframe della vista Insegnante e Studente.

L'iframe Visualizzazione insegnante è necessario per mostrare un'anteprima dell'esperienza degli studenti, ma può includere facoltativamente informazioni aggiuntive o funzionalità di modifica.

La Visualizzazione studente è la pagina presentata a ogni studente quando apre un allegato di un componente aggiuntivo.

Ai fini di questo esercizio, crea un unico percorso /load-content-attachment per la visualizzazione Insegnante e Studente. Usare i metodi dell'API Classroom per determinare se l'utente è un insegnante o uno studente quando la pagina viene caricata.

Python

Nell'esempio fornito, si trova nel file 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")

Tieni presente che a questo punto dovresti anche autenticare l'utente. Dovresti anche gestire il parametro di query login_hint qui e instradare l'utente al flusso di autorizzazione, se necessario. Per ulteriori informazioni su questo flusso, consulta i dettagli delle indicazioni per l'accesso discussi nelle procedure dettagliate precedenti.

Quindi, invia una richiesta all'endpoint getAddOnContext corrispondente al tipo di elemento.

Python

Nell'esempio fornito, questa è una continuazione del metodo load_content_attachment.

# Create an instance of the Classroom service.
classroom_service = googleapiclient.discovery.build(
    serviceName="classroom"
    version="v1",
    discoveryServiceUrl=f"https://classroom.googleapis.com/$discovery/rest?labels=ADD_ONS_ALPHA&key={GOOGLE_API_KEY}",
    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()

Questo metodo restituisce informazioni sul ruolo dell'utente corrente nella classe. Modificare la visualizzazione presentata all'utente in base al suo ruolo. Esattamente uno dei campi studentContext o teacherContext è compilato nell'oggetto risposta. Esaminali per stabilire come rivolgersi all'utente.

In ogni caso, utilizza il valore del parametro di query attachmentId per sapere quale allegato recuperare dal nostro database. Questo parametro di query viene fornito all'apertura degli URI della vista Insegnante o Studente.

Python

Nell'esempio fornito, questa è una continuazione del metodo 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)

Testa il componente aggiuntivo

Completa i seguenti passaggi per testare la creazione degli allegati:

  • Accedi a [Google Classroom] come uno degli utenti di test per Insegnanti.
  • Vai alla scheda Lavori del corso e crea un nuovo compito.
  • Fai clic sul pulsante Componenti aggiuntivi sotto l'area di testo e seleziona il componente aggiuntivo. L'iframe si apre e il componente aggiuntivo carica l'URI di configurazione dell'allegato che hai specificato nella pagina Configurazione app dell'SDK Google Workspace Marketplace.
  • Scegli un contenuto da allegare al compito.
  • Chiudi l'iframe al termine del flusso di creazione dell'allegato.

Dovresti vedere una scheda degli allegati nell'interfaccia utente di creazione del compito in Google Google Classroom. Fai clic sulla scheda per aprire l'iframe di Visualizzazione insegnante e verifica che appaia l'allegato corretto. Fai clic sul pulsante Assegna.

Completa i seguenti passaggi per testare l'esperienza degli studenti:

  • Accedi quindi a Classroom come utente di test dello studente nello stesso corso dell'utente di test dell'insegnante.
  • Trova il compito di prova nella scheda Lavori del corso.
  • Espandi il compito e fai clic sulla scheda dell'allegato per aprire l'iframe Visualizzazione studente.

Verifica che venga visualizzato l'allegato corretto per lo studente.

Complimenti! Puoi procedere con il passaggio successivo: creazione di allegati di tipo attività.