Criar um complemento do Google Sala de Aula

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

Neste tutorial, você estabelece as bases para desenvolver um aplicativo da Web e publicá-lo como um complemento do Google Sala de Aula. As etapas do tutorial futuram expandir esse aplicativo.

Neste tutorial, você vai concluir as seguintes etapas:

  • Crie um projeto do Google Cloud para seu app da Web.
  • Crie um esqueleto de app da Web com botões de login de marcadores de posição.
  • Publique uma página "Detalhes do app" particular do Google Workspace Marketplace (GWM) para seu app da Web.

Quando terminar, você poderá instalar e carregar o complemento no iframe de complementos do Google Sala de Aula.

Pré-requisitos

Escolha uma linguagem abaixo para conferir os pré-requisitos apropriados:

Python

Nosso exemplo em Python usa o framework Flask. É possível fazer o download do código-fonte completo para todos os tutoriais na Página de visão geral. O código deste tutorial específico está disponível no diretório /flask/01-basic-app/.

Se necessário, instale o Python 3.7+ e verifique se 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 os códigos a seguir para instalar as bibliotecas necessárias para este tutorial.

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

Node.js

Nosso exemplo em Node.js usa o framework Express. É possível fazer o download do código-fonte completo para todos os tutoriais na Página de visão geral.

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

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

npm install

Java

Nosso exemplo em Java usa o framework Spring Boot (link em inglês). É possível fazer o download do código-fonte completo para todos os tutoriais na Página de visão geral.

Instale o Java 11+ se ele ainda não estiver instalado na máquina.

Os aplicativos do 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 próprio Maven.

Para executar nosso exemplo fornecido, execute os seguintes comandos no diretório em que você fez o download do projeto para garantir que tenha os pré-requisitos para executá-lo.

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 pelos projetos do Google Cloud. As instruções a seguir orientam você pelas etapas mínimas para criar e configurar um novo projeto para uso com seu complemento.

Criar o projeto

Acesse a página de criação de projetos para criar um projeto do Google Cloud. Você pode fornecer qualquer nome para o novo projeto. Clique em Criar.

Leva alguns instantes para o novo projeto ser totalmente criado. Depois disso, selecione o projeto. Escolha-o no menu suspenso do seletor de projetos, na parte superior da tela, ou clique em SELECIONAR PROJETO no menu de notificações no canto superior direito.

Selecione o projeto no console do
Google Cloud

Anexar o SDK do GWM 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.

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 GWM

O GWM fornece a listagem em que os usuários e administradores instalam seu complemento. Configure a Tela de consentimento OAuth, a Configuração do app e a Detalhes do app do SDK do GWM para continuar.

A tela de consentimento OAuth aparece quando os usuários autorizam o app pela primeira vez. Ela pede que eles permitam que o app acesse informações pessoais e da conta, conforme ditado pelos escopos ativados.

Navegue até a página de criação da tela de consentimento do OAuth. Forneça as seguintes informações:

  • Defina o 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. Forneça todos os domínios que hospedam seu app em Domínios autorizados. Clique em SALVAR E CONTINUAR.
  • Adicione todos os escopos OAuth que seu app da Web exigir. Consulte o guia de configuração do OAuth para uma discussão detalhada sobre escopos e a finalidade deles.

    É 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ída)
    • https://www.googleapis.com/auth/userinfo.profile (já incluída)

    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 qualquer outro escopo da API do Google que o app exija 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.

Verifique se as configurações estão corretas e volte para o painel.

Configuração do app

Acesse a página Configuração do app do SDK do GWM. Forneça as seguintes informações:

  • Defina a Visibilidade do app como Private. Essa configuração é adequada para testes e desenvolvimento e é a escolha adequada para estas instruções. Escolha Public apenas se estiver tudo pronto para que seu complemento seja usado pelo público em geral.

  • Defina Configurações de instalação como Admin Only install se quiser restringir a instalação aos administradores do domínio.

  • Em Integração do app, selecione Complemento do Google Sala de Aula. É necessário o URI de configuração de anexo seguro. Esse é o URL que espera-se ser carregado quando um usuário abrir o 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étodos courses.*.addOnAttachments.create e courses.*.addOnAttachments.patch. A validação é uma correspondência de prefixo de string literal e não permite o uso de curingas no momento. Você pode deixar esses campos em branco por enquanto.

  • Adicione os mesmos escopos do OAuth fornecidos na tela de permissão do 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 do SDK do GWM. Forneça as seguintes informações:

  • Em Detalhes do app, adicione um idioma ou expanda o menu suspenso ao lado do idioma já listado. Forneça um nome e descrições do aplicativo. Eles aparecem na página "Detalhes do app" do GWM do seu complemento. Clique em Concluído para salvar.
  • Escolha uma Categoria para o complemento.
  • Em Recursos gráficos, forneça imagens nos campos obrigatórios. Eles podem ser alterados mais tarde e podem ser marcadores de posição se você definir a visibilidade do app como Particular na etapa anterior.
  • Em Links de suporte, forneça os URLs solicitados. Eles podem ser marcadores se você tiver definido a visibilidade do app como Particular na etapa anterior.

Clique em PUBLICAR para salvar as configurações. Se você tiver definido a visibilidade do app como Particular na etapa anterior, seu app ficará imediatamente disponível para instalação. Se você definir a visibilidade do app como Público, seu app será enviado para revisão pela equipe do GWM antes de ser disponibilizado para instalação.

Instalar o complemento

Agora você pode instalar o complemento usando o link na parte superior da página Detalhes do app do SDK do GWM. Clique em URL do app 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 esqueleto de um aplicativo da Web com duas rotas. As etapas de tutoriais futuros expandem esse aplicativo. Por enquanto, basta criar uma página de destino para o complemento /addon-discovery e uma página de índice fictícia / para o "site da empresa".

Exemplo de app da Web no 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. Eles demonstram um método para colocar o usuário com segurança em uma nova guia para autorização no próximo tutorial.

Criar script 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 above, 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 Python. Esse é o diretório webapp no exemplo fornecido.

Crie um diretório para o módulo de servidor, webapp, por exemplo. Mova o diretório static para o diretório do módulo. Crie também um diretório template no diretório do módulo (os arquivos HTML devem ser inseridos 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. Esse é webapp/routes.py no exemplo fornecido. Implemente as duas rotas nesse 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.")

Nossas rotas passam uma variável message para os respectivos modelos Jinja. Isso é útil para identificar qual página o usuário alcançou.

Criar arquivos de configuração e iniciar

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 linhas a seguir.

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

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

Abra /01-basic-app/routes/index.js e revise o código. Esse trajeto é alcançado quando o usuário final acessa o site da empresa. A rota renderiza uma resposta usando o modelo do Handlebars index e transmite para o modelo um objeto de dados contendo 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 revise o código. Este trajeto é alcançado quando a visita do usuário final é o complemento. Esse trajeto usa o modelo 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 de tutorial. Como este é o primeiro tutorial, o código está no módulo step_01_basic_app. Não é esperado que você implemente o projeto usando módulos. Em vez disso, sugerimos que você crie em um único projeto enquanto 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 do Spring acima da definição de classe para indicar a finalidade da classe.

@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 seu servidor. Em seguida, faça login no Google Sala de Aula como um dos usuários de teste do Professor. Navegue até a guia Atividades e crie uma nova Atividade. Clique no botão Complementos abaixo da área de texto e selecione o complemento. O iframe é aberto e o complemento carrega o URI de configuração do anexo que você especificou na página Configuração do app do SDK do GWM.

Parabéns! Está tudo pronto para a próxima etapa: fazer login de usuários com o SSO do Google.