İçerik türü ekler

Bu, Classroom eklentileri serisinin dördüncü adım adım açıklamalı kılavuzudur.

Bu adım adım açıklamalı kılavuzda, ek oluşturmak için Google Classroom API ile etkileşimde bulunacaksınız. Kullanıcıların ek içeriğini görüntülemeleri için rota sağlarsınız. Görünüm sayısı, kullanıcının sınıftaki rolüne göre farklılık gösterir. Bu adım adım açıklamalı kılavuz, öğrenci gönderimi gerektirmeyen content-type eklerini kapsar.

Bu adım adım açıklamalı kılavuzda aşağıdakileri tamamlarsınız:

  • Aşağıdaki eklenti sorgu parametrelerini alın ve kullanın:
    • addOnToken: Ek Bulma Görünümü'ne iletilen bir yetkilendirme jetonu.
    • itemId: Eklenti ekini alan CourseWork, CourseWorkMaterial veya Duyuru için benzersiz tanımlayıcı.
    • itemType: "courseWork", "courseWorkMaterials" veya "duyuru".
    • courseId: Ödevin oluşturulduğu Google Classroom dersinin benzersiz tanımlayıcısı.
    • attachmentId: Oluşturulduktan sonra eklenti ekine Google Classroom tarafından atanan benzersiz tanımlayıcı.
  • İçerik türündeki ekler için kalıcı depolamayı uygulayın.
  • Ek oluşturmak ve Öğretmen Görünümü ve Öğrenci Görünümü iframe'lerini sunmak için rotalar sağlayın.
  • Google Classroom eklentileri API'sine aşağıdaki istekleri gönderin:
    • Yeni bir ek oluşturun.
    • Giriş yapan kullanıcının öğrenci mi yoksa öğretmen mi olduğunu tanımlayan eklenti bağlamını alın.

İşiniz bittiğinde, öğretmen olarak giriş yaptığınızda Google Classroom kullanıcı arayüzü üzerinden ödevlerde içerik türü ekleri oluşturabilirsiniz. Öğretmenler ve öğrenciler de içeriği görüntüleyebilir.

Classroom API'yi etkinleştirme

Bu adımdan başlayarak Classroom API'ye çağrı yapın. Google Cloud projenizde çağrı yapabilmeniz için API'nin etkinleştirilmiş olması gerekir. Google Classroom API kitaplık girişi'ne gidin ve Etkinleştir'i seçin.

Ek Keşfi Görünümü sorgu parametrelerini işleme

Daha önce belirtildiği gibi, Google Classroom iframe'de Ek Bulma Görünümü'nü yüklerken sorgu parametrelerini iletir:

  • courseId: Mevcut Classroom dersinin kimliği.
  • itemId: Eklenti ekini alan CourseWork, CourseWorkMaterial veya Duyuru için benzersiz tanımlayıcı.
  • itemType: "courseWork", "courseWorkMaterials" veya "duyuru".
  • addOnToken: Belirli Classroom eklentisi işlemlerini yetkilendirmek için kullanılan bir jeton.
  • login_hint: Geçerli kullanıcının Google Kimliği.
  • hd: Geçerli kullanıcının ana makine alan adı (ör. example.com).

Bu adım adım açıklamalı kılavuzda courseId, itemId, itemType ve addOnToken ele alınmaktadır. Bunları, Classroom API'ye çağrı gönderirken saklayın ve iletin.

Önceki adım adım açıklamalı kılavuzda olduğu gibi, iletilen sorgu parametresi değerlerini oturumumuzda depolayın. Classroom'un söz konusu sorgu parametrelerini iletmesi için tek fırsat bu olduğundan, bunu Ek Bulma Görünümü ilk kez açıldığında yapmamız önemlidir.

Python

Ek Keşif Görünümü için rotalar sağlayan Flask sunucu dosyanıza gidin (sağladığımız örneği takip ediyorsanız attachment-discovery-routes.py). Eklenti açılış rotanızın en üstünde (sağladığımız örnekte /classroom-addon) courseId, itemId, itemType ve addOnToken sorgu parametrelerini alın ve depolayın.

# 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")

Bu değerleri yalnızca varsa oturuma yazın; kullanıcı daha sonra iframe'i kapatmadan Ek Keşfi Görünümü'ne geri dönerse bu değerler tekrar geçirilmez.

İçerik türü ekler için kalıcı depolama alanı ekleme

Oluşturulan eklerin yerel bir kaydına ihtiyacınız vardır. Bu sayede, Classroom tarafından sağlanan tanımlayıcıları kullanarak öğretmenin seçtiği içeriği bulabilirsiniz.

