สร้างส่วนเสริมของ Classroom

นี่เป็นคำแนะนำแบบทีละขั้นแรกในชุดคำแนะนำแบบทีละขั้นเกี่ยวกับส่วนเสริมของ Classroom

ในคำแนะนำแบบทีละขั้นนี้ คุณจะได้วางรากฐานสำหรับการพัฒนาเว็บแอปพลิเคชันและเผยแพร่เป็นส่วนเสริมของ Classroom คำแนะนำแบบทีละขั้น ในอนาคตจะขยายแอปนี้

ในคำแนะนำแบบทีละขั้นนี้ คุณจะต้องทำดังนี้

  • สร้างโปรเจ็กต์ Google Cloud ใหม่สำหรับส่วนเสริม
  • สร้างเว็บแอป Skeleton ที่มีปุ่มลงชื่อเข้าใช้ตัวยึดตำแหน่ง
  • เผยแพร่ข้อมูลผลิตภัณฑ์ใน Store ของ Google Workspace Marketplace สำหรับส่วนเสริม

เมื่อดำเนินการเสร็จแล้ว คุณจะติดตั้งส่วนเสริมและโหลดส่วนเสริมใน iframe ของส่วนเสริมของ Classroom ได้

สิ่งที่ต้องดำเนินการก่อน

เลือกภาษาเพื่อดูข้อกำหนดเบื้องต้นที่เหมาะสม

Python

ตัวอย่าง Python ของเราใช้เฟรมเวิร์ก Flask คุณสามารถดาวน์โหลดซอร์สโค้ดที่สมบูรณ์สำหรับคำแนะนำแบบทีละขั้นทั้งหมดได้จากหน้าภาพรวม โค้ดสำหรับคำแนะนำแบบทีละขั้นนี้จะอยู่ในไดเรกทอรี /flask/01-basic-app/

หากจำเป็น ให้ติดตั้ง Python 3.7+ และตรวจสอบว่ามี pip ให้ใช้งาน

python -m ensurepip --upgrade

นอกจากนี้ เราขอแนะนำให้คุณตั้งค่าและเปิดใช้งานสภาพแวดล้อมเสมือนของ Python ใหม่

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

ไดเรกทอรีย่อยคำแนะนำแบบทีละขั้นแต่ละรายการในตัวอย่างที่ดาวน์โหลดมาจะมี requirements.txt คุณติดตั้งไลบรารีที่จำเป็นได้อย่างรวดเร็วโดยใช้ pip ใช้รายการต่อไปนี้เพื่อติดตั้งไลบรารีที่จำเป็นสำหรับคำแนะนำแบบทีละขั้นนี้

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

Node.js

ตัวอย่าง Node.js ของเราใช้เฟรมเวิร์ก Express คุณสามารถดาวน์โหลดซอร์สโค้ดที่สมบูรณ์สำหรับคำแนะนำแบบทีละขั้นทั้งหมดได้จากหน้าภาพรวม

หากจำเป็น ให้ติดตั้ง NodeJS v16.13+

ติดตั้งโมดูลโหนดที่จำเป็นโดยใช้ npm

npm install

Java

ตัวอย่าง Java ของเราใช้เฟรมเวิร์ก Spring Boot คุณสามารถดาวน์โหลดซอร์สโค้ดที่สมบูรณ์สำหรับคำแนะนำแบบทีละขั้นทั้งหมดได้จากหน้าภาพรวม

ติดตั้ง Java 11+ หากยังไม่ได้ติดตั้งในเครื่อง

แอปพลิเคชัน Spring Boot สามารถใช้ Gradle หรือ Maven เพื่อจัดการบิลด์และจัดการการขึ้นต่อกันได้ ตัวอย่างนี้มี Wrapper ของ Maven ที่ช่วยให้สามารถสร้างบิลด์ได้สำเร็จโดยที่คุณไม่ต้องติดตั้ง Maven เอง

หากต้องการเรียกใช้ตัวอย่างที่เราให้ไว้ ให้เรียกใช้คำสั่งต่อไปนี้ในไดเรกทอรีที่คุณดาวน์โหลดโปรเจ็กต์เพื่อให้แน่ใจว่าคุณมีข้อกำหนดเบื้องต้นในการเรียกใช้โปรเจ็กต์

