Создать дополнение для Класса

Это первое пошаговое руководство из серии пошаговых руководств по дополнениям Classroom.

В этом пошаговом руководстве вы заложите основу для разработки веб-приложения и его публикации в качестве надстройки для Класса. Дальнейшие шаги пошагового руководства расширят возможности этого приложения.

В ходе этого пошагового руководства вы выполните следующее:

  • Создайте новый проект Google Cloud для вашего дополнения.
  • Создайте каркас веб-приложения с кнопками-заглушками для входа.
  • Опубликуйте страницу своего дополнения в магазине Google Workspace Marketplace.

После завершения вы можете установить свое дополнение и загрузить его в iframe дополнений для класса.

Предпосылки

Выберите язык, чтобы увидеть соответствующие предварительные условия:

Питон

В нашем примере на Python используется фреймворк Flask . Вы можете скачать полный исходный код для всех пошаговых инструкций со страницы «Обзор». Код для данного пошагового руководства находится в каталоге /flask/01-basic-app/ .

При необходимости установите Python 3.7+ и убедитесь, что pip доступен.

python -m ensurepip --upgrade

Мы также рекомендуем вам настроить и активировать новую виртуальную среду Python.

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

Каждый подкаталог пошагового руководства в загруженных примерах содержит файл requirements.txt . Вы можете быстро установить необходимые библиотеки с помощью pip . Используйте следующую команду для установки необходимых библиотек для этого пошагового руководства.

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

Node.js

В нашем примере на Node.js используется фреймворк Express . Вы можете скачать полный исходный код для всех пошаговых инструкций со страницы обзора.

При необходимости установите NodeJS v16.13+ .

Установите необходимые модули узла с помощью npm .

npm install

Ява

В нашем примере Java используется фреймворк Spring Boot . Вы можете скачать полный исходный код для всех пошаговых инструкций со страницы обзора.

Установите Java 11+ , если она еще не установлена на вашем компьютере.

Приложения Spring Boot могут использовать Gradle или Maven для сборки и управления зависимостями. Этот пример включает в себя оболочку Maven, которая обеспечивает успешную сборку без необходимости установки самого Maven.

Чтобы запустить предоставленный нами пример, выполните следующие команды в каталоге, куда вы загрузили проект, чтобы убедиться в наличии необходимых условий для запуска проекта.

java --version
./mvnw --version

Или в Windows:

java -version
mvnw.cmd --version

Настройте проект Google Cloud

Доступ к Classroom API и необходимые методы аутентификации контролируются проектами Google Cloud. Следующие инструкции помогут вам выполнить минимально необходимые шаги для создания и настройки нового проекта для использования с вашим дополнением.

Создать проект

Создайте новый проект Google Cloud, посетив страницу создания проекта . Вы можете указать любое имя для нового проекта. Нажмите «Создать» .

Создание нового проекта займёт несколько минут. После этого обязательно выберите проект . Вы можете выбрать его в раскрывающемся меню выбора проектов в верхней части экрана или нажать «ВЫБРАТЬ ПРОЕКТ» в меню уведомлений в правом верхнем углу.

Выберите проект в консоли Google Cloud.

Подключите Google Workspace Marketplace SDK к проекту Google Cloud

Откройте браузер библиотеки API . Найдите Google Workspace Marketplace SDK . SDK должен появиться в списке результатов.

Карточка SDK Google Workspace Marketplace

Выберите карточку Google Workspace Marketplace SDK, затем нажмите Включить .

Настройте Google Workspace Marketplace SDK

Google Workspace Marketplace предоставляет список, через который пользователи и администраторы устанавливают ваше дополнение. Чтобы продолжить, настройте конфигурацию приложения и список магазина Marketplace SDK, а также экран согласия OAuth .

Конфигурация приложения