Attachment için veritabanı şeması oluşturun. Verdiğimiz örnekte, bir resim ve başlık gören ekler gösterilmektedir. Attachment aşağıdaki özellikleri içerir:

  • attachment_id: Bir ekin benzersiz tanımlayıcısıdır. Classroom tarafından atanır ve ek oluşturulurken verilen yanıtta döndürülür.
  • image_filename: Gösterilecek resmin yerel dosya adı.
  • image_caption: Resimle birlikte gösterilecek başlık.

Python

Önceki adımlarda açıklanan SQLite ve flask_sqlalchemy uygulamasını genişletin.

Kullanıcı tablonuzu tanımladığınız dosyaya gidin (models.py sağladığımız örneği uyguluyorsanız). Aşağıdaki kodu dosyanın en altına User sınıfının altına ekleyin.

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))

Yeni Ek sınıfını, ek işleme rotalarınızla birlikte sunucu dosyasına aktarın.

Yeni rotalar oluşturun

Uygulamamızda yeni sayfalar oluşturarak bu adım adım açıklamalı kılavuza başlayın. Bunlar, kullanıcının eklentimiz üzerinden içerik oluşturmasına ve görüntülemesine olanak tanır.

Ek oluşturma rotaları ekleyin

Öğretmenin içeriği seçebilmesi ve ek oluşturma isteklerinde bulunabilmesi için sayfalara ihtiyacınız vardır. Öğretmenin belirleyeceği içerik seçeneklerini görüntülemek için /attachment-options rotasını uygulayın. İçerik seçimi ve oluşturma onay sayfaları için de şablonlar gerekir. Verilen örneklerde bunlar için şablonlar bulunmaktadır ve Classroom API'den gelen istek ve yanıtlar da gösterilebilir.

Alternatif olarak, yeni /attachment-options sayfasını oluşturmak yerine mevcut Ek Keşfi Görünümü açılış sayfanızı, içerik seçeneklerini gösterecek şekilde değiştirebilirsiniz. İkinci adım adım adımda uygulanan TOA davranışını (ör. uygulama izinlerinin iptali) korumak için bu alıştırmada yeni bir sayfa oluşturmanızı öneririz. Eklentinizi geliştirip test ederken bunların işinize yaraması gerekir.

Öğretmenler, sağladığımız örnekteki küçük bir altyazılı resim grubundan seçim yapabilir. Altyazıları dosya adlarından alınan ünlü önemli noktalara ait dört resim sağladık.

Python

Bu, verdiğimiz örnekte webapp/attachment_routes.py dosyasında yer almaktadır.

@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,
    )

Bu, aşağıdakine benzeyen bir "Ek Oluştur" sayfası oluşturur:

Python örnek içerik seçimi görünümü

Öğretmen birden fazla resim seçebilir. Öğretmenin create_attachments yönteminde seçtiği her resim için bir ek oluşturun.

Ek oluşturma isteklerini sorun

Öğretmenin hangi içerik parçalarını eklemek istediğini artık bildiğinize göre, ödevimizde ek oluşturmak için Classroom API'ya istek gönderebilirsiniz. Classroom API'den yanıt aldıktan sonra ekin ayrıntılarını veritabanınızda depolayın.

İlk olarak Classroom hizmetinin bir örneğini alın:

Python

Bu, verdiğimiz örnekte webapp/attachment_routes.py dosyasında yer almaktadır.

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)

courses.courseWork.addOnAttachments uç noktasına bir CREATE isteği gönderin. Öğretmen tarafından seçilen her resim için öncelikle bir AddOnAttachment nesnesi oluşturun:

Python

Verdiğimiz örnekte bu, create_attachments yönteminin devamıdır.

# 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}",
    }

Her ek için en az teacherViewUri, studentViewUri ve title alanları sağlanmalıdır. teacherViewUri ve studentViewUri, ek ilgili kullanıcı türü tarafından açıldığında yüklenen URL'leri gösterir.

İsteğin gövdesindeki AddOnAttachment nesnesini uygun addOnAttachments uç noktasına gönderin. Her istekle birlikte courseId, itemId, itemType ve addOnToken tanımlayıcılarını sağlayın.

Python

Verdiğimiz örnekte bu, create_attachments yönteminin devamıdır.

# 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()

Daha sonra doğru içeriği yükleyebilmek amacıyla yerel veritabanınızda bu ek için bir giriş oluşturun. Classroom, oluşturma isteğine yanıt olarak benzersiz bir id değeri döndürür. Bu nedenle, bunu veritabanımızda birincil anahtar olarak kullanın. Ayrıca, Classroom'un Öğretmen ve Öğrenci Görünümlerini açarken attachmentId sorgu parametresini ilettiğini de unutmayın:

Python

Verdiğimiz örnekte bu, create_attachments yönteminin devamıdır.

# 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()

Bu noktada, ekleri başarıyla oluşturduklarını onaylamak için kullanıcıyı bir onay sayfasına yönlendirmeyi düşünün.

