Tạo tiện ích bổ sung dành cho Lớp học

Đây là hướng dẫn đầu tiên trong chuỗi hướng dẫn từng bước về tiện ích bổ sung trong Lớp học.

Trong hướng dẫn này, bạn đã đặt nền tảng để phát triển một ứng dụng web và phát hành ứng dụng đó dưới dạng tiện ích bổ sung của Lớp học. Các bước hướng dẫn sau này sẽ mở rộng ứng dụng này.

Trong quá trình hướng dẫn này, bạn sẽ hoàn thành các bước sau:

  • Tạo một dự án mới trên Google Cloud cho ứng dụng web của bạn.
  • Tạo một ứng dụng web cơ bản với các nút đăng nhập có phần giữ chỗ.
  • Xuất bản một Trang thông tin riêng tư trên Cửa hàng Google Workspace Marketplace (GWM) cho ứng dụng web của bạn.

Sau khi hoàn tất, bạn có thể cài đặt và tải tiện ích bổ sung đó vào iframe của tiện ích bổ sung cho Lớp học.

Điều kiện tiên quyết

Chọn một ngôn ngữ bên dưới để xem các điều kiện tiên quyết thích hợp:

Python

Ví dụ về Python của chúng ta sử dụng khung Flask. Bạn có thể tải mã nguồn hoàn chỉnh xuống cho tất cả hướng dẫn từng bước từ trang Tổng quan. Bạn có thể tìm thấy mã dành cho hướng dẫn từng bước cụ thể này trong thư mục /flask/01-basic-app/.

Nếu cần, hãy cài đặt Python 3.7 trở lên và đảm bảo rằng pip có sẵn.

python -m ensurepip --upgrade

Bạn cũng nên thiết lập và kích hoạt một môi trường ảo Python mới.

python3 -m venv .classroom-addon-env
source .classroom-addon-env/bin/activate

Mỗi thư mục con hướng dẫn từng bước trong các ví dụ đã tải xuống đều chứa một requirements.txt. Bạn có thể nhanh chóng cài đặt các thư viện cần thiết bằng pip. Hãy sử dụng các bước sau để cài đặt các thư viện cần thiết cho hướng dẫn này.

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

Node.js

Ví dụ Node.js của chúng ta sử dụng khung Express. Bạn có thể tải mã nguồn hoàn chỉnh xuống cho tất cả hướng dẫn từng bước trên Trang tổng quan.

Nếu cần, hãy cài đặt NodeJS phiên bản 16.13 trở lên.

Cài đặt các mô-đun nút bắt buộc bằng npm.

npm install

Java

Ví dụ Java của chúng ta sử dụng khung Spring Boot. Bạn có thể tải mã nguồn hoàn chỉnh xuống cho tất cả hướng dẫn từng bước từ Trang tổng quan.

Cài đặt Java 11 trở lên nếu bạn chưa cài đặt ứng dụng này trên máy.

Các ứng dụng Spring Boot có thể dùng Gradle hoặc Maven để xử lý các bản dựng và quản lý các phần phụ thuộc. Ví dụ này bao gồm trình bao bọc Maven giúp đảm bảo tạo ra một bản dựng thành công mà không yêu cầu bạn phải cài đặt chính Maven.

Để có thể chạy ví dụ chúng tôi cung cấp, hãy chạy các lệnh sau trong thư mục mà bạn đã tải dự án xuống nhằm đảm bảo bạn có các điều kiện tiên quyết để chạy dự án.

java --version
./mvnw --version

Hoặc trên Windows:

java -version
mvnw.cmd --version

Thiết lập một dự án trên Google Cloud

Quyền truy cập vào API Lớp học và các phương thức xác thực bắt buộc đều do các dự án Google Cloud kiểm soát. Các hướng dẫn sau đây sẽ hướng dẫn bạn thực hiện các bước tối thiểu để tạo và định cấu hình một dự án mới để sử dụng cùng tiện ích bổ sung.

Tạo dự án

Tạo một dự án mới trên Google Cloud bằng cách truy cập vào trang tạo dự án. Bạn có thể đặt bất kỳ tên nào cho dự án mới. Nhấp vào Create (Tạo).

