Это первое пошаговое руководство из серии руководств по использованию дополнений для Classroom.
В этом пошаговом руководстве вы заложите основу для разработки веб-приложения и его публикации в качестве дополнения для Classroom. Дальнейшие шаги руководства позволят расширить функциональность этого приложения.
В ходе этого пошагового руководства вы выполните следующие действия:
- Создайте новый проект Google Cloud для своего дополнения.
- Создайте базовый шаблон веб-приложения с кнопками входа в систему в качестве заглушек.
- Опубликуйте своё дополнение в магазине Google Workspace Marketplace.
После завершения вы можете установить дополнение и загрузить его во вкладку iframe с дополнениями для Classroom.
Предварительные требования
Выберите язык, чтобы увидеть необходимые предварительные условия:
Python
В нашем примере на Python используется фреймворк Flask . Полный исходный код всех пошаговых инструкций можно скачать на странице «Обзор». Код для этой конкретной пошаговой инструкции находится в каталоге /flask/01-basic-app/ .
При необходимости установите Python 3.7+ и убедитесь, что pip доступен.
python -m ensurepip --upgradeМы также рекомендуем вам настроить и активировать новую виртуальную среду Python.
python3 -m venv .classroom-addon-envsource .classroom-addon-env/bin/activate
В каждой подпапке с примерами, представленными в загруженных руководствах, находится файл requirements.txt . Вы можете быстро установить необходимые библиотеки с помощью pip . Используйте следующую команду для установки необходимых библиотек для этого руководства.
cd flask/01-basic-apppip install -r requirements.txt
Node.js
В нашем примере на Node.js используется фреймворк Express . Полный исходный код всех пошаговых инструкций можно скачать на странице «Обзор».
При необходимости установите NodeJS версии 16.13+ .
Установите необходимые модули Node.js с помощью npm .
npm installJava
В нашем примере на Java используется фреймворк Spring Boot . Полный исходный код всех пошаговых инструкций можно скачать на странице «Обзор».
Установите Java 11 или более позднюю версию , если она еще не установлена на вашем компьютере.
Приложения Spring Boot могут использовать Gradle или Maven для сборки и управления зависимостями. В этом примере используется обертка Maven, которая обеспечивает успешную сборку без необходимости установки самого Maven.
Чтобы запустить предоставленный нами пример, выполните следующие команды в каталоге, куда вы загрузили проект, чтобы убедиться, что у вас есть все необходимые компоненты для его запуска.
java --version./mvnw --version
Или в Windows:
java -versionmvnw.cmd --version
Создайте проект в Google Cloud.
Доступ к API Classroom и необходимые методы аутентификации контролируются проектами Google Cloud. Следующие инструкции помогут вам выполнить минимальный набор шагов для создания и настройки нового проекта для использования с вашим дополнением.
Создайте проект
Создайте новый проект Google Cloud, перейдя на страницу создания проекта . Вы можете присвоить новому проекту любое имя. Нажмите «Создать» .
Для полного создания нового проекта потребуется несколько минут. После завершения обязательно выберите проект ; вы можете выбрать его в выпадающем меню выбора проектов в верхней части экрана или нажать кнопку «ВЫБРАТЬ ПРОЕКТ» в меню уведомлений в правом верхнем углу.

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

Выберите карточку Google Workspace Marketplace SDK, затем нажмите «Включить» .
Настройте SDK Google Workspace Marketplace.
Google Workspace Marketplace предоставляет список, через который пользователи и администраторы устанавливают ваше дополнение. Для продолжения настройте конфигурацию приложения , список в магазине и экран согласия OAuth в Marketplace SDK.
Конфигурация приложения
Перейдите на страницу конфигурации приложения в Marketplace SDK. Укажите следующую информацию:
Установите для приложения режим видимости :
PublicилиPrivate.- Режим «Публичный» предназначен для приложений, которые в конечном итоге будут выпущены для конечных пользователей. Публичное приложение должно пройти процесс утверждения, прежде чем оно будет опубликовано для конечных пользователей, но вы можете указать пользователей, которые могут установить и протестировать его, в режиме «Черновик» . Это состояние перед публикацией, которое позволит вам протестировать и доработать ваше дополнение, прежде чем отправлять его на утверждение.
- Режим «частный» подходит для внутреннего тестирования и разработки. Частное приложение могут установить только пользователи из того же домена, где был создан проект. Поэтому устанавливать видимость «частный» следует только в том случае, если проект был создан в домене с подпиской Google Workspace for Education , иначе ваши тестовые пользователи не смогут запускать дополнения Classroom.
Установите параметр «Установка
Admin Only installесли хотите ограничить установку только администраторами домена.В разделе «Интеграция с приложениями» выберите надстройку Classroom . Вам будет предложено ввести защищенный 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 . Подробное описание областей действия и их назначения см. в руководстве по настройке OAuth .
Для отправки параметра запроса
login_hintнеобходимо запросить как минимум одну из следующих областей действия (scopes). Более подробное объяснение этого поведения доступно в нашем руководстве по настройке 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 дополнения. -
/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
Настройте каталог приложения.
В рамках этого примера структурируем логику приложения в виде модуля 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 и просмотрите код. Этот маршрут используется, когда конечный пользователь заходит на страницу дополнения. Обратите внимание, что этот маршрут использует шаблон discovery для отображения страницы, а также макет addon.hbs , что отличает его от веб-сайта компании.
router.get('/', function (req, res, next) {
res.render('discovery', {
layout: 'addon.hbs',
title: 'Education Technology Classroom add-on',
message: `Welcome.`
});
});
Java
В приведенном примере кода на 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 настройки вложений, указанный вами на странице конфигурации приложения в SDK Marketplace.
Поздравляем! Вы готовы перейти к следующему шагу: авторизации пользователей с помощью Google SSO .