Tworzenie dodatku do Classroom

To pierwszy przewodnik z serii dodatków do Classroom.

Ten przewodnik pomoże Ci utworzyć aplikację internetową i opublikować ją jako dodatek do Classroom. Kolejne kroki przewodnika poszerzą zakres tej aplikacji.

W ramach tego przewodnika wykonasz następujące czynności:

  • Utwórz nowy projekt Google Cloud dla swojej aplikacji internetowej.
  • utworzyć szkieletową aplikację internetową z zastępczymi przyciskami logowania,
  • Opublikuj w Google Workspace Marketplace (GWM) prywatną stronę aplikacji internetowej.

Po zakończeniu możesz zainstalować dodatek i wczytać go w elemencie iframe dodatków do Classroom.

Wymagania wstępne

Wybierz język poniżej, aby zobaczyć odpowiednie wymagania wstępne:

Python

W naszym przykładzie w języku Python korzystamy z platformy Flask. Pełny kod źródłowy wszystkich przewodników możesz pobrać ze strony Przegląd. Kod tego przewodnika znajduje się w katalogu /flask/01-basic-app/.

W razie potrzeby zainstaluj Python 3.7 lub nowszy i sprawdź, czy dostępny jest język pip.

python -m ensurepip --upgrade

Zalecamy też skonfigurowanie i aktywowanie nowego wirtualnego środowiska Pythona.

python3 -m venv .classroom-addon-env
source .classroom-addon-env/bin/activate

Każdy podkatalog przewodników w pobranych przykładach zawiera requirements.txt. Wymagane biblioteki możesz szybko zainstalować za pomocą pip. Użyj tych instrukcji, aby zainstalować biblioteki wymagane do tego przewodnika.

cd flask/01-basic-app
pip install -r requirements.txt

Node.js

W naszym przykładzie w Node.js użyto platformy Express. Pełny kod źródłowy wszystkich instrukcji możesz pobrać ze strony Przegląd.

W razie potrzeby zainstaluj NodeJS w wersji 16.13 lub nowszej.

Zainstaluj wymagane moduły węzłów za pomocą: npm.

npm install

Java

Nasz przykład w Javie korzysta z platformy Spring Boot. Pełny kod źródłowy wszystkich przewodników możesz pobrać ze strony Przegląd.

Zainstaluj Java 11+, jeśli jeszcze nie masz tej wersji na komputerze.

Aplikacje Spring Boot mogą używać Gradle lub Maven do obsługi kompilacji i zarządzania zależnościami. Ten przykład zawiera kod Maven, który zapewnia udaną kompilację bez konieczności instalowania samej aplikacji Maven.

Aby uruchomić podany przykład, uruchom poniższe polecenia w katalogu, w którym został pobrany projekt. W ten sposób upewnisz się, że spełniasz wymagania wstępne do uruchomienia projektu.

java --version
./mvnw --version

Lub w systemie Windows:

java -version
mvnw.cmd --version

Skonfiguruj projekt Google Cloud

Dostęp do interfejsu Classroom API i wymagane metody uwierzytelniania są kontrolowane przez projekty Google Cloud. Poniższe instrukcje przeprowadzą Cię przez minimalne kroki konieczne do utworzenia i skonfigurowania nowego projektu do użycia z dodatkiem.

Tworzenie projektu

Aby utworzyć nowy projekt Google Cloud, wejdź na stronę tworzenia projektu. Możesz podać dowolną nazwę nowego projektu. Kliknij Utwórz.

Utworzenie nowego projektu może chwilę potrwać. Gdy skończysz, wybierz projekt w menu selektora projektów u góry ekranu lub kliknij WYBIERZ PROJEKT w menu powiadomień w prawym górnym rogu.

Wybrać projekt w konsoli Google Cloud

Dołącz pakiet GWM SDK do projektu Google Cloud

Otwórz przeglądarkę biblioteki interfejsów API. Wyszukaj Google Workspace Marketplace SDK. Pakiet SDK powinien być widoczny na liście wyników.

Karta pakietu SDK Google Workspace Marketplace

Wybierz kartę pakietu SDK Google Workspace Marketplace i kliknij Włącz.

Konfigurowanie pakietu GWM SDK

GWM udostępnia stronę, za pomocą której użytkownicy i administratorzy instalują Twój dodatek. Aby kontynuować, skonfiguruj ekran zgody OAuth oraz Konfiguracja aplikacji i Informacje o aplikacji z pakietu GWM SDK.