java --version
./mvnw --version

หรือบน Windows:

java -version
mvnw.cmd --version

ตั้งค่าโปรเจ็กต์ Google Cloud

โปรเจ็กต์ Google Cloud จะควบคุมสิทธิ์เข้าถึง Classroom API และวิธีการตรวจสอบสิทธิ์ที่จำเป็น วิธีการต่อไปนี้นำคุณผ่านขั้นตอนขั้นต่ำในการสร้างและกำหนดค่าโปรเจ็กต์ใหม่เพื่อใช้กับส่วนเสริมของคุณ

สร้างโปรเจ็กต์

สร้างโปรเจ็กต์ Google Cloud ใหม่โดยไปที่หน้าการสร้างโปรเจ็กต์ คุณตั้งชื่อโปรเจ็กต์ใหม่ได้ คลิกสร้าง

ระบบจะใช้เวลาสักครู่ในการสร้างโปรเจ็กต์ใหม่ให้เสร็จสมบูรณ์ เมื่อดำเนินการเสร็จแล้ว อย่าลืมเลือกโปรเจ็กต์ โดยคุณสามารถเลือกโปรเจ็กต์ในเมนูแบบเลื่อนลงของตัวเลือกโปรเจ็กต์ที่ด้านบนของหน้าจอ หรือคลิกเลือกโปรเจ็กต์ในเมนูการแจ้งเตือนที่ด้านขวาบน

เลือกโปรเจ็กต์ในคอนโซล Google Cloud

แนบ SDK ของ Google Workspace Marketplace กับโปรเจ็กต์ Google Cloud

ไปที่เบราว์เซอร์ไลบรารี API ค้นหา Google Workspace Marketplace SDK คุณจะเห็น SDK ปรากฏในรายการผลการค้นหา

การ์ด Google Workspace Marketplace SDK

เลือกการ์ด SDK ของ Google Workspace Marketplace แล้วคลิกเปิดใช้

กำหนดค่า SDK ของ Google Workspace Marketplace

Google Workspace Marketplace จะแสดงข้อมูลที่ผู้ใช้และผู้ดูแลระบบใช้ติดตั้งส่วนเสริม กำหนดค่าการกำหนดค่าแอปและรายชื่อร้านค้าของ Marketplace SDK และหน้าจอคำยินยอม OAuth เพื่อดำเนินการต่อ

การกำหนดค่าแอป

ไปที่หน้าการกำหนดค่าแอปของ Marketplace SDK ระบุข้อมูลต่อไปนี้

  • ตั้งค่าระดับการเข้าถึงแอปเป็น Public หรือ Private

    • การตั้งค่าสาธารณะมีไว้สำหรับแอปที่จะเผยแพร่ต่อผู้ใช้ปลายทางในท้ายที่สุด แอปสาธารณะจะต้องผ่านกระบวนการอนุมัติก่อนจึงจะเผยแพร่ไปยังผู้ใช้ปลายทางได้ แต่คุณจะระบุผู้ใช้ที่ติดตั้งและทดสอบแอปเป็นเวอร์ชันร่างได้ นี่คือสถานะก่อนการเผยแพร่ที่ให้คุณทดสอบและพัฒนาส่วนเสริมก่อนส่งเพื่อขออนุมัติ
    • การตั้งค่าส่วนตัวเหมาะสำหรับการทดสอบและพัฒนาภายใน แอปส่วนตัวจะติดตั้งได้โดยผู้ใช้ในโดเมนเดียวกับโปรเจ็กต์ที่สร้างขึ้นเท่านั้น ดังนั้นคุณควรตั้งค่าระดับการเข้าถึงเป็น "ส่วนตัว" เฉพาะในกรณีที่สร้างโปรเจ็กต์ในโดเมนที่มีการสมัครใช้บริการ Google Workspace for Education ไม่เช่นนั้นผู้ใช้ทดสอบจะเปิดใช้งานส่วนเสริมของ Classroom ไม่ได้
  • ตั้งค่าการตั้งค่าการติดตั้งเป็น Admin Only install หากต้องการจำกัดการติดตั้งให้กับผู้ดูแลระบบโดเมนเท่านั้น

  • เลือกส่วนเสริมของ Classroom ในส่วนการผสานรวมแอป ระบบจะแจ้งให้คุณดำเนินการกับ URI ของการตั้งค่าไฟล์แนบที่ปลอดภัย ซึ่งเป็น URL ที่คุณคาดว่าจะโหลดเมื่อผู้ใช้เปิดส่วนเสริม สำหรับคำแนะนำแบบทีละขั้นนี้ ควรเป็น https://<your domain>/addon-discovery

  • คำนำหน้า URI ของไฟล์แนบที่อนุญาตใช้เพื่อตรวจสอบ URI ที่ตั้งค่าไว้ใน AddOnAttachment โดยใช้เมธอด courses.*.addOnAttachments.create และ courses.*.addOnAttachments.patch การตรวจสอบจะเป็นการจับคู่คำนำหน้าสตริงตามตัวอักษรและไม่อนุญาตให้ใช้ไวลด์การ์ดในขณะนี้ เพิ่มโดเมนรากของเซิร์ฟเวอร์เนื้อหาเป็นอย่างน้อย เช่น https://localhost:5000/ หรือ https://cdn.myedtech.com/

  • เพิ่มขอบเขต OAuth เดียวกันกับที่ให้ไว้ในหน้าจอคำยินยอม OAuth ในขั้นตอนก่อนหน้า

  • กรอกข้อมูลในช่องต่างๆ ตามความเหมาะสมกับองค์กรในส่วนลิงก์นักพัฒนาซอฟต์แวร์

