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 Routen bereit, über die Nutzer den Inhalt des Anhangs ansehen können. Die Ansichten unterscheiden sich je nach Rolle des Nutzers im Kurs. In dieser Schritt-für-Schritt-Anleitung geht es um Anhänge vom Typ „Inhalt“, für die keine Aufgabenabgabe durch Schüler oder Studenten erforderlich ist.
Im Laufe dieser Anleitung führen Sie folgende Schritte aus:
- Die folgenden Abfrageparameter für Add-ons abrufen und verwenden:
addOnToken: Ein Autorisierungstoken, das an die Ansicht zur Suche nach Anhängen übergeben wird.itemId: Eine eindeutige Kennung für die Kursaufgabe, das Kursmaterial oder die Mitteilung, die den Add-on-Anhang erhält.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 von Google Classroom nach der Erstellung einem Add-on-Anhang zugewiesen wird.
- Nichtflüchtiger Speicher für Anhänge vom Typ „Inhalt“ implementieren.
- Routen zum Erstellen von Anhängen und zum Bereitstellen der iFrames für die Ansicht für Lehrkräfte und die Ansicht für Schüler/Studenten bereitstellen.
- Die folgenden Anfragen an die Google Classroom Add-ons API senden:
- Einen neuen Anhang erstellen.
- Den Add-on-Kontext abrufen, der angibt, ob der angemeldete Nutzer ein Schüler/Student oder eine Lehrkraft ist.
Nach Abschluss dieser Anleitung können Sie als Lehrkraft angemeldet über die Google Classroom-Benutzeroberfläche Anhänge vom Typ „Inhalt“ zu Aufgaben hinzufügen. Lehrkräfte und Schüler/Studenten im Kurs können sich die Inhalte ebenfalls ansehen.
Classroom API aktivieren
Ab diesem Schritt können Sie Anfragen an die Classroom API senden. Die API muss für Ihr Google Cloud-Projekt aktiviert sein, bevor Sie Anfragen senden können. Rufen Sie den Bibliothekseintrag der Google Classroom API auf und wählen Sie Aktivieren aus.
Abfrageparameter für die Ansicht zur Suche nach Anhängen verarbeiten
Wie bereits erwähnt, übergibt Google Classroom Abfrageparameter, wenn die Ansicht zur Suche nach Anhängen im iFrame geladen wird:
courseId: Die ID des aktuellen Classroom-Kurses.itemId: Eine eindeutige Kennung für die Kursaufgabe, das Kursmaterial oder die Mitteilung, die den Add-on-Anhang erhält.itemType: Entweder „courseWork“, „courseWorkMaterials“ oder „announcement“.addOnToken: Ein Token, das zur Autorisierung bestimmter Classroom-Add-on-Aktionen verwendet wird.login_hint: Die Google-ID des aktuellen Nutzers.
In dieser Anleitung werden courseId, itemId, itemType und addOnToken behandelt.
Behalten Sie diese bei und übergeben Sie sie, wenn Sie Anfragen an die Classroom API senden.
Wie im vorherigen Schritt der Anleitung speichern Sie die übergebenen Abfrageparameterwerte in Ihrer Sitzung. Das ist wichtig, wenn die Ansicht zur Suche nach Anhängen zum ersten Mal geöffnet wird, da dies die einzige Möglichkeit für Classroom ist, diese Suchparameter zu übergeben.
Python
Rufen Sie die Flask-Serverdatei auf, die Routen für die Ansicht zur Suche nach Anhängen bereitstellt (attachment-discovery-routes.py, wenn Sie unserem bereitgestellten Beispiel folgen). Rufen Sie oben in der Landingpage-Route für Ihr Add-on (/classroom-addon in unserem bereitgestellten 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")
Schreiben Sie diese Werte nur in die Sitzung, wenn sie vorhanden sind. Sie werden nicht noch einmal übergeben, wenn der Nutzer später zur Ansicht zur Suche nach Anhängen zurückkehrt, ohne den iFrame zu schließen.
Nichtflüchtigen Speicher für Anhänge vom Typ „Inhalt“ hinzufügen
Sie benötigen einen lokalen Datensatz aller erstellten Anhänge. So können Sie die Inhalte, die die Lehrkraft ausgewählt hat, anhand der von Classroom bereitgestellten Kennungen nachschlagen.
Richten Sie ein Datenbankschema für einen Attachment ein. In unserem bereitgestellten Beispiel werden Anhänge mit einem Bild und einer Bildunterschrift angezeigt. 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 Bildes.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 Tabelle „User“ definiert haben (models.py, wenn Sie unserem bereitgestellten 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 Klasse „Attachment“ in die Serverdatei mit Ihren Routen zur Anhängeverwaltung.
Neue Routen einrichten
Beginnen Sie diesen Schritt der Anleitung, indem Sie einige neue Seiten in Ihrer Anwendung einrichten. So können Nutzer über Ihr Add-on Inhalte erstellen und ansehen.
Routen zum Erstellen von Anhängen hinzufügen
Sie benötigen Seiten, auf denen die Lehrkraft Inhalte auswählen und Anfragen zum Erstellen von Anhängen senden kann. Implementieren Sie die Route /attachment-options, um Inhaltsoptionen anzuzeigen, die die Lehrkraft auswählen kann. Außerdem benötigen Sie Vorlagen für die Seiten zur Auswahl von Inhalten und zur Bestätigung der Erstellung. Unsere bereitgestellten Beispiele enthalten Vorlagen für diese Seiten und können auch die Anfragen und Antworten der Classroom API anzeigen.
Alternativ können Sie auch die vorhandene Landingpage für die Ansicht zur Suche nach Anhängen ändern, um die Inhaltsoptionen anzuzeigen, anstatt die neue Seite /attachment-options zu erstellen. Wir empfehlen, für die Zwecke von
dieser Übung eine neue Seite zu erstellen, damit Sie das SSO-Verhalten beibehalten, das im zweiten
Schritt der Anleitung implementiert wurde, z. B. den Widerruf der App-Berechtigungen. Diese sollten sich beim Erstellen und Testen Ihres Add-ons als nützlich erweisen.
In unserem bereitgestellten Beispiel kann eine Lehrkraft aus einer kleinen Auswahl von Bildern mit Bildunterschriften auswählen. Wir haben vier Bilder von berühmten Wahrzeichen bereitgestellt, deren Bildunterschriften aus den Dateinamen abgeleitet sind.
Python
In unserem bereitgestellten Beispiel befindet sich dies 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,
)
Dadurch wird eine Seite „Anhänge erstellen“ erstellt, die so aussieht:
Die Lehrkraft kann mehrere Bilder auswählen. Erstellen Sie in der Methode create_attachments für jedes von der Lehrkraft ausgewählte Bild einen Anhang.
Anfragen zum Erstellen von Anhängen senden
Nachdem Sie nun wissen, welche Inhalte die Lehrkraft anhängen möchte, senden Sie Anfragen an die Classroom API, um Anhänge zu Ihrer 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 bereitgestellten Beispiel befindet sich dies 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)
Senden Sie eine CREATE-Anfrage an den courses.courseWork.addOnAttachments
Endpunkt. Erstellen Sie für jedes von der Lehrkraft ausgewählte Bild zuerst ein
AddOnAttachment Objekt:
Python
In unserem bereitgestellten Beispiel ist dies eine Fortsetzung der Methode 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}",
}
Für jeden Anhang müssen mindestens die Felder teacherViewUri, studentViewUri und title angegeben werden. teacherViewUri und studentViewUri stellen die URLs dar, die geladen werden, wenn der Anhang vom jeweiligen Nutzertyp geöffnet wird.
Senden Sie das AddOnAttachment-Objekt im Textkörper einer Anfrage an den entsprechenden Endpunkt addOnAttachments. Geben Sie mit jeder Anfrage die Kennungen courseId, itemId, itemType und addOnToken an.
Python
In unserem bereitgestellten Beispiel ist dies eine Fortsetzung der Methode 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()
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 Ihrer Datenbank. Beachten Sie außerdem, dass Classroom den Abfrageparameter attachmentId übergibt, wenn die Ansicht für Lehrkräfte und die Ansicht für Schüler/Studenten geöffnet werden:
Python
In unserem bereitgestellten Beispiel ist dies eine Fortsetzung der Methode 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()
Sie können den Nutzer an dieser Stelle zu einer Bestätigungsseite weiterleiten, auf der bestätigt wird, dass er Anhänge erstellt hat.
Anhänge aus Ihrem Add-on zulassen
Jetzt ist ein guter Zeitpunkt, um dem Feld „Zulässige URI-Präfixe für Anhänge“ auf der Seite „App-Konfiguration“ des Google Workspace Marketplace SDK alle entsprechenden Adressen hinzuzufügen. Ihr Add-on kann nur Anhänge aus einem der auf dieser Seite aufgeführten URI-Präfixe erstellen. Dies ist eine Sicherheitsmaßnahme, um die Wahrscheinlichkeit von Man-in-the-Middle-Angriffen zu verringern.
Der einfachste Ansatz besteht darin, Ihre Top-Level-Domain in diesem Feld anzugeben, 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 Ansicht für Lehrkräfte und die Ansicht für Schüler/Studenten hinzufügen
Es gibt vier iFrames, in denen ein Google Classroom-Add-on geladen werden kann. Bisher haben Sie nur Routen erstellt, die den iFrame für die Ansicht zur Suche nach Anhängen bereitstellen. Fügen Sie als Nächstes Routen hinzu, um auch die iFrames für die Ansicht für Lehrkräfte und die Ansicht für Schüler/Studenten bereitzustellen.
Der iFrame Ansicht für Lehrkräfte ist erforderlich, um eine Vorschau der Ansicht für Schüler/Studenten zu zeigen. Er kann aber optional zusätzliche Informationen oder Bearbeitungsfunktionen enthalten.
Die Ansicht für Schüler/Studenten ist die Seite, die jedem Schüler oder Studenten angezeigt wird, wenn er einen Add-on-Anhang öffnet.
Erstellen Sie für diese Übung eine einzelne Route /load-content-attachment, die sowohl die Ansicht für Lehrkräfte als auch die Ansicht für Schüler/Studenten bereitstellt. Verwenden Sie Classroom API-Methoden, um zu ermitteln, ob der Nutzer eine Lehrkraft oder ein Schüler/Student ist, wenn die Seite geladen wird.
Python
In unserem bereitgestellten Beispiel befindet sich dies 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. Außerdem sollten Sie hier den Abfrageparameter login_hint verarbeiten und den Nutzer gegebenenfalls zu Ihrem Autorisierungsablauf weiterleiten. Weitere Informationen zu diesem Ablauf finden Sie in der Anleitung zur Anmeldung, die in den vorherigen Schritt-für-Schritt-Anleitungen behandelt wurde.
Senden Sie dann eine Anfrage an den Endpunkt getAddOnContext, der dem Elementtyp entspricht.
Python
In unserem bereitgestellten 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.
Ändern Sie die Ansicht, die dem Nutzer präsentiert wird, je nach seiner Rolle. Im Antwort
objekt wird genau eines der
studentContext oder teacherContext Felder ausgefüllt. Prüfen Sie diese Felder, um zu ermitteln, wie Sie den Nutzer ansprechen sollen.
Verwenden Sie in jedem Fall den attachmentId Parameterwert, um zu ermitteln, welcher Anhang aus unserer Datenbank abgerufen werden soll. Dieser Abfrageparameter wird beim Öffnen der URIs für die Ansicht für Lehrkräfte oder die Ansicht für Schüler/Studenten bereitgestellt.
Python
In unserem bereitgestellten 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 die Erstellung 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 und wählen Sie Ihr 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, der an die Aufgabe angehängt werden soll.
- Schließen Sie den iFrame, nachdem der Ablauf zum Erstellen von Anhängen abgeschlossen ist.
In der Benutzeroberfläche zum Erstellen von Aufgaben in Google Classroom sollte eine Anhangskarte angezeigt werden. Klicken Sie auf die Karte, um den iFrame für die Ansicht für Lehrkräfte zu öffnen und zu bestätigen, dass der richtige Anhang angezeigt wird. Klicken Sie auf die Schaltfläche Zuweisen.
Führen Sie die folgenden Schritte aus, um die Ansicht für Schüler/Studenten zu testen:
- Melden Sie sich dann in Classroom als Testnutzer mit der Rolle „Schüler/Student“ im selben Kurs wie der Testnutzer mit der Rolle „Lehrkraft“ an.
- Suchen Sie auf dem Tab „Kursaufgaben“ nach der Testaufgabe.
- Maximieren Sie die Aufgabe und klicken Sie auf die Anhangskarte, um den iFrame für die Ansicht für Schüler/Studenten zu öffnen.
Prüfen Sie, ob der richtige Anhang für den Schüler oder Studenten angezeigt wird.
Glückwunsch! Sie können mit dem nächsten Schritt fortfahren: Anhänge vom Typ „Aktivität“ erstellen.