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

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

Trong phần hướng dẫn từng bước này, bạn đã đặt nền tảng để phát triển một ứng dụng web và xuất bản ứng dụng đó dưới dạng một tiện ích bổ sung cho Google Lớp học. Các bước hướng dẫn từng bước trong tương lai sẽ mở rộng ứng dụng này.

Trong hướng dẫn từng bước 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 tiện ích bổ sung.
  • Tạo một ứng dụng web skeleton với các nút đăng nhập phần giữ chỗ.
  • Xuất bản Trang thông tin trên Cửa hàng Play trên Google Workspace Marketplace cho tiện ích bổ sung của bạn.

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

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

Chọn ngôn ngữ để xem các điều kiện tiên quyết phù hợp:

Python

Ví dụ về Python của chúng tôi 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ã 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+ 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 làm theo các bước sau để cài đặt các thư viện cần thiết cho hướng dẫn từng bước này.

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

Node.js

Ví dụ Node.js của chúng tôi 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 từ Trang tổng quan.

Nếu cần, hãy cài đặt NodeJS v16.13+.

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 tôi sử dụng khung khởi động mùa xuân. 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 xây 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ụ mà 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ó đ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 do các dự án trên Google Cloud kiểm soát. Các hướng dẫn sau đây sẽ hướng dẫn bạn các bước tối thiểu để tạo và định cấu hình 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 trang tạo dự án. Bạn có thể cung cấp bất kỳ tên nào cho dự án mới. Nhấp vào Create (Tạo).

