Criar um complemento do Google Sala de Aula

Este é o primeiro tutorial da série de tutoriais sobre complementos do Google Sala de Aula.

Neste tutorial, você vai criar a base para desenvolver um aplicativo da Web e publicá-lo como um complemento do Google Sala de Aula. As próximas etapas do tutorial vão expandir esse app.

Neste tutorial, você vai fazer o seguinte:

  • Crie um projeto do Google Cloud para seu complemento.
  • Crie um app da Web esqueleto com botões de login de marcador de posição.
  • Publique uma página de detalhes da loja do Google Workspace Marketplace para seu complemento.

Depois de terminar, instale e carregue o complemento no iframe de complementos do Google Sala de Aula.

Pré-requisitos

Escolha um idioma para conferir os pré-requisitos adequados:

Python

Nosso exemplo em Python usa o framework Flask. Você pode baixar o código-fonte completo de todos os tutoriais na página "Visão geral". O código deste 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 baixados 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 do Node.js usa o framework Express. Você pode baixar o código-fonte completo de todos os tutoriais na página "Visão geral".

Se necessário, instale o NodeJS v16.13+.

Instale os módulos de nós necessários usando npm.

npm install

Java

Nosso exemplo em Java usa o framework Spring Boot. Você pode 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 ele ainda não estiver instalado na sua máquina.

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 uma compilação bem-sucedida sem exigir a instalação do Maven.

Para executar o exemplo fornecido, execute os comandos a seguir no diretório em que você baixou o projeto para garantir que 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 é controlado 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 seu complemento.

Criar o projeto

Crie um projeto do Google Cloud na página de criação de projetos. Você pode dar qualquer nome ao novo projeto. Clique em Criar.

A criação do novo projeto leva alguns instantes. Depois, selecione o projeto no menu suspenso do seletor na parte de cima da tela ou clique em SELECIONAR PROJETO no menu de notificações no canto superior direito.

Selecione o projeto no console do Google Cloud.

Anexe o SDK do Google Workspace Marketplace ao projeto do Google Cloud

Navegue até o navegador Biblioteca de APIs. Pesquise por Google Workspace Marketplace SDK. O SDK vai aparecer na lista de resultados.

O card do SDK do Google Workspace Marketplace

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 página em que usuários e administradores instalam seu complemento. Configure a Configuração do app e a Página 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 ou Private.

    • 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 usuários finais, mas você pode especificar usuários que podem instalar e testar como um Rascunho. Esse é um estado de pré-publicação que permite testar e desenvolver o complemento antes de enviá-lo para aprovação.
    • A configuração "Privada" é adequada para testes e desenvolvimento internos. Um app particular só pode ser instalado por usuários no mesmo domínio em que o projeto foi criado. Portanto, defina a visibilidade como privada somente 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 da 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 apps, selecione Complemento do Google Sala de Aula. Você vai receber uma solicitação para o URI de configuração de anexo seguro, que é o URL que você espera ser carregado quando um usuário abrir o complemento. Para os fins deste tutorial, use 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étodos courses.*.addOnAttachments.create e courses.*.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, como https://localhost:5000/ ou https://cdn.myedtech.com/.

  • Adicione os mesmos escopos do OAuth fornecidos na tela de permissão OAuth na etapa anterior.

  • Preencha os campos conforme apropriado para sua organização em Links do desenvolvedor.

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 para o aplicativo. Essas informações aparecem na página "Detalhes do app" do complemento no 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. Elas podem ser mudadas depois e podem ser marcadores de posição por enquanto.
  • Em Links de suporte, forneça os URLs solicitados. Eles podem ser marcadores de posição se você definir a visibilidade do app como Privada na etapa anterior.

Se você definiu a visibilidade do app como Privada na etapa anterior, clique em PUBLICAR. Seu app vai estar disponível para instalação imediatamente. 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.

A tela de consentimento do OAuth aparece quando os usuários autorizam seu app pela primeira vez. Ela solicita que eles permitam que o app acesse as informações pessoais e da conta, conforme determinado pelos escopos que você ativa.

Navegue até a página de criação da tela de consentimento do OAuth. Informe o seguinte:

  • Defina Tipo de usuário como Externo. Clique em Criar.
  • Na próxima página, preencha os detalhes do app e as informações de contato necessárias. Informe os domínios que hospedam seu app em Domínios autorizados. Clique em SALVAR E CONTINUAR.
  • Adicione os escopos do OAuth que seu app da Web exige. Consulte o guia de configuração do OAuth para uma discussão detalhada sobre escopos e finalidades.

    Você precisa solicitar pelo menos um dos seguintes escopos 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 dos 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 outros escopos de API do Google que seu 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 Usuários de teste. Clique em SALVAR E CONTINUAR.

Confirme se as configurações estão corretas e volte para o 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 em Ver no Marketplace na parte de cima da página para conferir a página de detalhes e escolha Instalar.

Criar um app da Web básico

Configure um aplicativo da Web esqueleto com duas rotas. As próximas etapas do tutorial vão expandir 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".

Exemplo de app da Web em iframe

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. Esses demonstram um método para abrir com segurança o usuário em uma nova guia para autorização no próximo tutorial.

Criar script de utilitário

Crie um diretório static/scripts. Crie um 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 este exemplo, estruture a lógica do aplicativo como um módulo do 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 também. É aqui que seus arquivos HTML vão ficar.

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 web app. Este é webapp/routes.py no 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.")

As duas rotas transmitem uma variável message aos respectivos modelos Jinja. Isso é útil para identificar a página que o usuário acessou.

Criar arquivos de configuração e de inicialização

No diretório raiz do aplicativo, crie os arquivos main.py e config.py. Configure sua 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

As rotas são registradas 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 é acessada 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 as 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 é acessada quando o usuário final visita o complemento. Observe que essa rota usa o modelo discovery Handlebars e também 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 do tutorial sequencial. Como este é o primeiro tutorial, 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 à medida que segue cada etapa do tutorial.

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 de classe para indicar a finalidade dela.

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

Em seguida, implemente as duas rotas e uma rota adicional para 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 usuários de teste Professor. Acesse a guia Atividades e crie uma nova atividade. Selecione seu complemento no seletor Complementos. O iframe é aberto e o complemento carrega o URI de configuração de anexo especificado na página Configuração do app do SDK do Marketplace.

Parabéns! Agora você pode seguir para a próxima etapa: fazer login de usuários com o SSO do Google.