ข้อมูลผลิตภัณฑ์ใน Store

ไปที่หน้าข้อมูลผลิตภัณฑ์ใน Store ของ Marketplace SDK ระบุข้อมูลต่อไปนี้

  • ในส่วนรายละเอียดแอป ให้เพิ่มภาษาหรือขยายเมนูแบบเลื่อนลงข้างภาษาที่แสดงอยู่แล้ว ระบุชื่อแอปพลิเคชันและคำอธิบาย ซึ่งจะปรากฏในหน้าข้อมูลผลิตภัณฑ์ใน Store ของ Google Workspace Marketplace คลิกเสร็จสิ้นเพื่อบันทึก
  • เลือกหมวดหมู่สำหรับส่วนเสริม
  • ในส่วนเนื้อหากราฟิก ให้ใส่รูปภาพตามช่องที่ต้องกรอก เครื่องมือเหล่านี้สามารถเปลี่ยนได้ในภายหลัง และสามารถใช้เป็นตัวยึดตำแหน่งได้ในตอนนี้
  • ในส่วนลิงก์ขอรับความช่วยเหลือ ให้ระบุ URL ที่ขอ ซึ่งอาจเป็นตัวยึดตำแหน่งหากคุณตั้งค่าระดับการเข้าถึงแอปเป็นส่วนตัวในขั้นตอนก่อนหน้า

หากคุณตั้งค่าระดับการเข้าถึงแอปเป็นส่วนตัวในขั้นตอนก่อนหน้า ให้คลิกเผยแพร่ ซึ่งจะทำให้แอปพร้อมให้ติดตั้งทันที หากคุณตั้งค่าระดับการเข้าถึงแอปเป็นสาธารณะ ให้เพิ่มอีเมลในส่วนผู้ทดสอบฉบับร่างสำหรับผู้ใช้ทดสอบ แล้วคลิกบันทึกฉบับร่าง

หน้าจอคำยินยอม OAuth จะปรากฏขึ้นเมื่อผู้ใช้ให้สิทธิ์แอปของคุณเป็นครั้งแรก โดยจะแจ้งให้อนุญาตให้แอปเข้าถึงข้อมูลส่วนตัวและข้อมูลบัญชีของตนตามขอบเขตที่คุณเปิดใช้