Sẽ mất một chút thời gian để tạo dự án mới hoàn toàn. Sau khi hoàn tất, hãy nhớ chọn dự án; bạn có thể chọn dự án đó trong trình đơn thả xuống bộ chọn dự án ở đầu màn hình, hoặc nhấp vào CHỌN dự án trong trình đơn thông báo ở trên cùng bên phải.

Chọn dự án trong bảng điều khiển
Google Cloud

Đính kèm SDK GWM vào dự án Google Cloud

Chuyển đến trình duyệt Thư viện API. Tìm Google Workspace Marketplace SDK. Bạn sẽ thấy SDK xuất hiện trong danh sách kết quả.

Thẻ SDK Google Workspace Marketplace

Chọn thẻ SDK Google Workspace Marketplace, sau đó nhấp vào Bật.

Định cấu hình SDK GWM

GWM cung cấp danh sách những người dùng và quản trị viên cài đặt tiện ích bổ sung của bạn. Hãy định cấu hình Màn hình đồng ý OAuthCấu hình ứng dụng cũng như Trang thông tin trên Cửa hàng Play của SDK GWM để tiếp tục.

Màn hình đồng ý OAuth xuất hiện khi người dùng uỷ quyền ứng dụng lần đầu tiên. Màn hình này nhắc họ cho phép ứng dụng truy cập vào thông tin cá nhân và thông tin tài khoản của họ, như được ghi rõ bằng các phạm vi mà bạn bật.

Chuyển đến trang tạo màn hình xin phép bằng OAuth. Cung cấp các thông tin sau:

  • Đặt User Type (Loại người dùng) thành External (Bên ngoài). Nhấp vào Create (Tạo).
  • Trên trang tiếp theo, hãy điền thông tin liên hệ và chi tiết cần thiết về ứng dụng. Cung cấp mọi miền lưu trữ ứng dụng của bạn theo Miền được uỷ quyền. Nhấp vào LƯU VÀ TIẾP TỤC.
  • Thêm mọi Phạm vi OAuth mà ứng dụng web của bạn yêu cầu. Xem hướng dẫn cấu hình OAuth để biết nội dung thảo luận chuyên sâu về phạm vi và mục đích của các phạm vi này.

    Bạn phải yêu cầu ít nhất một trong các phạm vi sau để Google gửi tham số truy vấn login_hint. Bạn có thể xem nội dung giải thích chi tiết hơn về hành vi này trong hướng dẫn định cấu hình OAuth:

    • https://www.googleapis.com/auth/userinfo.email (đã có sẵn)
    • https://www.googleapis.com/auth/userinfo.profile (đã có sẵn)

    Các phạm vi sau đây dành riêng cho các tiện ích bổ sung dành cho Lớp học:

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

    Ngoài ra, hãy thêm mọi phạm vi API của Google mà ứng dụng của bạn yêu cầu từ người dùng cuối.

    Nhấp vào LƯU VÀ TIẾP TỤC.

  • Liệt kê địa chỉ email của một tài khoản thử nghiệm trên trang Người dùng thử nghiệm. Nhấp vào LƯU VÀ TIẾP TỤC.

Xác nhận rằng chế độ cài đặt của bạn là chính xác, rồi quay lại trang tổng quan.

Cấu hình ứng dụng

Chuyển đến trang Cấu hình ứng dụng của GWM SDK. Cung cấp các thông tin sau:

  • Đặt Chế độ hiển thị của ứng dụng thành Private. Chế độ cài đặt này phù hợp cho mục đích kiểm thử và phát triển, đồng thời là lựa chọn thích hợp cho các hướng dẫn này. Chỉ chọn Public nếu bạn đã sẵn sàng để công chúng sử dụng tiện ích bổ sung của mình.

  • Đặt Cài đặt cài đặt thành Admin Only install nếu bạn muốn hạn chế việc cài đặt cho quản trị viên miền.

  • Trong phần Tích hợp ứng dụng, hãy chọn Tiện ích bổ sung cho Lớp học. Bạn được nhắc URI thiết lập tệp đính kèm bảo mật; đây là URL mà bạn mong muốn được tải khi người dùng mở tiện ích bổ sung. Theo hướng dẫn này, giá trị này phải là https://<your domain>/addon-discovery.

  • Tiền tố URI tệp đính kèm được phép dùng để xác thực các URI được đặt trong AddOnAttachment bằng phương thức courses.*.addOnAttachments.createcourses.*.addOnAttachments.patch. Quy trình xác thực là so khớp tiền tố chuỗi theo giá trị cố định và không cho phép sử dụng thẻ đại diện tại thời điểm này. Hiện tại, bạn có thể để trống các trường này.

  • Thêm cùng một Phạm vi OAuth như đã cung cấp trong màn hình xin phép bằng OAuth ở bước trước.

  • Điền các trường phù hợp với tổ chức của bạn trong Đường liên kết dành cho nhà phát triển.