Перейдите на страницу конфигурации приложения Marketplace SDK. Укажите следующую информацию:

  • Установите Видимость приложения : Public или Private .

    • Публичный режим предназначен для приложений, которые в конечном итоге будут выпущены для конечных пользователей. Публичное приложение должно пройти процедуру утверждения перед публикацией для конечных пользователей, но вы можете указать пользователей, которые смогут установить и протестировать его в качестве черновика . Это состояние до публикации, которое позволит вам протестировать и разработать дополнение перед отправкой его на утверждение.
    • Режим «Частный» подходит для внутреннего тестирования и разработки. Частное приложение могут установить только пользователи в том же домене, где был создан проект. Поэтому следует устанавливать режим «Частный» только в том случае, если проект создан в домене с подпиской на Google Workspace for Education , иначе ваши тестовые пользователи не смогут запускать дополнения для Класса.
  • Если вы хотите разрешить установку Admin Only install домена, задайте для параметров установки значение «Установка только администратором».

  • В разделе «Интеграция приложений» выберите « Надстройка для класса» . Вам будет предложено ввести безопасный URI настройки вложения; это URL-адрес, который должен загружаться при открытии пользователем вашего дополнения. В данном руководстве это должен быть https://<your domain>/addon-discovery .

  • Префиксы разрешенных URI вложений используются для проверки URI, заданных в AddOnAttachment с помощью courses.*.addOnAttachments.create и courses.*.addOnAttachments.patch . Проверка осуществляется путем сопоставления префиксов строк и в настоящее время не допускает использование подстановочных знаков. Добавьте как минимум корневой домен вашего сервера контента, например https://localhost:5000/ или https://cdn.myedtech.com/ .

  • Добавьте те же области OAuth , которые указаны на экране согласия OAuth на предыдущем шаге.

  • Заполните поля в соответствии с особенностями вашей организации в разделе «Ссылки для разработчиков» .

Листинг магазина

Перейдите на страницу описания магазина Marketplace SDK. Укажите следующую информацию:

  • В разделе «Сведения о приложении» добавьте язык или разверните раскрывающийся список рядом с уже указанным языком. Укажите название приложения и его описание; они появятся на странице описания вашего дополнения в Google Workspace Marketplace. Нажмите «Готово» , чтобы сохранить.
  • Выберите категорию для вашего дополнения.
  • В разделе «Графические ресурсы» укажите изображения для обязательных полей. Их можно будет изменить позже, а пока использовать в качестве заполнителей.
  • В разделе «Ссылки поддержки» укажите запрошенные URL-адреса. Они могут быть заглушками, если на предыдущем шаге вы установили параметр «Видимость приложения» на «Частный» .

Если на предыдущем шаге вы установили параметр «Видимость приложения» на «Частный» , нажмите кнопку «Опубликовать» ; ваше приложение сразу же станет доступно для установки. Если же параметр «Видимость приложения» установлен на «Публичный» , добавьте адреса электронной почты всех тестовых пользователей в разделе «Тестировщики черновика» и нажмите кнопку «Сохранить черновик» .

Экран согласия OAuth появляется при первой авторизации вашего приложения пользователями. Он предлагает им разрешить вашему приложению доступ к их личным данным и учётной записи в соответствии с выбранными вами областями действия.

Перейдите на страницу создания экрана согласия OAuth . Укажите следующую информацию:

  • Установите тип пользователя « Внешний» . Нажмите «Создать» .
  • На следующей странице заполните необходимые сведения о приложении и контактную информацию. Укажите все домены, на которых размещено ваше приложение, в разделе «Авторизованные домены» . Нажмите «СОХРАНИТЬ И ПРОДОЛЖИТЬ» .
  • Добавьте все области действия OAuth , необходимые вашему веб-приложению. Подробное описание областей действия и их назначения см. в руководстве по настройке OAuth.

    Чтобы Google отправил параметр запроса login_hint , необходимо запросить как минимум одну из следующих областей. Более подробное описание этого поведения доступно в нашем руководстве по настройке OAuth :

    • https://www.googleapis.com/auth/userinfo.email (уже включено)
    • https://www.googleapis.com/auth/userinfo.profile (уже включено)

    Следующие области действия относятся только к надстройкам Classroom:

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

    Также включите любые другие области действия API Google , которые ваше приложение требует от конечных пользователей.

    Нажмите СОХРАНИТЬ И ПРОДОЛЖИТЬ .

  • Перечислите адреса электронной почты всех тестовых учётных записей на странице «Тестовые пользователи» . Нажмите «СОХРАНИТЬ И ПРОДОЛЖИТЬ» .

Подтвердите правильность настроек, затем вернитесь на панель управления.