ไปที่หน้าการสร้างหน้าจอขอความยินยอม OAuth ระบุข้อมูลต่อไปนี้

  • ตั้งค่าประเภทผู้ใช้เป็นภายนอก คลิกสร้าง
  • ในหน้าถัดไป ให้ป้อนรายละเอียดแอปที่จำเป็นและข้อมูลติดต่อ ระบุโดเมนที่โฮสต์แอปของคุณในส่วนโดเมนที่ได้รับอนุญาต คลิกบันทึกและดำเนินการต่อ
  • เพิ่มขอบเขต OAuth ที่เว็บแอปต้องใช้ โปรดดูที่คู่มือการกำหนดค่า OAuth เพื่อดูการสนทนาโดยละเอียดเกี่ยวกับขอบเขตและวัตถุประสงค์ของขอบเขต

    คุณต้องขอขอบเขตต่อไปนี้อย่างน้อย 1 รายการเพื่อให้ Google ส่งพารามิเตอร์การค้นหา login_hint ได้ ดูคำอธิบายลักษณะการทำงานนี้อย่างละเอียดได้ในคู่มือการกำหนดค่า OAuth

    • https://www.googleapis.com/auth/userinfo.email (รวมอยู่แล้ว)
    • https://www.googleapis.com/auth/userinfo.profile (รวมอยู่แล้ว)

    ขอบเขตต่อไปนี้มีไว้สำหรับส่วนเสริมของ Classroom โดยเฉพาะ

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

    รวมถึงระบุขอบเขต Google API อื่นๆ ที่แอปต้องการจากผู้ใช้ปลายทาง

    คลิกบันทึกและต่อไป

  • ระบุที่อยู่อีเมลของบัญชีทดสอบในหน้าผู้ใช้ทดสอบ คลิกบันทึกและต่อไป

ตรวจสอบว่าการตั้งค่าของคุณถูกต้อง แล้วกลับไปที่หน้าแดชบอร์ด

ติดตั้งส่วนเสริม

ตอนนี้คุณติดตั้งส่วนเสริมโดยใช้ลิงก์ที่ด้านบนของหน้าข้อมูลผลิตภัณฑ์ใน Store ของ Marketplace SDK ได้แล้ว คลิก URL ของแอปที่ด้านบนของหน้าเพื่อดูข้อมูล จากนั้นเลือกติดตั้ง

สร้างเว็บแอปพื้นฐาน

ตั้งค่า Skeleton Web Application โดยใช้ 2 เส้นทาง คำแนะนำแบบทีละขั้นในอนาคตจะขยายการสมัครนี้ ดังนั้น ในตอนนี้ให้สร้างหน้า Landing Page สำหรับส่วนเสริม /addon-discovery และหน้าจำลอง / สำหรับ "เว็บไซต์ของบริษัท" ของเรา

ตัวอย่างเว็บแอปใน iframe

ใช้ปลายทาง 2 อย่างนี้

  • /: แสดงข้อความต้อนรับและปุ่มเพื่อปิดทั้งแท็บปัจจุบันและ iframe ของส่วนเสริม
  • /addon-discovery: แสดงข้อความต้อนรับและปุ่ม 2 ปุ่ม โดยปุ่มหนึ่งจะปิด iframe ของส่วนเสริม และอีกปุ่มหนึ่งสำหรับเปิดเว็บไซต์ในแท็บใหม่

โปรดทราบว่าเรากำลังเพิ่มปุ่มเพื่อสร้างและปิดหน้าต่างหรือ iframe ซึ่งจะสาธิตวิธีการนำผู้ใช้ไปยังแท็บใหม่อย่างปลอดภัยสำหรับการให้สิทธิ์ในคำแนะนำแบบทีละขั้นถัดไป

สร้างสคริปต์ยูทิลิตี

สร้างไดเรกทอรี static/scripts สร้างไฟล์ใหม่ addon-utils.js เพิ่มฟังก์ชัน 2 รายการต่อไปนี้

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

สร้างเส้นทาง

ใช้ปลายทาง /addon-discovery และ /

Python

ตั้งค่าไดเรกทอรีของแอปพลิเคชัน

สำหรับในตัวอย่างนี้ ให้จัดโครงสร้างตรรกะแอปพลิเคชันเป็นโมดูล Python นี่คือไดเรกทอรี webapp ในตัวอย่างที่เราให้ไว้

สร้างไดเรกทอรีสำหรับโมดูลเซิร์ฟเวอร์ เช่น webapp ย้ายไดเรกทอรี static ไปยังไดเรกทอรีโมดูล ให้สร้างไดเรกทอรี template ในไดเรกทอรีโมดูลด้วย โดยไฟล์ HTML จะแสดงที่นี่

สร้างโมดูลเซิร์ฟเวอร์*