Danh sách cửa hàng

Chuyển đến trang Trang thông tin trên Cửa hàng Play của GWM SDK. Cung cấp các thông tin sau:

  • Trong Chi tiết ứng dụng, hãy thêm ngôn ngữ hoặc mở rộng trình đơn thả xuống bên cạnh ngôn ngữ đã liệt kê. Cung cấp Tên ứng dụng và nội dung mô tả; những tên này sẽ xuất hiện trên trang thông tin của tiện ích bổ sung GWM trên Cửa hàng Play. Nhấp vào Xong để lưu.
  • Chọn một Danh mục cho tiện ích bổ sung của bạn.
  • Trong mục Thành phần đồ hoạ, hãy cung cấp hình ảnh cho các trường bắt buộc. Bạn có thể thay đổi các lớp này sau và có thể là phần giữ chỗ nếu đặt Chế độ hiển thị của ứng dụng thành Riêng tư trong bước trước.
  • Trong phần Đường liên kết hỗ trợ, hãy cung cấp các URL được yêu cầu. Các URL này có thể là phần giữ chỗ nếu bạn đặt Chế độ hiển thị của ứng dụng thành Riêng tư trong bước trước.

Nhấp vào XUẤT BẢN để lưu chế độ cài đặt của bạn. Nếu bạn đặt Chế độ hiển thị của ứng dụng thành Riêng tư ở bước trước, ứng dụng sẽ ngay lập tức xuất hiện để cài đặt. Nếu bạn đặt Chế độ hiển thị của ứng dụng thành Công khai, thì ứng dụng sẽ được nhóm GWM xem xét trước khi được cung cấp để cài đặt.

Cài đặt tiện ích bổ sung

Giờ đây, bạn có thể cài đặt tiện ích bổ sung bằng cách sử dụng đường liên kết ở đầu trang Trang thông tin trên Cửa hàng Play của SDK GWM. Nhấp vào URL ứng dụng ở đầu trang để xem trang thông tin, sau đó chọn Cài đặt.

Tạo ứng dụng web cơ bản

Thiết lập ứng dụng web cơ bản với 2 tuyến. Các bước hướng dẫn sau này sẽ mở rộng ứng dụng này, vì vậy, bây giờ chỉ cần tạo trang đích cho tiện ích bổ sung /addon-discovery và trang chỉ mục mô phỏng / cho "trang web công ty" của chúng tôi.

Ứng dụng web mẫu trong iframe

Triển khai 2 điểm cuối sau:

  • /: hiển thị thông báo chào mừng và nút để đóng cả thẻ hiện tại và iframe của tiện ích bổ sung.
  • /addon-discovery: hiển thị thông báo chào mừng và 2 nút: một để đóng iframe của tiện ích bổ sung và một nút để mở một trang web trong thẻ mới.

Xin lưu ý rằng chúng ta sẽ thêm các nút để tạo và đóng cửa sổ hoặc iframe. Các tệp này minh hoạ một phương thức đưa người dùng sang một thẻ mới để được cấp quyền một cách an toàn trong hướng dẫn từng bước tiếp theo.

Tạo tập lệnh tiện ích

Tạo thư mục static/scripts. Tạo tệp mới addon-utils.js. Thêm hai hàm sau.