Eklentinizden gelen eklere izin verme

Şimdi GWM SDK Uygulama Yapılandırması sayfasındaki İzin Verilen Ek URI Önekleri alanına uygun adresleri eklemenin tam zamanıdır. Eklentiniz yalnızca bu sayfada listelenen URI öneklerinin birinden ekler oluşturabilir. Bu, ortadaki adam saldırıları olasılığını azaltmaya yardımcı olan bir güvenlik önlemidir.

En basit yaklaşım, üst düzey alanınızı bu alanda sağlamaktır (örneğin, https://example.com). Web sunucusu olarak yerel makinenizi kullanırsanız https://localhost:<your port number>/ çalışır.

Öğretmen ve Öğrenci Görünümleri için rota ekleme

Bir Google Classroom eklentisinin yüklenebileceği dört iframe vardır. Yalnızca şu ana kadar Ek Keşfi Görünümü iframe'i sunan rotalar oluşturdunuz. Ardından, Öğretmen ve Öğrenci Görünümü iframe'lerini de sunmak için rotalar ekleyin.

Öğretmen Görünümü iframe'i, öğrenci deneyiminin bir önizlemesini göstermek için gereklidir, ancak isteğe bağlı olarak ek bilgiler veya düzenleme özellikleri içerebilir.

Öğrenci Görünümü, eklenti eklerini açan her öğrenciye gösterilen sayfadır.

Bu alıştırmada hem Öğretmen hem de Öğrenci Görünümü'ne hizmet veren tek bir /load-content-attachment rotası oluşturun. Sayfa yüklendiğinde kullanıcının öğretmen mi öğrenci mi olduğunu belirlemek için Classroom API yöntemlerini kullanın.

Python

Bu, verdiğimiz örnekte webapp/attachment_routes.py dosyasında yer almaktadır.

@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")

Bu noktada kullanıcının kimliğini de doğrulamanız gerektiğini unutmayın. Ayrıca, login_hint ve hd sorgu parametrelerini burada ele almalı ve gerekirse kullanıcıyı yetkilendirme akışınıza yönlendirmelisiniz. Bu akış hakkında daha fazla bilgi edinmek için önceki adım adım açıklamalı kılavuzlarda açıklanan giriş kılavuzu ayrıntılarını inceleyin.

Ardından, öğe türüyle eşleşen getAddOnContext uç noktasına bir istek gönderin.

Python

Verilen örnekte, load_content_attachment yönteminin devamıdır.

# 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()

Bu yöntem, geçerli kullanıcının sınıftaki rolüyle ilgili bilgileri döndürür. Kullanıcıya sunulan görünümü, rolüne bağlı olarak değiştirin. Yanıt nesnesinde tam olarak studentContext veya teacherContext alanlarından biri doldurulur. Kullanıcılara nasıl hitap edeceğinizi belirlemek için bunları inceleyin.

Her durumda, veritabanımızdan hangi eki alacağınızı öğrenmek için attachmentId sorgu parametresi değerini kullanın. Bu sorgu parametresi, Öğretmen veya Öğrenci Görünümü URI'ları açılırken sağlanır.

Python

Verilen örnekte, load_content_attachment yönteminin devamıdır.

# 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)

Eklentiyi test etme

Ek oluşturmayı test etmek için aşağıdaki adımları uygulayın:

  • [Google Classroom]'da Öğretmen test kullanıcılarınızdan biri olarak oturum açın.
  • Sınıf Çalışmaları sekmesine gidin ve yeni bir Ödev oluşturun.
  • Metin alanının altındaki Eklentiler düğmesini tıklayın, ardından eklentinizi seçin. iframe açılır ve eklenti, GWM SDK'sının Uygulama Yapılandırması sayfasında belirttiğiniz Ek Kurulum URI'si'ni yükler.
  • Ödeve eklenecek içeriği seçin.
  • Ek oluşturma akışı tamamlandıktan sonra iframe'i kapatın.

Google Classroom'daki ödev oluşturma kullanıcı arayüzünde bir ek kartı görürsünüz. Öğretmen Görünümü iframe'ini açmak için kartı tıklayın ve doğru ekin göründüğünü onaylayın. Ata düğmesini tıklayın.

Öğrenci deneyimini test etmek için aşağıdaki adımları uygulayın:

  • Ardından, Classroom'da, öğretmen test kullanıcısıyla aynı sınıfta öğrenci test kullanıcısı olarak oturum açın.
  • Test ödevini Sınıf Çalışmaları sekmesinde bulun.
  • Ödevi genişletin ve Öğrenci Görünümü iframe'ini açmak için ek kartını tıklayın.

Öğrenci için doğru ekin göründüğünden emin olun.

Tebrikler! Bir sonraki adım olan etkinlik türü ekler oluşturma adımına geçmeye hazırsınız.