Allegati per tipo di contenuti

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

In questa procedura dettagliata, interagisci con l'API Google Classroom per creare allegati. Sei tu a fornire agli utenti i percorsi per visualizzare i contenuti degli allegati. Le visualizzazioni variano in base al ruolo dell'utente nel corso. Questa procedura dettagliata riguarda gli allegati dei tipi di contenuti, che non richiedono l'invio da parte di uno studente.

Nel corso di questa procedura dettagliata, eseguirai quanto segue:

  • Recupera e utilizza i seguenti parametri di query del componente aggiuntivo:
    • addOnToken: un token di autorizzazione passato alla vista di rilevamento degli allegati.
    • itemId: un identificatore univoco per CourseWork, CourseWorkMaterial o all'interno dell'annuncio che riceve l'allegato del componente aggiuntivo.
    • itemType: "courseWork", "courseWorkMaterials" o "announcement".
    • 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 del componente aggiuntivo dopo la creazione.
  • Implementa l'archiviazione permanente per gli allegati di tipo contenuto.
  • Fornisci i percorsi per creare allegati e pubblicare gli iframe della Vista insegnante e della Visualizzazione studente.
  • Invia le seguenti richieste all'API Google Classroom add-ons:
    • Crea un nuovo allegato.
    • Scarica 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 sui compiti tramite l'interfaccia utente di Google Classroom dopo aver eseguito l'accesso come insegnante. Anche insegnanti e studenti del corso possono vedere i contenuti.

Attivare l'API Classroom

Effettua chiamate all'API Classroom iniziando da questo passaggio. L'API deve essere abilitata per il progetto Google Cloud prima di poter effettuare chiamate al progetto. Vai alla voce della raccolta dell'API Google Classroom e scegli Abilita.

Gestire i parametri di query della visualizzazione di rilevamento degli allegati

Come spiegato in precedenza, Google Classroom passa i parametri di query durante il caricamento della visualizzazione Attachment Discovery nell'iframe:

  • courseId: l'ID del corso di Classroom corrente.
  • itemId: un identificatore univoco per CourseWork, CourseWorkMaterial o all'interno dell'annuncio che riceve l'allegato del componente aggiuntivo.
  • itemType: "courseWork", "courseWorkMaterials" o "announcement".
  • addOnToken: un token utilizzato per autorizzare determinate azioni dei componenti aggiuntivi di Classroom.
  • login_hint: l'ID Google dell'utente corrente.
  • hd: il dominio host dell'utente corrente, ad esempio example.com.

Questa procedura dettagliata riguarda courseId, itemId, itemType e addOnToken. Conservale e trasmettile quando invii chiamate all'API Classroom.

Come nel passaggio della procedura dettagliata precedente, memorizza i valori dei parametri di query trasmessi nella nostra sessione. È importante farlo quando viene aperta per la prima volta la visualizzazione Scoperta degli allegati, poiché si tratta dell'unica opportunità per Classroom di passare questi parametri di query.

Python

Vai al file del server Flask che fornisce le route per la visualizzazione Attachment Discovery (attachment-discovery-routes.py se stai seguendo il nostro 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 passati di nuovo se l'utente torna alla visualizzazione di rilevamento degli allegati in un secondo momento senza chiudere l'iframe.

Aggiungi spazio di archiviazione permanente per gli allegati per tipo di contenuto

Hai bisogno di 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 Attachment contiene i seguenti attributi:

  • attachment_id: l'identificatore univoco di 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 stai seguendo l'esempio fornito). Aggiungi quanto segue alla fine del file sotto il corso 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 degli allegati nel file del server con i percorsi di gestione degli allegati.

Configura nuovi percorsi

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

Aggiungi route per la creazione di allegati

L'insegnante ha bisogno di pagine in cui selezionare i contenuti e inviare richieste di creazione degli allegati. Implementa il percorso /attachment-options per mostrare le opzioni dei contenuti che l'insegnante può selezionare. Sono necessari anche modelli per le pagine di conferma della selezione e della creazione dei contenuti. Gli esempi forniti contengono modelli che possono anche visualizzare le richieste e le risposte dall'API Classroom.

