Este é o primeiro tutorial da série de complementos do Google Sala de Aula.
Neste tutorial, você vai aprender a desenvolver um aplicativo da Web e publicá-lo como um complemento do Google Sala de Aula. As próximas etapas do tutorial expandem esse app.
Durante este tutorial, você vai concluir o seguinte:
- Crie um projeto do Google Cloud para o complemento.
- Crie um app da Web básico com botões de login de marcador de posição.
- Publique uma página de detalhes do Google Workspace Marketplace para o complemento.
Quando terminar, você poderá instalar o complemento e carregá-lo no iFrame de complementos do Google Sala de Aula.
Pré-requisitos
Escolha um idioma para ver os pré-requisitos adequados:
Python
Nosso exemplo em Python usa o framework Flask. É possível fazer o download do
código-fonte completo de todos os tutoriais na página "Visão geral". O código para este
tutorial específico pode ser encontrado no diretório /flask/01-basic-app/
.
Se necessário, instale o Python 3.7 ou mais recente e verifique se o pip
está disponível.
python -m ensurepip --upgrade
Também recomendamos que você configure e ative um novo ambiente virtual do Python.
python3 -m venv .classroom-addon-env
source .classroom-addon-env/bin/activate
Cada subdiretório de tutorial nos exemplos transferidos por download contém um
requirements.txt
. É possível instalar rapidamente as bibliotecas necessárias usando
pip
. Use o seguinte para instalar as bibliotecas necessárias para este
tutorial.
cd flask/01-basic-app
pip install -r requirements.txt
Node.js
Nosso exemplo de Node.js usa o framework Express. É possível fazer o download do código-fonte completo de todos os tutoriais na página "Visão geral".
Se necessário, instale o NodeJS v16.13 ou mais recente.
Instale os módulos de nó necessários usando npm
.
npm install
Java
Nosso exemplo em Java usa o framework do Spring Boot. É possível fazer o download do código-fonte completo de todos os tutoriais na página "Visão geral".
Instale o Java 11 ou mais recente, se ainda não tiver feito isso.
Os aplicativos Spring Boot podem usar o Gradle ou o Maven para processar builds e gerenciar dependências. Este exemplo inclui o wrapper do Maven, que garante um build bem-sucedido sem exigir que você instale o Maven.
Para executar o exemplo fornecido, execute os comandos a seguir no diretório em que você fez o download do projeto para garantir que você tenha os pré-requisitos para executar o projeto.
java --version
./mvnw --version
Ou no Windows:
java -version
mvnw.cmd --version
Configure um projeto do Google Cloud
O acesso à API Classroom e aos métodos de autenticação necessários são controlados por projetos do Google Cloud. As instruções a seguir mostram as etapas mínimas para criar e configurar um novo projeto para uso com o complemento.
Criar o projeto
Crie um projeto do Google Cloud acessando a página de criação de projetos. Você pode fornecer qualquer nome para o novo projeto. Clique em Criar.
A criação do novo projeto leva alguns instantes. Depois, selecione o projeto. Você pode fazer isso no menu suspenso do seletor de projetos na parte de cima da tela ou clicando em SELECIONAR PROJETO no menu de notificações, no canto superior direito.
Anexar o SDK do Google Workspace Marketplace ao projeto do Google Cloud
Acesse o navegador da Biblioteca de APIs. Pesquise
Google Workspace Marketplace SDK
. O SDK vai aparecer na lista de
resultados.
Selecione o card do SDK do Google Workspace Marketplace e clique em Ativar.
Configurar o SDK do Google Workspace Marketplace
O Google Workspace Marketplace fornece a listagem em que os usuários e administradores instalam o complemento. Configure a Configuração do app e a Listagem da loja do SDK do Marketplace e a tela de consentimento do OAuth para continuar.
Configuração do app
Acesse a página Configuração do app do SDK do Marketplace. Forneça as seguintes informações:
Defina a Visibilidade do app como
Public
ouPrivate
.- A configuração pública é destinada a apps que serão lançados para usuários finais. Um app público precisa passar por um processo de aprovação antes de ser publicado para os usuários finais, mas você pode especificar os usuários que podem instalar e testar como um Rascunho. Esse é um estado pré-publicação que permite testar e desenvolver o complemento antes de enviá-lo para aprovação.
- A configuração particular é adequada para testes e desenvolvimento internos. Um app privado só pode ser instalado por usuários no mesmo domínio em que o projeto foi criado. Portanto, defina a visibilidade como privada apenas se o projeto foi criado em um domínio com uma assinatura do Google Workspace for Education. Caso contrário, os usuários de teste não poderão iniciar os complementos do Google Sala de Aula.
Defina Configurações de instalação como
Admin Only install
se quiser restringir a instalação aos administradores do domínio.Em Integração de app, selecione Complemento do Google Sala de Aula. Você será solicitado a fornecer o URI de configuração de anexo seguro, que é o URL que você espera que seja carregado quando um usuário abrir seu complemento. Para os fins deste tutorial, ele precisa ser
https://<your domain>/addon-discovery
.Os prefixos de URI de anexo permitidos são usados para validar os URIs definidos em
AddOnAttachment
usando os métodoscourses.*.addOnAttachments.create
ecourses.*.addOnAttachments.patch
. A validação é uma correspondência literal de prefixo de string e não permite o uso de caracteres curinga no momento. Adicione pelo menos o domínio raiz do servidor de conteúdo, comohttps://localhost:5000/
ouhttps://cdn.myedtech.com/
.Adicione os mesmos escopos do OAuth informados na tela de consentimento do OAuth na etapa anterior.
Preencha os campos conforme apropriado para sua organização em Links para desenvolvedores.
Detalhes do app
Acesse a página Detalhes do app na loja do SDK do Marketplace. Forneça as seguintes informações:
- Em Detalhes do app, adicione um idioma ou abra o menu suspenso ao lado do idioma já listado. Informe um nome e descrições do aplicativo. Eles vão aparecer na página "Detalhes do app" do Google Workspace Marketplace. Clique em Concluído para salvar.
- Escolha uma categoria para o complemento.
- Em Recursos gráficos, forneça imagens para os campos obrigatórios. Eles podem ser alterados mais tarde e podem ser marcadores de posição por enquanto.
- Em Links de suporte, informe os URLs solicitados. Eles podem ser marcadores de posição se você definir a visibilidade do app como Privado na etapa anterior.
Se você definir a visibilidade do app como Privado na etapa anterior, clique em PUBLISH. O app vai ficar imediatamente disponível para instalação. Se você definir a visibilidade do app como Pública, adicione endereços de e-mail na área Testadores de rascunho para todos os usuários de teste e clique em Salvar rascunho.
Tela de permissão OAuth
A tela de consentimento do OAuth aparece quando os usuários autorizam o app pela primeira vez. Ela solicita que eles permitam que o app acesse as informações pessoais e da conta, conforme determinado pelos escopos ativados.
Navegue até a página de criação da tela de consentimento do OAuth. Forneça as seguintes informações:
- Defina Tipo de usuário como Externo. Clique em Criar.
- Na próxima página, preencha os detalhes do app e os dados de contato necessários. Informe os domínios que hospedam seu app em Domínios autorizados. Clique em SALVAR E CONTINUAR.
Adicione os escopos do OAuth necessários para o app da Web. Consulte o guia de configuração do OAuth para uma discussão detalhada sobre os escopos e suas finalidades.
É necessário solicitar pelo menos um dos escopos a seguir para que o Google envie o parâmetro de consulta
login_hint
. Uma explicação mais detalhada desse comportamento está disponível no nosso guia de configuração do OAuth:https://www.googleapis.com/auth/userinfo.email
(já incluído)https://www.googleapis.com/auth/userinfo.profile
(já incluído)
Os escopos a seguir são específicos para os complementos do Google Sala de Aula:
https://www.googleapis.com/auth/classroom.addons.teacher
https://www.googleapis.com/auth/classroom.addons.student
Inclua também todos os outros escopos da API do Google que o app exige dos usuários finais.
Clique em SALVAR E CONTINUAR.
Liste os endereços de e-mail de todas as contas de teste na página Test Users. Clique em SALVAR E CONTINUAR.
Confirme se as configurações estão corretas e volte ao painel.
Instalar o complemento
Agora você pode instalar o complemento usando o link na parte de cima da página Detalhes do app do SDK do Marketplace. Clique no URL do app na parte de cima da página para ver a listagem e escolha Instalar.
Criar um app da Web básico
Configure um aplicativo da Web de esqueleto com duas rotas. As etapas de instrução futuras
expandem esse aplicativo. Por enquanto, crie uma página de destino para o complemento
/addon-discovery
e uma página de índice simulada /
para o "site da empresa".
Implemente estes dois endpoints:
/
: mostra uma mensagem de boas-vindas e um botão para fechar a guia atual e o iframe do complemento./addon-discovery
: mostra uma mensagem de boas-vindas e dois botões: um para fechar o iframe do complemento e outro para abrir um site em uma nova guia.
Estamos adicionando botões para criar e fechar janelas ou o iframe. Elas demonstram um método para abrir com segurança o usuário em uma nova guia para autorização na próxima etapa.
Criar um script de utilitário
Crie um diretório static/scripts
. Crie um novo arquivo addon-utils.js
. Adicione as
duas funções a seguir.
/**
* 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',
}, '*');
};
Criar rotas
Implemente os endpoints /addon-discovery
e /
.
Python
Configurar o diretório do aplicativo
Para fins deste exemplo, estruture a lógica do aplicativo como um
módulo Python. Este é o diretório webapp
no exemplo fornecido.
Crie um diretório para o módulo do servidor, por exemplo, webapp
. Mova o
diretório static
para o diretório do módulo. Crie um diretório template
no diretório do módulo. Seus arquivos HTML vão ficar aqui.
Criar o módulo do servidor*
Crie o arquivo __init__.py
no diretório do módulo e adicione as seguintes
importações e declarações.
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
Em seguida, crie um arquivo para processar as rotas do app da Web. Isso é
webapp/routes.py
no nosso exemplo fornecido. Implemente as duas rotas neste
arquivo.
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.")
Observe que nossas rotas transmitem uma variável message
para os respectivos
modelos Jinja. Isso é útil para identificar qual página o usuário acessou.
Criar arquivos de configuração e inicialização
No diretório raiz do aplicativo, crie os arquivos main.py
e config.py
. Configure a chave secreta em 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."
No arquivo main.py
, importe o módulo e inicie o servidor 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
Os trajetos são registrados no arquivo app.js
com as seguintes linhas.
const websiteRouter = require('./routes/index');
const addonRouter = require('./routes/classroom-addon');
app.use('/', websiteRouter);
app.use('/addon-discovery', addonRouter);
Abra /01-basic-app/routes/index.js
e analise o código. Essa rota é
alcançada quando o usuário final visita o site da empresa. A rota renderiza uma
resposta usando o modelo index
Handlebars e transmite ao modelo um
objeto de dados que contém variáveis title
e message
.
router.get('/', function (req, res, next) {
res.render('index', {
title: 'Education Technology',
message: 'Welcome to our website!'
});
});
Abra a segunda rota /01-basic-app/routes/classroom-addon.js
e analise
o código. Essa rota é alcançada quando o usuário final visita o complemento. Observe
que essa rota usa o modelo de Handlebars discovery
e, além disso,
o layout addon.hbs
para renderizar a página de maneira diferente do site
da empresa.
router.get('/', function (req, res, next) {
res.render('discovery', {
layout: 'addon.hbs',
title: 'Education Technology Classroom add-on',
message: `Welcome.`
});
});
Java
O exemplo de código Java usa módulos para empacotar as etapas sequenciais
da apresentação. Como esta é a primeira demonstração, o código está no
módulo step_01_basic_app
. Não é esperado que você implemente seu
projeto usando módulos. Em vez disso, sugerimos que você crie um único projeto
ao seguir cada etapa da demonstração.
Crie uma classe de controlador, Controller.java
neste projeto de exemplo, para
definir os endpoints. Nesse arquivo, importe a anotação @GetMapping
da
dependência spring-boot-starter-web
.
import org.springframework.web.bind.annotation.GetMapping;
Inclua a anotação do controlador do framework Spring acima da definição da classe para indicar a finalidade dela.
@org.springframework.stereotype.Controller
public class Controller {
Em seguida, implemente as duas rotas e uma rota adicional para o tratamento de erros.
/** 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";
}
Testar o complemento
Inicie o servidor. Em seguida, faça login no Google Sala de Aula como um dos seus professores de teste. Navegue até a guia Atividades e crie uma nova Atividade. Selecione o complemento no seletor Complementos. O iframe é aberto e o complemento carrega o URI de configuração de anexo que você especificou na página Configuração do app do SDK do Marketplace.
Parabéns! Você já pode seguir para a próxima etapa: fazer login de usuários com o SSO do Google.