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

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

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

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

  • Создайте новый проект 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.

Прикрепите SDK Google Workspace Marketplace к проекту Google Cloud.

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

Карта SDK Google Workspace Marketplace

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

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

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 (уже включено)

    Следующие области действия характерны для дополнений Класса:

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

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

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

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

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

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

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

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

Настройте скелет веб-приложения с двумя маршрутами. Дальнейшие шаги расширяют это приложение, поэтому сейчас просто создайте целевую страницу для надстройки /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 и / конечные точки.

Питон

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

Для целей этого примера структурируйте логику приложения как модуль 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 и просмотрите код. Этот маршрут достигается, когда конечный пользователь посещает веб-сайт компании. Маршрут отображает ответ с использованием шаблона index Handlebars и передает шаблону объект данных, содержащий переменные 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 как один из тестовых пользователей вашего учителя . Перейдите на вкладку «Задания» и создайте новое задание . Выберите дополнение в списке дополнений . Откроется iframe, и надстройка загрузит URI настройки вложения , который вы указали на странице конфигурации приложения Marketplace SDK.

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