Hệ thống sẽ mất vài phút để tạo hoàn chỉnh dự án mới. 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 của bộ chọn dự án ở đầu màn hình hoặc nhấp vào SELECT PROJECT (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 của Google Workspace Marketplace vào dự án trên Google Cloud

Chuyển đến trình duyệt API Library (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 của Google Workspace Marketplace

Chọn thẻ SDK của Google Workspace Marketplace rồi nhấp vào Bật.

Định cấu hình SDK của Google Workspace Marketplace

Google Workspace Marketplace cung cấp danh sách cho 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 Cấu hình ứng dụng của SDK Marketplace và Danh sách cửa hàng cũng như Màn hình lấy sự đồng ý của OAuth để tiếp tục.

Cấu hình ứng dụng

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

  • Đặt Chế độ hiển thị của ứng dụng thành Public hoặc Private.

    • Chế độ cài đặt công khai này là dành cho các ứng dụng sẽ được phát hành cho người dùng cuối. Ứng dụng công khai phải trải qua quy trình phê duyệt trước khi phát hành cho người dùng cuối, nhưng bạn có thể chỉ định người dùng có thể cài đặt và kiểm thử ứng dụng dưới dạng Bản nháp. Đây là trạng thái trước khi phát hành, cho phép bạn thử nghiệm và phát triển tiện ích bổ sung trước khi gửi đi để phê duyệt.
    • Chế độ cài đặt riêng tư này phù hợp cho hoạt động kiểm thử và phát triển nội bộ. Chỉ người dùng trong cùng miền với dự án được tạo mới có thể cài đặt ứng dụng riêng tư. Do đó, bạn chỉ nên đặt chế độ hiển thị thành riêng tư nếu dự án được tạo trong một miền có gói thuê bao Google Workspace for Education, nếu không, người dùng thử nghiệm sẽ không thể chạy các tiện ích bổ sung cho Lớp học.
  • Đặt phần 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 đối với 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 dành cho Lớp học. Bạn được nhắc chuyển đến URI thiết lập tệp đính kèm bảo mật; đây là URL mà bạn muốn tải khi người dùng mở tiện ích bổ sung của bạn. Trong phần hướng dẫn này, bạn nên dùng https://<your domain>/addon-discovery.

  • Tiền tố URI đính kèm được phép dùng để xác thực các URI được đặt trong AddOnAttachment bằng cách sử dụng courses.*.addOnAttachments.create và phương thức courses.*.addOnAttachments.patch. Quy trình xác thực là một kết quả khớp với tiền tố chuỗi theo chữ và không cho phép sử dụng ký tự đại diện tại thời điểm này. Thêm ít nhất là miền gốc của máy chủ nội dung, chẳng hạn như https://localhost:5000/ hoặc https://cdn.myedtech.com/.

  • Thêm Phạm vi OAuth tương tự như được 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 phần Đường liên kết 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 SDK Marketplace. Cung cấp các thông tin sau:

  • Trong phần Chi tiết ứng dụng, hãy thêm một ngôn ngữ hoặc mở rộng trình đơn thả xuống bên cạnh ngôn ngữ đã được liệt kê. Cung cấp Tên ứng dụng và nội dung mô tả. Những thông tin này xuất hiện tại trang thông tin của tiện ích bổ sung trên Cửa hàng Google Workspace Marketplace. Nhấp vào Xong để lưu.
  • Chọn một Danh mục cho tiện ích bổ sung.
  • Trong phần Graphics assets (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 những đoạn mã này sau và hiện tại có thể là phần giữ chỗ.
  • 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ư ở bước trước.

Nếu bạn đặt Chế độ hiển thị của ứng dụng thành Riêng tư ở bước trước, hãy nhấp vào XUẤT BẢN; ứng dụng của bạn sẽ có thể cài đặt ngay lập tức. Nếu bạn đặt Chế độ hiển thị của ứng dụng thành Công khai, hãy thêm địa chỉ email trong khu vực Người kiểm thử bản nháp cho mọi người dùng kiểm thử rồi nhấp vào Lưu bản nháp.

Màn hình đồng ý OAuth xuất hiện khi người dùng cho phép ứng dụng của bạn 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 nhập bằng giọng nói của 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. Hãy 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).
  • Trong trang tiếp theo, hãy điền thông tin liên hệ và thông tin bắt buộc về ứng dụng. Cung cấp mọi miền lưu trữ ứng dụng của bạn trong Miền được uỷ quyền. Nhấp vào LƯU VÀ TIẾP TỤC.
  • Thêm bất kỳ Phạm vi OAuth mà ứng dụng web của bạn yêu cầu. Hãy xem hướng dẫn cấu hình OAuth để thảo luận chi tiết về phạm vi và mục đích của các phạm vi đó.

    Bạn phải yêu cầu ít nhất một trong các phạm vi sau thì Google có thể 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 cấu hình OAuth:

    • https://www.googleapis.com/auth/userinfo.email (đã được bao gồm)
    • https://www.googleapis.com/auth/userinfo.profile (đã được bao gồm)

    Sau đây là các phạm vi 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 khác 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 bất kỳ tài khoản thử nghiệm nào 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 các chế độ cài đặt của bạn là chính xác, sau đó quay lại trang tổng quan.

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

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

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

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

Ví dụ về ứng dụng web 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à hai nút: một nút dùng để đóng iframe của tiện ích bổ sung và một nút để mở 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 video này minh hoạ một phương thức giúp đưa người dùng vào một thẻ mới một cách an toàn để uỷ quyề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 2 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, 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

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

Tạo thư mục cho mô-đun máy chủ, chẳng hạn như 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; tệp HTML của bạn sẽ nằm ở đây.

Xây dựng mô-đun máy chủ*

Tạo tệp __init__.py trong thư mục mô-đun rồi 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. Đây 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 đường của chúng tôi đều chuyển biến message đến các mẫu Jinja tương ứng. Điều này rất hữu ích khi xác định người dùng đã truy cập trang nào.

Tạo tệp cấu hình và 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 đượ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('/addon-discovery', addonRouter);

Mở /01-basic-app/routes/index.js và xem lại mã. Tuyến này sẽ truy cập khi người dùng cuối truy cập vào trang web của công ty. Tuyến này sẽ kết xuất phản hồi bằng cách sử dụng mẫu Tay cầm index và truyền cho mẫu 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ã. Tuyến này sẽ đạt đến khi tiện ích bổ sung của người dùng cuối truy cập. Hãy lưu ý rằng tuyến này sử dụng mẫu Tay cầm discovery và ngoài ra, 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 tuần tự. Vì đây là hướng dẫn từng bước đầu tiên, nên mã nằm trong mô-đun step_01_basic_app. Do đó, bạn không nên triển khai dự án bằng các mô-đun. Thay vào đó, bạn nên tạo trên một dự án duy nhất sau khi làm theo từng bước trong hướng dẫn từng bước.

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

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

Thêm chú thích trình điều khiển khung Spring ở 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à 1 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ủ của bạn. Sau đó, đă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ử Giáo viên. Chuyển đến thẻ Bài tập trên lớp và tạo một Bài tập mới. Chọn tiện ích bổ sung của bạn trong bộ chọn Tiện ích bổ sung. iframe sẽ mở ra và tiện ích bổ sung 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 Marketplace.

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.