/**
 *   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',
  }, '*');
};

Tạo tuyến đường

Triển khai các điểm cuối /addon-discovery/.

Python

Thiết lập thư mục ứng dụng

Để phục vụ mục đích của ví dụ này, hãy cấu trúc logic ứng dụng dưới dạng mô-đun Python. Đây là thư mục webapp trong ví dụ chúng tôi cung cấp.

Tạo thư mục cho mô-đun máy chủ, ví dụ: webapp. Di chuyển thư mục static vào thư mục mô-đun. Tạo thư mục template trong thư mục mô-đun; các tệp HTML của bạn sẽ nằm tại đây.

Tạo mô-đun máy chủ*

Tạo tệp __init__.py trong thư mục mô-đun và thêm các mục nhập và khai báo sau.

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

Sau đó, hãy tạo một tệp để xử lý các tuyến của ứng dụng web. Đó là webapp/routes.py trong ví dụ chúng tôi cung cấp. Triển khai 2 tuyến trong tệp này.

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.")

Xin lưu ý rằng cả hai tuyến của chúng tôi đều truyền biến message đến các mẫu Jinja tương ứng. Điều này rất hữu ích trong việc xác định trang nào người dùng đã truy cập.

Tạo tệp cấu hình và khởi chạy

Trong thư mục gốc của ứng dụng, hãy tạo các tệp main.pyconfig.py. Định cấu hình khoá bí mật của bạn trong 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."

Trong tệp main.py, hãy nhập mô-đun và khởi động máy chủ 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

Các tuyến đường được đăng ký trong tệp app.js bằng các dòng sau.

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

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

Mở /01-basic-app/routes/index.js và xem lại mã. Lộ trình này sẽ truy cập khi người dùng cuối truy cập trang web của công ty. Tuyến đường này sẽ kết xuất phản hồi bằng mẫu Tay điều khiển index, đồng thời truyền mẫu này một đối tượng dữ liệu chứa các biến titlemessage.

router.get('/', function (req, res, next) {
  res.render('index', {
    title: 'Education Technology',
    message: 'Welcome to our website!'
  });
});

Mở tuyến thứ hai /01-basic-app/routes/classroom-addon.js và xem lại mã. Lộ trình này đạt đến khi lượt truy cập của người dùng cuối là tiện ích bổ sung. Xin lưu ý rằng tuyến này sử dụng mẫu Tay cầm discovery và ngoài bố cục addon.hbs để hiển thị trang khác với trang web của công ty.

router.get('/', function (req, res, next) {
  res.render('discovery', {
    layout: 'addon.hbs',
    title: 'Education Technology Classroom add-on',
    message: `Welcome.`
});
});

Java

Ví dụ về mã Java sử dụng các mô-đun để đóng gói các bước hướng dẫn từng bước theo tuần tự. Vì đây là hướng dẫn đầu tiên nên mã nằm trong mô-đun step_01_basic_app. Bạn không nên triển khai dự án của mình bằng các mô-đun; thay vào đó, bạn nên xây dựng trên một dự án đơn lẻ khi làm theo từng bước trong hướng dẫn từng bước.

Tạo một lớp tay điều khiển (Controller.java) trong dự án mẫu này để xác định các điểm cuối. Trong tệp này, hãy nhập chú thích @GetMapping từ phần phụ thuộc spring-boot-starter-web.

import org.springframework.web.bind.annotation.GetMapping;

Đưa chú thích bộ điều khiển khung Spring vào phía trên định nghĩa lớp để cho biết mục đích của lớp.

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

Sau đó, hãy triển khai 2 tuyến này và một tuyến bổ sung để xử lý lỗi.

/** 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";
}

Kiểm thử tiện ích bổ sung

Khởi chạy máy chủ. Sau đó, hãy đăng nhập vào Google Lớp học với tư cách là một trong những người dùng kiểm thử dành cho Giáo viên. Chuyển đến thẻ Bài tập trên lớp rồi tạo một Bài tập mới. Nhấp vào nút Tiện ích bổ sung bên dưới vùng văn bản rồi chọn tiện ích bổ sung của bạn. Iframe sẽ mở ra và tiện ích bổ sung này sẽ tải URI thiết lập tệp đính kèm mà bạn đã chỉ định trên trang Cấu hình ứng dụng của SDK GWM.

Xin chúc mừng! Bạn đã sẵn sàng để chuyển sang bước tiếp theo: đăng nhập cho người dùng bằng dịch vụ SSO của Google.