Ekran zgody OAuth pojawia się, gdy użytkownicy po raz pierwszy autoryzują Twoją aplikację. Wyświetla prośbę o przyznanie aplikacji dostępu do danych osobowych i informacji o koncie zgodnie z włączonymi zakresami.

Otwórz stronę tworzenia ekranu zgody OAuth. Podaj następujące informacje:

  • Ustaw Typ użytkownika na Zewnętrzny. Kliknij Utwórz.
  • Na następnej stronie podaj wymagane szczegóły aplikacji i informacje kontaktowe. Podaj wszystkie domeny, które hostują Twoją aplikację, w sekcji Autoryzowane domeny. Kliknij ZAPISZ I KONTYNUUJ.
  • Dodaj wszystkie zakresy OAuth wymagane przez Twoją aplikację internetową. Dokładne omówienie zakresów i ich przeznaczenia znajdziesz w przewodniku po konfiguracji protokołu OAuth.

    Aby umożliwić Google wysłanie parametru zapytania login_hint, musisz zażądać co najmniej jednego z poniższych zakresów. Bardziej szczegółowe omówienie tego zachowania znajdziesz w przewodniku po konfiguracji protokołu OAuth:

    • https://www.googleapis.com/auth/userinfo.email (już w pakiecie)
    • https://www.googleapis.com/auth/userinfo.profile (już w pakiecie)

    Te zakresy są specyficzne dla dodatków do Classroom:

    • https://www.googleapis.com/auth/classroom.addons.teacher
    • https://www.googleapis.com/auth/classroom.addons.student

    Podaj też wszelkie inne zakresy interfejsów API Google, których Twoja aplikacja wymaga od użytkowników.

    Kliknij ZAPISZ I KONTYNUUJ.

  • Podaj adresy e-mail wszystkich kont testowych na stronie Użytkownicy testowi. Kliknij ZAPISZ I KONTYNUUJ.

Sprawdź, czy ustawienia są poprawne, a następnie wróć do panelu.

Konfiguracja aplikacji

Otwórz stronę Konfiguracja aplikacji pakietu GWM SDK. Podaj następujące informacje:

  • Ustaw Widoczność aplikacji na Private. To ustawienie jest odpowiednie do testowania i programowania oraz jest odpowiednim wyborem w przypadku tych instrukcji. Wybierz Public tylko wtedy, gdy Twój dodatek jest gotowy do powszechnego użytku.

  • Ustaw Ustawienia instalacji na Admin Only install, aby zezwolić na instalację tylko administratorom domeny.

  • W sekcji Integracja aplikacji wybierz Dodatek do Classroom. Pojawi się prośba o podanie bezpiecznego identyfikatora URI konfiguracji załączników. Jest to adres URL, który ma zostać załadowany, gdy użytkownik otworzy Twój dodatek. Na potrzeby tego przewodnika powinna to być wartość https://<your domain>/addon-discovery.

  • Dozwolone prefiksy identyfikatorów URI załączników służą do weryfikowania identyfikatorów URI ustawionych w AddOnAttachment za pomocą metod courses.*.addOnAttachments.create i courses.*.addOnAttachments.patch. Weryfikacja polega na dopasowaniu prefiksu ciągu znaków dosłownego i obecnie nie można używać symboli wieloznacznych. Na razie możesz pozostawić te pola puste.

  • Dodaj te same zakresy OAuth co na ekranie akceptacji OAuth w poprzednim kroku.

  • Wypełnij pola w sekcji Linki dla deweloperów według potrzeb Twojej organizacji.

Informacje o aplikacji

Otwórz stronę Informacje o aplikacji pakietu GWM SDK. Podaj następujące informacje:

  • W sekcji Szczegóły aplikacji dodaj język lub rozwiń menu obok języka, który jest już na liście. Wpisz nazwę i opisy aplikacji. Pojawią się one na stronie z informacjami o aplikacji w GWM. Aby zapisać zmiany, kliknij Gotowe.
  • Wybierz kategorię dodatku.
  • W sekcji Zasoby graficzne prześlij obrazy do wymaganych pól. Możesz je później zmienić lub zastąpić nimi obiekty zastępcze, jeśli w poprzednim kroku ustawisz widoczność aplikacji na Prywatny.
  • W sekcji Linki do stron pomocy podaj żądane adresy URL. Mogą to być symbole zastępcze, jeśli w poprzednim kroku ustawisz widoczność aplikacji na Prywatna.