สร้างไฟล์ __init__.py ในไดเรกทอรีโมดูล แล้วเพิ่มการนำเข้าและการประกาศต่อไปนี้

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

จากนั้นสร้างไฟล์เพื่อจัดการเส้นทางของเว็บแอป นี่คือ webapp/routes.py ในตัวอย่างที่เราให้ไว้ ใช้ 2 เส้นทางในไฟล์นี้

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

โปรดทราบว่าทั้ง 2 เส้นทางจะส่งตัวแปร message ไปยังเทมเพลต Jinja ที่เกี่ยวข้อง วิธีนี้มีประโยชน์ในการระบุว่าผู้ใช้ไปถึงหน้าใด

สร้างไฟล์การกำหนดค่าและเรียกใช้งาน

สร้างไฟล์ main.py และ config.py ในไดเรกทอรีรากของแอปพลิเคชัน กำหนดค่ารหัสลับใน 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."

ในไฟล์ main.py ให้นำเข้าโมดูลและเริ่มเซิร์ฟเวอร์ 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

เส้นทางจะลงทะเบียนในไฟล์ app.js ด้วยบรรทัดต่อไปนี้

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

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

เปิด /01-basic-app/routes/index.js และตรวจสอบโค้ด ถึงเส้นทางนี้จะถึงเมื่อผู้ใช้ปลายทางเข้าชมเว็บไซต์บริษัท เส้นทางจะแสดงการตอบสนองโดยใช้เทมเพลตแถบควบคุม index และส่งออบเจ็กต์ข้อมูลที่มีตัวแปร title และ message ให้เทมเพลต

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

เปิดเส้นทางที่ 2 /01-basic-app/routes/classroom-addon.js และตรวจสอบโค้ด ระบบจะมาถึงเส้นทางนี้เมื่อการเข้าชมของผู้ใช้ปลายทางของส่วนเสริม โปรดสังเกตว่าเส้นทางนี้ใช้เทมเพลต discovery แถบแฮนเดิล และเพิ่มเติมเลย์เอาต์ addon.hbs เพื่อแสดงหน้าให้แตกต่างจากเว็บไซต์ของบริษัท

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

Java

ตัวอย่างโค้ด Java ใช้โมดูลในการจัดแพ็กเกจขั้นตอนคำแนะนำแบบทีละขั้นตามลำดับ เนื่องจากนี่เป็นคำแนะนำแบบทีละขั้นครั้งแรก โค้ดจึงอยู่ภายใต้โมดูล step_01_basic_app ซึ่งเราไม่แนะนำให้คุณติดตั้งโปรเจ็กต์โดยใช้โมดูล แต่เราขอแนะนำให้คุณสร้างในโปรเจ็กต์เดียวเมื่อคุณทำตามแต่ละขั้นตอนในคำแนะนำแบบทีละขั้น

สร้างคลาสตัวควบคุม Controller.java ในโปรเจ็กต์ตัวอย่างนี้เพื่อกำหนดปลายทาง ในไฟล์นี้ ให้นำเข้าคำอธิบายประกอบ @GetMapping จากทรัพยากร Dependency spring-boot-starter-web

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

ใส่คำอธิบายประกอบตัวควบคุมเฟรมเวิร์ก Spring เหนือคำจำกัดความของคลาสเพื่อระบุวัตถุประสงค์ของคลาส

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

จากนั้นจึงใช้เส้นทาง 2 เส้นทางและเส้นทางเพิ่มเติมเพื่อจัดการข้อผิดพลาด

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

ทดสอบส่วนเสริม

เปิดเซิร์ฟเวอร์ จากนั้นลงชื่อเข้าใช้ Google Classroom ในฐานะผู้ใช้ทดสอบของ ครู ไปที่แท็บงานของชั้นเรียนและสร้างงานใหม่ เลือกส่วนเสริมจากเครื่องมือเลือกส่วนเสริม iframe จะเปิดขึ้นและส่วนเสริมจะโหลด URI การตั้งค่าไฟล์แนบที่คุณระบุไว้ในหน้าการกำหนดค่าแอปของ Marketplace SDK

ยินดีด้วย คุณก็พร้อมที่จะทำขั้นตอนถัดไปแล้ว นั่นคือการลงชื่อเข้าใช้ผู้ใช้ด้วย SSO ของ Google