Dies ist die vierte Anleitung in der Reihe zu Classroom-Add-ons.
In dieser Anleitung interagieren Sie mit der Google Classroom API, um Anhänge zu erstellen. Sie stellen Nutzern Pfade zum Ansehen des Anhangs zur Verfügung. Die Ansichten unterscheiden sich je nach Rolle des Nutzers im Kurs. In dieser Anleitung geht es um Anhänge mit Inhaltstyp, für die keine Einreichung durch Schüler oder Studenten erforderlich ist.
In dieser Anleitung führen Sie die folgenden Schritte aus:
- Rufen Sie die folgenden Add-on-Abfrageparameter ab und verwenden Sie sie:
addOnToken
: Ein Autorisierungstoken, das an die Ansicht „Anhänge – Suche“ übergeben wird.itemId
: Eine eindeutige Kennung für die Kursarbeit, das Kursarbeitsmaterial oder die Mitteilung, an die der Add-on-Anhang angehängt wird.itemType
: Entweder „courseWork“, „courseWorkMaterials“ oder „announcement“.courseId
: Eine eindeutige Kennung für den Google Classroom-Kurs, in dem die Aufgabe erstellt wird.attachmentId
: Eine eindeutige Kennung, die einem Add-on-Anhang nach der Erstellung von Google Classroom zugewiesen wird.
- Implementieren Sie einen nichtflüchtigen Speicher für Anhänge mit Inhaltstypen.
- Geben Sie Routen an, um Anhänge zu erstellen und die Iframes für die Ansicht der Lehrkraft und die Ansicht der Schüler/Studenten zu senden.
- Senden Sie die folgenden Anfragen an die Google Classroom Add-ons API:
- Erstellen Sie einen neuen Anhang.
- Rufen Sie den Add-on-Kontext ab, der angibt, ob der angemeldete Nutzer ein Schüler/Student oder eine Lehrkraft ist.
Wenn Sie fertig sind, können Sie über die Google Classroom-Benutzeroberfläche Anhänge mit Inhaltstypen für Aufgaben erstellen, wenn Sie als Lehrkraft angemeldet sind. Auch Lehrkräfte und Schüler/Studenten im Kurs können sich die Inhalte ansehen.
Classroom API aktivieren
Rufen Sie ab diesem Schritt die Classroom API auf. Die API muss für Ihr Google Cloud-Projekt aktiviert sein, bevor Sie sie aufrufen können. Rufen Sie den Bibliothekseintrag für die Google Classroom API auf und wählen Sie Aktivieren aus.
Umgang mit den Suchparametern der Ansicht „Anhänge – Suche“
Wie bereits erwähnt, übergibt Google Classroom Abfrageparameter beim Laden der Ansicht „Anhängesuche“ im IFrame:
courseId
: Die ID des aktuellen Classroom-Kurses.itemId
: Eine eindeutige Kennung für die Kursarbeit, das Kursarbeitsmaterial oder die Mitteilung, an die der Add-on-Anhang angehängt wird.itemType
: Entweder „courseWork“, „courseWorkMaterials“ oder „announcement“.addOnToken
: Ein Token, mit dem bestimmte Aktionen von Classroom-Add-ons autorisiert werden.login_hint
: Die Google-ID des aktuellen Nutzers.
In dieser Anleitung geht es um courseId
, itemId
, itemType
und addOnToken
.
Behalten Sie diese bei und geben Sie sie beim Ausführen von Aufrufen an die Classroom API weiter.
Wie im vorherigen Schritt speichern wir die übergebenen Suchparameterwerte in unserer Sitzung. Das ist wichtig, wenn die Ansicht „Anhängesuche“ zum ersten Mal geöffnet wird, da dies die einzige Möglichkeit ist, dass Classroom diese Abfrageparameter übergeben kann.
Python
Rufen Sie die Flask-Serverdatei auf, die Routen für die Discovery-Ansicht für Anhänge enthält (attachment-discovery-routes.py
, wenn Sie unserem Beispiel folgen). Rufen Sie oben in der Add-on-Landingpage-Route (/classroom-addon
in unserem Beispiel) die Abfrageparameter courseId
, itemId
, itemType
und addOnToken
ab und speichern Sie sie.
# 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")
Diese Werte werden nur in die Sitzung geschrieben, wenn sie vorhanden sind. Sie werden nicht noch einmal übergeben, wenn der Nutzer später zur Ansicht „Anhänge finden“ zurückkehrt, ohne den IFrame zu schließen.
Nichtflüchtigen Speicher für Anhänge mit Inhaltstyp hinzufügen
Sie benötigen einen lokalen Datensatz aller erstellten Anhänge. So können Sie die Inhalte, die der Lehrer ausgewählt hat, anhand der von Classroom bereitgestellten IDs aufrufen.
Richten Sie ein Datenbankschema für eine Attachment
ein. In unserem Beispiel sind Anhänge mit einem Bild und einer Bildunterschrift zu sehen. Ein Attachment
enthält die folgenden Attribute:
attachment_id
: Eine eindeutige Kennung für einen Anhang. Wird von Classroom zugewiesen und in der Antwort zurückgegeben, wenn ein Anhang erstellt wird.image_filename
: Der lokale Dateiname des anzuzeigenden Bilds.image_caption
: Die Bildunterschrift, die mit dem Bild angezeigt werden soll.
Python
Erweitern Sie die SQLite- und flask_sqlalchemy
-Implementierung aus den vorherigen Schritten.
Rufen Sie die Datei auf, in der Sie die Nutzertabelle definiert haben (models.py
, wenn Sie unserem Beispiel folgen). Fügen Sie unten in der Datei unter der Klasse User
Folgendes hinzu:
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))
Importieren Sie die neue Anhangsklasse in die Serverdatei mit Ihren Routen für die Anhangsverwaltung.
Neue Routen einrichten
Beginnen Sie mit diesem Schritt, indem Sie einige neue Seiten in unserer Anwendung einrichten. Mit diesen können Nutzer Inhalte über unser Add-on erstellen und ansehen.
Routen zum Erstellen von Anhängen hinzufügen
Sie benötigen Seiten, auf denen die Lehrkräfte Inhalte auswählen und Anträge auf das Erstellen von Anhängen stellen können. Implementieren Sie die Route /attachment-options
, um Inhaltsoptionen für die Auswahl durch die Lehrkraft anzuzeigen. Außerdem benötigen Sie Vorlagen für die Seiten zur Auswahl der Inhalte und zur Bestätigung der Erstellung. Die bereitgestellten Beispiele enthalten Vorlagen für diese und können auch die Anfragen und Antworten der Classroom API anzeigen.
Sie können auch die Landingpage Ihrer vorhandenen Ansicht für die Suche nach Anhängen ändern, um die Inhaltsoptionen anzuzeigen, anstatt eine neue /attachment-options
-Seite zu erstellen. Wir empfehlen, für diese Übung eine neue Seite zu erstellen, damit das im zweiten Schritt der Anleitung implementierte SSO-Verhalten erhalten bleibt, z. B. der Widerruf der App-Berechtigungen. Diese sollten Ihnen beim Erstellen und Testen Ihres Add-ons nützlich sein.
In unserem Beispiel kann eine Lehrkraft aus einer kleinen Auswahl von Bildern mit Untertiteln auswählen. Wir haben vier Bilder berühmter Sehenswürdigkeiten bereitgestellt, deren Bildunterschriften aus den Dateinamen abgeleitet sind.
Python
In unserem Beispiel befindet sich diese in der Datei 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,
)
Daraufhin wird die Seite „Anhänge erstellen“ angezeigt, die in etwa so aussieht:
Der Lehrer kann mehrere Bilder auswählen. Erstellen Sie einen Anhang für jedes Bild, das die Lehrkraft mit der Methode create_attachments
ausgewählt hat.
Anfragen zum Erstellen von Anhängen stellen
Da Sie jetzt wissen, welche Inhalte der Lehrer anhängen möchte, senden Sie Anfragen an die Classroom API, um Anhänge für die Aufgabe zu erstellen. Speichern Sie die Details des Anhangs in Ihrer Datenbank, nachdem Sie eine Antwort von der Classroom API erhalten haben.
Rufen Sie zuerst eine Instanz des Classroom-Dienstes ab:
Python
In unserem Beispiel befindet sich diese in der Datei 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)
Stelle eine CREATE
-Anfrage an den Endpunkt courses.courseWork.addOnAttachments
. Erstellen Sie für jedes von der Lehrkraft ausgewählte Bild zuerst ein AddOnAttachment
-Objekt:
Python
In unserem Beispiel ist dies eine Fortsetzung der create_attachments
-Methode.
# 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}",
}
Für jeden Anhang müssen mindestens die Felder teacherViewUri
, studentViewUri
und title
angegeben werden. teacherViewUri
und studentViewUri
stehen für die URLs, die geladen werden, wenn der Anhang vom jeweiligen Nutzertyp geöffnet wird.
Sende das AddOnAttachment
-Objekt im Anfragetext an den entsprechenden addOnAttachments
-Endpunkt. Geben Sie bei jeder Anfrage die IDs courseId
, itemId
, itemType
und addOnToken
an.
Python
In unserem Beispiel ist dies eine Fortsetzung der create_attachments
-Methode.
# 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()
Erstellen Sie einen Eintrag für diesen Anhang in Ihrer lokalen Datenbank, damit Sie später die richtigen Inhalte laden können. Classroom gibt in der Antwort auf die Erstellungsanfrage einen eindeutigen id
-Wert zurück. Verwenden Sie diesen als Primärschlüssel in unserer Datenbank. Beachten Sie auch, dass Classroom den Abfrageparameter attachmentId
übergibt, wenn die Ansichten für Lehrkräfte und Schüler/Studenten geöffnet werden:
Python
In unserem Beispiel ist dies eine Fortsetzung der create_attachments
-Methode.
# 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()
Sie können den Nutzer an dieser Stelle auf eine Bestätigungsseite weiterleiten, auf der er sieht, dass er Anhänge erstellt hat.
Anhänge aus Ihrem Add-on zulassen
Fügen Sie jetzt auf der Seite App-Konfiguration des Google Workspace Marketplace SDK im Feld „Zulässige URI-Präfixe für Anhänge“ alle entsprechenden Adressen hinzu. Ihr Add-on kann nur Anhänge über eines der auf dieser Seite aufgeführten URI-Präfixe erstellen. Dies ist eine Sicherheitsmaßnahme, die das Risiko von Man-in-the-Middle-Angriffen verringern soll.
Am einfachsten geben Sie in diesem Feld Ihre Top-Level-Domain an, z. B. https://example.com
. https://localhost:<your port number>/
würde funktionieren, wenn Sie Ihren lokalen Computer als Webserver verwenden.
Routen für die Ansichten „Lehrkraft“ und „Schüler/Student“ hinzufügen
Es gibt vier Iframes, in die ein Google Classroom-Add-on geladen werden kann. Sie haben bisher nur Routen erstellt, über die der iFrame der Discovery-Ansicht für Anhänge ausgeliefert wird. Fügen Sie als Nächstes Routen hinzu, um auch die Iframes für die Ansichten von Lehrkräften und Schülern zu senden.
Der IFrame für die Lehrkraftansicht ist erforderlich, um eine Vorschau der Schüler-/Studentenoberfläche anzuzeigen. Er kann aber auch optional zusätzliche Informationen oder Bearbeitungsfunktionen enthalten.
Die Ansicht für Schüler/Studenten ist die Seite, die jedem Schüler/Studenten angezeigt wird, wenn er einen Add-on-Anhang öffnet.
Erstellen Sie für diese Übung eine einzelne /load-content-attachment
-Route, die sowohl für die Ansicht der Lehrkräfte als auch für die der Schüler/Studenten verwendet wird. Verwenden Sie Classroom API-Methoden, um beim Laden der Seite zu ermitteln, ob der Nutzer eine Lehrkraft oder ein Schüler/Student ist.
Python
In unserem Beispiel befindet sich diese in der Datei 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")
Denken Sie daran, dass Sie den Nutzer an dieser Stelle auch authentifizieren sollten. Hier solltest du auch den Abfrageparameter login_hint
verarbeiten und den Nutzer bei Bedarf zu deinem Autorisierungsablauf weiterleiten. Weitere Informationen zu diesem Ablauf finden Sie in den Details zur Anmeldung, die in den vorherigen Schritt-für-Schritt-Anleitungen erläutert wurden.
Sende dann eine Anfrage an den getAddOnContext
-Endpunkt, der dem Artikeltyp entspricht.
Python
In unserem Beispiel ist dies eine Fortsetzung der Methode 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()
Diese Methode gibt Informationen zur Rolle des aktuellen Nutzers im Kurs zurück.
Die Ansicht, die dem Nutzer angezeigt wird, kann je nach Rolle geändert werden. Im Antwortobjekt ist genau eines der Felder studentContext
oder teacherContext
ausgefüllt. Anhand dieser Informationen können Sie bestimmen, wie Sie den Nutzer ansprechen.
Verwenden Sie in jedem Fall den Wert des Abfrageparameters attachmentId
, um zu erfahren, welcher Anhang aus unserer Datenbank abgerufen werden soll. Dieser Abfrageparameter wird beim Öffnen der URIs für die Ansicht der Lehrkraft oder der Schüler/Studenten angegeben.
Python
In unserem Beispiel ist dies eine Fortsetzung der Methode 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)
Add-on testen
Führen Sie die folgenden Schritte aus, um das Erstellen von Anhängen zu testen:
- Melden Sie sich in [Google Classroom] als einer Ihrer Lehrkraft-Testnutzer an.
- Rufen Sie den Tab Kursaufgaben auf und erstellen Sie eine neue Aufgabe.
- Klicken Sie unter dem Textfeld auf die Schaltfläche Add-ons (Add-ons) und wählen Sie das gewünschte Add-on aus. Der Iframe wird geöffnet und das Add-on lädt den URI für die Einrichtung von Anhängen, den Sie auf der Seite App-Konfiguration des Google Workspace Marketplace SDK angegeben haben.
- Wählen Sie einen Inhalt aus, den Sie der Aufgabe anhängen möchten.
- Schließen Sie den IFrame, nachdem der Vorgang zum Erstellen des Anhangs abgeschlossen ist.
In der Benutzeroberfläche zum Erstellen von Aufgaben in Google Classroom sollte eine Anhängekarte angezeigt werden. Klicken Sie auf die Karte, um den Iframe für die Ansicht des Lehrers zu öffnen, und prüfen Sie, ob der richtige Anhang angezeigt wird. Klicken Sie auf die Schaltfläche Zuweisen.
Führen Sie die folgenden Schritte aus, um die Nutzerfreundlichkeit für Schüler und Studenten zu testen:
- Melden Sie sich dann als Schüler-/Studenten-Testnutzer in Classroom in demselben Kurs an wie der Testnutzer für Lehrkräfte.
- Sie finden die Testaufgabe auf dem Tab „Aufgaben“.
- Maximieren Sie die Aufgabe und klicken Sie auf die Karte „Anhang“, um den IFrame für die Schüler-/Studentenansicht zu öffnen.
Prüfen Sie, ob der richtige Anhang für den Schüler/Studenten angezeigt wird.
Glückwunsch! Sie können mit dem nächsten Schritt fortfahren: Anhänge vom Typ „Aktivität“ erstellen.