Tieni presente che, in alternativa, puoi modificare la tua pagina di destinazione esistente di Visualizzazione degli allegati per visualizzare le opzioni di contenuto 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 app. Dovrebbero essere utili durante la creazione 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 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 della 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 con le richieste di creazione di allegati

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

Inizia recuperando 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.
    # We need to request the Classroom API from a specific URL while add-ons
    # are in Early Access.

    # A Google API Key can be created in your Google Cloud project's Credentials
    # settings: https://console.cloud.google.com/apis/credentials.
    # Click "Create Credentials" at top and choose "API key", then provide
    # the key in the discoveryServiceUrl below.
    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)

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

Python

Nell'esempio fornito, si tratta di 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}",
    }

Devi fornire almeno i campi teacherViewUri, studentViewUri e title per ogni allegato. teacherViewUri e studentViewUri rappresentano gli URL caricati quando l'allegato viene aperto dal tipo di utente corrispondente.

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, si tratta di 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 seguito il contenuto corretto. Classroom restituisce un valore id univoco nella risposta alla richiesta di creazione, pertanto utilizzalo come chiave primaria nel database. Tieni inoltre presente che Classroom passa il parametro di query attachmentId quando si apre la vista Insegnante e Studente:

Python

Nell'esempio fornito, si tratta di 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, con l'avviso di aver creato gli allegati correttamente.

Consentire gli allegati dal componente aggiuntivo

Questo è il momento giusto per aggiungere gli indirizzi appropriati nel campo Prefissi URI degli allegati consentiti nella pagina Configurazione app SDK GWM. Il componente aggiuntivo può creare allegati solo da uno dei prefissi URI elencati in questa pagina. Questa è una misura di sicurezza per ridurre la possibilità di attacchi man in the middle.

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

Aggiunta di percorsi per le visualizzazioni Insegnante e Studente

Sono quattro gli iframe in cui potrebbe essere caricato un componente aggiuntivo di Google Classroom. Finora hai creato solo route che servono l'iframe della visualizzazione Origine degli allegati. In seguito, aggiungi le route per pubblicare anche gli iframe della visualizzazione per insegnanti e studenti.

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

La visualizzazione studente è la pagina che viene presentata a ogni studente quando apre un allegato del componente aggiuntivo.

Ai fini di questo esercizio, crea un singolo percorso /load-content-attachment che funzioni sia per la Vista insegnante che per la Vista Studente. Utilizza 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 devi anche autenticare l'utente. Dovresti anche gestire i parametri di query login_hint e hd qui e indirizzare l'utente al flusso di autorizzazione, se necessario. Per ulteriori informazioni su questo flusso, consulta i dettagli delle indicazioni di accesso discussi nelle procedure dettagliate precedenti.

Quindi invia una richiesta all'endpoint getAddOnContext che corrisponde 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. Modifica la visualizzazione presentata all'utente in base al suo ruolo. Uno dei campi studentContext o teacherContext viene compilato esattamente nell'oggetto risposta. Esaminali per stabilire come rivolgerti all'utente.

In ogni caso, utilizza il valore del parametro di query attachmentId per sapere quale allegato recuperare dal database. Questo parametro di query viene fornito all'apertura degli URI della visualizzazione 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

Per testare la creazione degli allegati, procedi nel seguente modo:

  • Accedi a [Google Classroom] come utente di test Insegnante.
  • 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 GWM.
  • Scegli un contenuto da allegare al compito.
  • Chiudi l'iframe al termine del flusso di creazione dell'allegato.

Dovresti vedere una scheda per gli allegati nell'interfaccia utente per la creazione dei compiti in Google Google Classroom. Fai clic sulla scheda per aprire l'iframe della Visualizzazione insegnante e confermare che venga visualizzato l'allegato corretto. Fai clic sul pulsante Assegna.

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

  • Accedi quindi a Classroom come studente/utente di test nello stesso corso dell'utente di test insegnante.
  • Individua il compito di prova nella scheda Lavori del corso.
  • Espandi il compito e fai clic sulla scheda dell'allegato per aprire l'iframe della 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à.