Ini adalah panduan keempat dalam seri panduan add-on Classroom.
Dalam panduan ini, Anda akan berinteraksi dengan Google Classroom API untuk membuat lampiran. Anda memberikan rute bagi pengguna untuk melihat konten lampiran. Tampilan akan berbeda, bergantung pada peran pengguna di class. Panduan ini mencakup lampiran jenis konten, yang tidak memerlukan kiriman siswa.
Dalam kursus ini, Anda akan menyelesaikan hal-hal berikut:
- Ambil dan gunakan parameter kueri add-on berikut:
addOnToken
: Token otorisasi yang diteruskan ke Tampilan Penemuan Lampiran.itemId
: ID unik untuk CourseWork, CourseWorkMaterial, atau Pengumuman yang menerima lampiran add-on.itemType
: "courseWork", "courseWorkMaterials", atau "announcement".courseId
: ID unik untuk kursus Google Classroom tempat tugas dibuat.attachmentId
: ID unik yang ditetapkan oleh Google Classroom ke lampiran add-on setelah dibuat.
- Menerapkan penyimpanan persisten untuk lampiran jenis konten.
- Memberikan rute untuk membuat lampiran dan menayangkan iframe Tampilan Pengajar dan Tampilan Siswa.
- Berikan permintaan berikut ke API add-on Google Classroom:
- Buat lampiran baru.
- Dapatkan konteks add-on, yang mengidentifikasi apakah pengguna yang login adalah siswa atau pengajar.
Setelah selesai, Anda dapat membuat lampiran jenis konten pada tugas melalui UI Google Classroom saat login sebagai pengajar. Pengajar dan siswa di kelas juga dapat melihat kontennya.
Mengaktifkan Classroom API
Lakukan panggilan ke Classroom API dimulai dari langkah ini. API harus diaktifkan untuk project Google Cloud sebelum Anda dapat melakukan panggilan ke project tersebut. Buka entri library Google Classroom API, lalu pilih Aktifkan.
Menangani parameter kueri Tampilan Penemuan Lampiran
Seperti yang telah dibahas sebelumnya, Google Classroom meneruskan parameter kueri saat memuat Tampilan Penemuan Lampiran dalam iframe:
courseId
: ID kursus Classroom saat ini.itemId
: ID unik untuk CourseWork, CourseWorkMaterial, atau Pengumuman yang menerima lampiran add-on.itemType
: "courseWork", "courseWorkMaterials", atau "announcement".addOnToken
: Token yang digunakan untuk mengizinkan tindakan add-on Classroom tertentu.login_hint
: ID Google pengguna saat ini.hd
: Domain host untuk pengguna saat ini, sepertiexample.com
.
Panduan ini membahas courseId
, itemId
, itemType
, dan addOnToken
.
Pertahankan dan teruskan panggilan tersebut saat melakukan panggilan ke Classroom API.
Seperti pada langkah panduan sebelumnya, simpan parameter value kueri yang diteruskan dalam sesi kita. Penting bagi kita untuk melakukannya saat Tampilan Penemuan Lampiran pertama kali dibuka, karena ini adalah satu-satunya kesempatan bagi Classroom untuk meneruskan parameter kueri ini.
Python
Buka file server Flask Anda yang menyediakan rute untuk Tampilan Discovery Lampiran (attachment-discovery-routes.py
jika Anda mengikuti contoh yang kami berikan). Di bagian atas rute landing add-on Anda (/classroom-addon
dalam contoh yang diberikan), ambil dan simpan parameter kueri courseId
, itemId
, itemType
, dan 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")
Tulis nilai ini ke sesi hanya jika ada. Nilai tersebut tidak akan diteruskan lagi jika pengguna kebetulan kembali ke Tampilan Penemuan Lampiran nanti tanpa menutup iframe.
Menambahkan penyimpanan persisten untuk lampiran jenis konten
Anda memerlukan data lokal untuk setiap lampiran yang dibuat. Hal ini memungkinkan Anda mencari konten yang dipilih pengajar menggunakan ID yang diberikan oleh Classroom.
Siapkan skema database untuk Attachment
. Contoh yang diberikan adalah lampiran
yang menunjukkan gambar dan {i>caption<i}. Attachment
berisi
atribut berikut:
attachment_id
: ID unik untuk lampiran. Ditetapkan oleh Classroom dan ditampilkan sebagai respons saat membuat lampiran.image_filename
: Nama file lokal gambar yang akan ditampilkan.image_caption
: Teks yang akan ditampilkan bersama gambar.
Python
Perluas implementasi SQLite dan flask_sqlalchemy
dari langkah sebelumnya.
Buka file tempat Anda telah menentukan tabel Pengguna (models.py
jika Anda mengikuti contoh yang kami berikan). Tambahkan kode berikut di bagian bawah
file di bawah class 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))
Impor class Lampiran baru ke dalam file server dengan rute penanganan lampiran Anda.
Menyiapkan rute baru
Mulai langkah panduan ini dengan menyiapkan beberapa halaman baru di aplikasi kita. Fitur ini memungkinkan pengguna membuat dan melihat konten melalui add-on kami.
Menambahkan rute pembuatan lampiran
Anda memerlukan halaman bagi pengajar untuk memilih konten dan mengeluarkan permintaan
pembuatan lampiran. Terapkan rute /attachment-options
untuk menampilkan opsi konten
yang dapat dipilih pengajar. Anda juga memerlukan {i>template<i} untuk halaman pemilihan konten dan
konfirmasi pembuatan. Contoh yang kami berikan berisi template untuk ini,
dan juga dapat menampilkan permintaan serta respons dari
Classroom API.
Perlu diperhatikan bahwa Anda dapat mengubah halaman landing Tampilan Penemuan Lampiran yang ada untuk menampilkan opsi konten, bukan membuat halaman /attachment-options
baru. Sebaiknya buat halaman baru untuk tujuan
latihan ini agar Anda dapat mempertahankan perilaku SSO yang diterapkan dalam langkah
panduan kedua, seperti pencabutan izin aplikasi. Ini seharusnya terbukti
berguna saat Anda membangun dan menguji add-on Anda.
Pengajar dapat memilih dari serangkaian kecil gambar teks dalam contoh yang kami berikan. Kami telah menyediakan empat gambar bangunan terkenal yang teksnya diambil dari nama file.
Python
Dalam contoh yang diberikan, file ini ada dalam 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,
)
Tindakan ini akan menghasilkan halaman "Buat Lampiran" yang terlihat seperti berikut:
Pengajar dapat memilih beberapa gambar. Buat satu lampiran untuk setiap gambar
yang dipilih pengajar di metode create_attachments
.
Permintaan pembuatan lampiran masalah
Setelah Anda mengetahui konten mana yang ingin dilampirkan oleh pengajar, ajukan permintaan ke Classroom API untuk membuat lampiran pada tugas kita. Simpan detail lampiran dalam database Anda setelah menerima respons dari Classroom API.
Mulailah dengan mendapatkan instance layanan Classroom:
Python
Dalam contoh yang diberikan, file ini ada dalam 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)
Berikan permintaan CREATE
ke endpoint
courses.courseWork.addOnAttachments
. Untuk setiap gambar yang dipilih oleh pengajar, pertama-tama buat
objek AddOnAttachment
:
Python
Dalam contoh yang diberikan, ini adalah kelanjutan dari metode 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}",
}
Setidaknya kolom teacherViewUri
, studentViewUri
, dan title
harus
disediakan untuk setiap lampiran. teacherViewUri
dan studentViewUri
mewakili URL yang dimuat saat lampiran dibuka oleh
jenis pengguna masing-masing.
Kirim objek AddOnAttachment
dalam isi permintaan ke endpoint
addOnAttachments
yang sesuai. Berikan ID courseId
, itemId
, itemType
, dan
addOnToken
dengan setiap permintaan.
Python
Dalam contoh yang diberikan, ini adalah kelanjutan dari metode 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()
Buat entri untuk lampiran ini di database lokal agar Anda dapat
memuat konten yang benar pada lain waktu. Classroom menampilkan nilai id
unik
sebagai respons terhadap permintaan pembuatan, jadi gunakan nilai ini sebagai kunci utama dalam
database kita. Perlu diketahui juga bahwa Classroom meneruskan parameter kueri attachmentId
saat membuka Tampilan Pengajar dan Siswa:
Python
Dalam contoh yang diberikan, ini adalah kelanjutan dari metode 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()
Pertimbangkan untuk mengarahkan pengguna ke halaman konfirmasi pada tahap ini, dengan memberikan konfirmasi bahwa mereka telah berhasil membuat lampiran.
Mengizinkan lampiran dari add-on Anda
Sekarang adalah saat yang tepat untuk menambahkan alamat yang sesuai ke kolom Awalan URI Lampiran yang Diizinkan di halaman Konfigurasi Aplikasi GWM SDK. Add-on Anda hanya dapat membuat lampiran dari salah satu awalan URI yang tercantum di halaman ini. Langkah ini adalah langkah keamanan untuk membantu mengurangi kemungkinan serangan {i>man-in-the-middle<i}.
Pendekatan yang paling sederhana adalah dengan memberikan domain level teratas di kolom ini, misalnya https://example.com
. https://localhost:<your port number>/
akan berfungsi jika Anda menggunakan komputer lokal sebagai server web.
Menambahkan rute untuk Tampilan Pengajar dan Siswa
Ada empat iframe tempat add-on Google Classroom mungkin dimuat. Anda hanya membuat rute yang menayangkan iframe Lampiran Discovery View sejauh ini. Berikutnya, tambahkan juga rute untuk menayangkan iframe Tampilan Pengajar dan Siswa.
Iframe Tampilan Pengajar diperlukan untuk menampilkan pratinjau pengalaman siswa, tetapi dapat secara opsional menyertakan informasi atau fitur pengeditan tambahan.
Tampilan Siswa adalah halaman yang ditampilkan kepada setiap siswa saat mereka membuka lampiran add-on.
Untuk tujuan latihan ini, buat satu rute /load-content-attachment
yang menayangkan Tampilan Pengajar dan Siswa. Gunakan metode Classroom API
untuk menentukan apakah pengguna adalah pengajar atau siswa saat halaman
dimuat.
Python
Dalam contoh yang diberikan, file ini ada dalam 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")
Perlu diingat bahwa Anda juga harus mengautentikasi pengguna pada tahap ini. Anda
juga harus menangani parameter kueri login_hint
dan hd
di sini, dan mengarahkan
pengguna ke alur otorisasi Anda jika perlu. Lihat detail panduan
login yang dibahas dalam panduan sebelumnya untuk mengetahui informasi
selengkapnya tentang alur ini.
Kemudian, kirim permintaan ke endpoint getAddOnContext
yang cocok dengan jenis
item.
Python
Dalam contoh yang diberikan, ini adalah kelanjutan dari metode 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()
Metode ini menampilkan informasi tentang peran pengguna saat ini di class.
Mengubah tampilan yang ditampilkan kepada pengguna, bergantung pada peran mereka. Tepat salah satu kolom
studentContext
atau teacherContext
diisi di objek
respons. Periksa ini untuk menentukan bagaimana menangani pengguna.
Dalam kasus apa pun, gunakan parameter value kueri attachmentId
untuk mengetahui lampiran mana yang akan diambil dari database kami. Parameter kueri ini disediakan saat
membuka URI Tampilan Pengajar atau Siswa.
Python
Dalam contoh yang diberikan, ini adalah kelanjutan dari metode 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)
Menguji add-on
Selesaikan langkah-langkah berikut untuk menguji pembuatan lampiran:
- Login ke [Google Classroom] sebagai salah satu pengguna pengujian Pengajar Anda.
- Buka tab Tugas Kelas dan buat Tugas baru.
- Klik tombol Add-on di bawah area teks, lalu pilih add-on Anda. iframe akan terbuka dan add-on akan memuat URI Penyiapan Lampiran yang Anda tentukan di halaman Konfigurasi Aplikasi GWM SDK.
- Pilih konten untuk dilampirkan ke tugas.
- Tutup iframe setelah alur pembuatan lampiran selesai.
Anda akan melihat kartu lampiran muncul di UI pembuatan tugas di Google Google Classroom. Klik kartu untuk membuka iframe Tampilan Pengajar dan mengonfirmasi bahwa lampiran yang benar muncul. Klik tombol Tetapkan.
Selesaikan langkah-langkah berikut untuk menguji pengalaman siswa:
- Kemudian, login ke Classroom sebagai pengguna uji coba siswa di kelas yang sama dengan pengguna uji coba pengajar.
- Cari tugas ujian di tab Tugas Kelas.
- Luaskan tugas dan klik kartu lampiran untuk membuka iframe Tampilan Siswa.
Pastikan bahwa lampiran yang benar muncul untuk siswa.
Selamat! Anda siap untuk melanjutkan ke langkah berikutnya: membuat lampiran jenis aktivitas.