Установить дополнение

Теперь вы можете установить дополнение, перейдя по ссылке в верхней части страницы описания Marketplace SDK. Нажмите «Просмотреть в Marketplace» в верхней части страницы, чтобы увидеть описание, затем выберите «Установить» .

Создайте простое веб-приложение

Создайте каркас веб-приложения с двумя маршрутами. В последующих шагах пошагового руководства мы расширим это приложение, а пока просто создадим целевую страницу для дополнения /addon-discovery и макет индексной страницы / для нашего «сайта компании».

Пример веб-приложения в iframe

Реализуйте эти две конечные точки:

  • / : отображает приветственное сообщение и кнопку для закрытия как текущей вкладки, так и дополнительного iframe.
  • /addon-discovery : отображает приветственное сообщение и две кнопки: одну для закрытия iframe надстройки и одну для открытия веб-сайта в новой вкладке.

Обратите внимание, что мы добавляем кнопки для создания и закрытия окон или iframe. Они демонстрируют метод безопасного открытия новой вкладки для авторизации в следующем пошаговом руководстве.

Создать скрипт утилиты

Создайте каталог static/scripts . Создайте новый файл addon-utils.js . Добавьте в него две следующие функции.

/**
 *   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, 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',
  }, '*');
};

Создавать маршруты

Реализуйте /addon-discovery и / endpoints.

Питон

Настройте каталог приложений

Для этого примера структурируйте логику приложения как модуль Python. В нашем примере это каталог webapp .

Создайте каталог для серверного модуля, например, webapp . Переместите каталог static в каталог модуля. Создайте каталог template в каталоге модуля; ваши HTML-файлы будут находиться здесь.

Сборка серверного модуля *

Создайте файл __init__.py в каталоге вашего модуля и добавьте следующие импорты и объявления.

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

Затем создайте файл для управления маршрутами веб-приложения. В нашем примере это webapp/routes.py . Реализуйте два маршрута в этом файле.

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

Обратите внимание, что оба наших маршрута передают переменную message в соответствующие шаблоны Jinja. Это полезно для определения, какую страницу перешёл пользователь.

Создание файлов конфигурации и запуска

В корневом каталоге приложения создайте файлы main.py и config.py . Настройте секретный ключ в 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."

В файле main.py импортируйте свой модуль и запустите сервер 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

Маршруты регистрируются в файле app.js с помощью следующих строк.

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

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

Откройте /01-basic-app/routes/index.js и изучите код. Этот маршрут используется, когда конечный пользователь посещает веб-сайт компании. Маршрут формирует ответ, используя шаблон Handlebars index , и передаёт ему объект данных, содержащий переменные title и message .

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

Откройте второй маршрут /01-basic-app/routes/classroom-addon.js и проверьте код. Этот маршрут открывается, когда конечный пользователь посещает дополнение. Обратите внимание, что этот маршрут использует шаблон Handlebars discovery и макет addon.hbs для отображения страницы иначе, чем на веб-сайте компании.

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

Ява

В примере кода Java используются модули для упаковки последовательных шагов пошагового руководства. Поскольку это первое пошаговое руководство, код находится в модуле step_01_basic_app . Мы не предполагаем, что вы будете реализовывать свой проект с помощью модулей; вместо этого мы рекомендуем вам разрабатывать проект на основе одного проекта, выполняя каждый шаг пошагового руководства.

Создайте класс контроллера Controller.java в этом примере проекта для определения конечных точек. В этом файле импортируйте аннотацию @GetMapping из зависимости spring-boot-starter-web .

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

Включите аннотацию контроллера фреймворка Spring над определением класса, чтобы указать назначение класса.

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

Затем реализуйте два маршрута и дополнительный маршрут для обработки ошибок.

/** 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";
}

Протестируйте дополнение

Запустите сервер. Затем войдите в Google Classroom как один из ваших тестовых пользователей Teacher . Перейдите на вкладку «Задания» и создайте новое задание . Выберите дополнение в списке дополнений . Откроется iframe, и дополнение загрузит URI настройки вложения , указанный вами на странице конфигурации приложения Marketplace SDK.

Поздравляем! Вы готовы перейти к следующему шагу: входу пользователей с помощью Google SSO .