Aby zapisać ustawienia, kliknij OPUBLIKUJ. Jeśli w poprzednim kroku ustawisz widoczność aplikacji na Prywatna, aplikacja będzie od razu dostępna do zainstalowania. Jeśli widoczność aplikacji jest ustawiona na Publiczna, przed udostępnieniem do instalacji zostanie ona przesłana do sprawdzenia przez zespół GWM.

Instalowanie dodatku

Teraz możesz zainstalować dodatek, korzystając z linku u góry strony Informacje o aplikacji pakietu GWM SDK. Aby wyświetlić stronę aplikacji, kliknij URL aplikacji u góry strony, a potem kliknij Zainstaluj.

Tworzenie podstawowej aplikacji internetowej

skonfigurować szkieletową aplikację internetową z 2 trasami, Kolejne kroki przewodnika poszerzą zakres aplikacji. Na razie utwórz stronę docelową dodatku /addon-discovery i przykładową stronę indeksu / dla naszej „witryny firmowej”.

Przykładowa aplikacja internetowa w elemencie iframe

Zaimplementuj te 2 punkty końcowe:

  • /: wyświetla wiadomość powitalną i przycisk zamykający zarówno bieżącą kartę, jak i element iframe dodatku.
  • /addon-discovery: wyświetla wiadomość powitalną i 2 przyciski: jeden do zamykania elementu iframe dodatku i drugi do otwierania witryny w nowej karcie.

Pamiętaj, że dodajemy przyciski służące do tworzenia i zamykania okien oraz elementów iframe. W następnym przewodniku pokazujemy metodę bezpiecznego umieszczania użytkownika w nowej karcie w celu autoryzacji.

Utwórz skrypt narzędziowy

Utwórz katalog static/scripts. Utwórz nowy plik addon-utils.js. Dodaj 2 następujące funkcje.

/**
 *   Opens a given destination route in a new window. This function uses
 *   window.open() so as to force window.opener to retain a reference to the
 *   iframe from which it was called.
 *   @param {string} destinationURL The endpoint to open, or "/" if none is
 *   provided.
 */
function openWebsiteInNewTab(destinationURL = '/') {
  window.open(destinationURL, '_blank');
}

/**
 *   Close the iframe by calling postMessage() in the host Classroom page. This
 *   function can be called directly when in a Classroom add-on iframe.
 *
 *   Alternatively, it can be used to close an add-on iframe in another window.
 *   For example, if an add-on iframe in Window 1 opens a link in a new Window 2
 *   using the openWebsiteInNewTab function above, you can call
 *   window.opener.closeAddonIframe() from Window 2 to close the iframe in Window
 *   1.
 */
function closeAddonIframe() {
  window.parent.postMessage({
    type: 'Classroom',
    action: 'closeIframe',
  }, '*');
};

Tworzenie tras

Zaimplementuj punkty końcowe /addon-discovery i /.

Python

Konfigurowanie katalogu aplikacji

Na potrzeby tego przykładu uporządkuj logikę aplikacji tak, aby odpowiadała modułowi Pythona. Jest to katalog webapp w podanym przykładzie.

Utwórz katalog dla modułu serwera, np. webapp. Przenieś katalog static do katalogu modułu. Utwórz katalog template także w katalogu modułu, a Twoje pliki HTML znajdą się tutaj.

Utwórz moduł serwera*

Utwórz plik __init__.py w katalogu modułu i dodaj poniższe importy i deklaracje.

from flask import Flask
import config

app = Flask(__name__)
app.config.from_object(config.Config)

# Load other module script files. This import statement refers to the
# 'routes.py' file described below.
from webapp import routes

Następnie utwórz plik do obsługi tras aplikacji internetowej. W podanym przykładzie jest to wartość webapp/routes.py. Wdróż dwie trasy w tym pliku.

from webapp import app
import flask

@app.route("/")
def index():
    return flask.render_template("index.html",
                                message="You've reached the index page.")

@app.route("/classroom-addon")
def classroom_addon():
    return flask.render_template(
        "addon-discovery.html",
        message="You've reached the addon discovery page.")

Pamiętaj, że nasze trasy przekazują zmienną message do odpowiednich szablonów Jina. Pozwala to określić, do której strony dotarł użytkownik.

Tworzenie plików konfiguracji i uruchamianie plików

W katalogu głównym aplikacji utwórz pliki main.py i config.py. Skonfiguruj tajny klucz w config.py.

import os

class Config(object):
    # Note: A secret key is included in the sample so that it works.
    # If you use this code in your application, replace this with a truly secret
    # key. See https://flask.palletsprojects.com/quickstart/#sessions.
    SECRET_KEY = os.environ.get(
        'SECRET_KEY') or "REPLACE ME - this value is here as a placeholder."

Zaimportuj moduł do pliku main.py i uruchom serwer Flask.

from webapp import app

if __name__ == "__main__":
    # Run the application over HTTPs with a locally stored certificate and key.
    # Defaults to https://localhost:5000.
    app.run(
        host="localhost",
        ssl_context=("localhost.pem", "localhost-key.pem"),
        debug=True)

Node.js

Trasy są rejestrowane w pliku app.js w następujących wierszach.

const websiteRouter = require('./routes/index');
const addonRouter = require('./routes/classroom-addon');

app.use('/', websiteRouter);
app.use('/classroom-addon', addonRouter);

Otwórz /01-basic-app/routes/index.js i sprawdź kod. Ta trasa jest osiągana, gdy użytkownik odwiedza witrynę firmy. Trasa renderuje odpowiedź za pomocą szablonu kierownicy index i przekazuje szablon do obiektu danych zawierającego zmienne title i message.

router.get('/', function (req, res, next) {
  res.render('index', {
    title: 'Education Technology',
    message: 'Welcome to our website!'
  });
});

Otwórz drugą trasę /01-basic-app/routes/classroom-addon.js i sprawdź kod. Ta trasa jest osiągana, gdy użytkownik korzysta z dodatku. Zwróć uwagę, że ta trasa korzysta z szablonu kierownicy discovery oraz układu addon.hbs, aby renderować stronę inaczej niż witryna firmy.

router.get('/', function (req, res, next) {
  res.render('discovery', {
    layout: 'addon.hbs',
    title: 'Education Technology Classroom add-on',
    message: `Welcome.`
});
});

Java

W przykładowym kodzie w Javie są używane moduły do spakowania kolejnych kroków przewodnika. Ponieważ jest to pierwszy przewodnik, kod znajduje się w module step_01_basic_app. Nie zalecamy wdrażania projektu przy użyciu modułów. Sugerujemy raczej, aby podczas wykonywania kolejnych kroków instrukcji korzystać z jednego projektu.

Aby zdefiniować punkty końcowe, utwórz w tym przykładowym projekcie klasę kontrolera Controller.java. W tym pliku zaimportuj adnotację @GetMapping z zależności spring-boot-starter-web.

import org.springframework.web.bind.annotation.GetMapping;

Dodaj adnotację kontrolera platformy Spring nad definicją klasy, aby wskazać przeznaczenie klasy.

@org.springframework.stereotype.Controller
public class Controller {

Następnie zaimplementuj 2 trasy i dodatkową trasę do obsługi błędów.

/** Returns the index page that will be displayed when the add-on opens in a
*   new tab.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the index page template if successful, or the onError method to
*   handle and display the error message.
*/
@GetMapping(value = {"/"})
public String index(Model model) {
  try {
    return "index";
  } catch (Exception e) {
    return onError(e.getMessage(), model);
  }
}

/** Returns the add-on discovery page that will be displayed when the iframe
*   is first opened in Classroom.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the addon-discovery page.
*/
@GetMapping(value = {"/addon-discovery"})
public String addon_discovery(Model model) {
  try {
    return "addon-discovery";
  } catch (Exception e) {
    return onError(e.getMessage(), model);
  }
}

/** Handles application errors.
*   @param errorMessage message to be displayed on the error page.
*   @param model the Model interface to pass error information to display on
*   the error page.
*   @return the error page.
*/
@GetMapping(value = {"/error"})
public String onError(String errorMessage, Model model) {
  model.addAttribute("error", errorMessage);
  return "error";
}

Testowanie dodatku

Uruchom serwer. Następnie zaloguj się w Google Classroom jako jeden z użytkowników testowych Nauczyciela. Otwórz kartę Zadania i utwórz nowy projekt. Kliknij przycisk Dodatki pod obszarem tekstowym, a następnie wybierz dodatek. Element iframe otworzy się, a dodatek wczyta identyfikator URI konfiguracji załączników podany na stronie Konfiguracja aplikacji pakietu GWM SDK.

Gratulacje! Możesz przejść do następnego kroku: logowania użytkowników przy użyciu logowania jednokrotnego Google.