有没有办法使用 Pub Sub 收听多个 Google 课堂课程的更新?

Is there a way to listen for updates on multiple Google Classroom Courses using Pub Sub?

目标

当学生完成作业或为 任何 课程添加作业时触发更新 Cloud Firestore 的功能。

问题

official docs 声明 CourseWorkChangesInfo 的提要需要 courseId,我想避免为每个课程注册和订阅,每个 运行在自己的线程上。

我有什么

我成功注册了一门课程:

def registration_body():
    return {  # An instruction to Classroom to send notifications from the `feed` to the
        # provided destination.
        "feed": {  # Information about a `Feed` with a `feed_type` of `COURSE_WORK_CHANGES`.
            "feedType": "COURSE_WORK_CHANGES",  # Information about a `Feed` with a `feed_type` of `COURSE_WORK_CHANGES`.
            "courseWorkChangesInfo": { 
                # This field must be specified if `feed_type` is `COURSE_WORK_CHANGES`.
                "courseId": "xxxxxxxxxxxx",  # The `course_id` of the course to subscribe to work changes for.
            },
        },
        "cloudPubsubTopic": {
            "topicName": "projects/xxxxx/topics/gcr-course",  # The `name` field of a Cloud Pub/Sub
        },
    }


def create_registration(service):
    """
    Creates a registration to the Google Classroom Service which will listen
    for updates on Google Classroom according to the requested body.
    Pub Sub will emit a payload to subscribers when a classroom upate occurs.

    Args:
        service (Google Classroom Service): Google Classroom Service as retrieved
        from the Google Aclassroom Service builder

    Returns:
        Registration: Google Classroom Registration
    """

    body = registration_body()
    try:
        registration = service.registrations().create(body=body).execute()
        print(f"Registration to Google CLassroom Created\n{registration}")
        return registration
    except Exception as e:
        print(e)
        raise

并且我能够与我的 FastAPI 服务器一起成功订阅这些更新:

def init_subscription():
    # [INIT PUBSUB SUBSCRIBER AND CALLBACKS]
    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        "x-student-portal", "gcr-course-sub"
    )
    future = subscriber.subscribe(subscription_path, callback)
    with subscriber:
        try:
            future.result()
        except TimeoutError:
            future.cancel()
            future.result()


def callback(message):
    print("message recieved")
    # do_stuff(message)
    print(message)
    message.ack()

注册订阅初始化:

@app.on_event("startup")
async def startup_event():
    global db
    global gc_api
    global gc_service
    global gc_registration
    global future
    global pub_sub_subscription_thread

    db = firestore.FirestoreDatabase()
    gc_service = get_service()
    gc_api = ClassroomApi(service=gc_service)
    gc_registration = publisher_client.create_registration(gc_service)

    pub_sub_subscription_thread = multiprocessing.Process(
        target=publisher_client.init_subscription
    )
    pub_sub_subscription_thread.start()

结论

我非常想避免 运行 多个线程,同时仍然能够订阅我所有课程的更改。

如有任何建议,我们将不胜感激。

答案:

这是不可能的。

如您所见here:

,您不能通过一次注册来跟踪多门课程的课程作业更改

Types of feeds

The Classroom API currently offers three types of feed:

  • Each domain has a roster changes for domain feed, which exposes notifications when students and teachers join and leave courses in that domain.
  • Each course has a roster changes for course feed, which exposes notifications when students and teachers join and leave courses in that course.
  • Each course has a course work changes for course feed, which exposes notifications when any course work or student submission objects are created or modified in that course.

提交功能请求:

如果您认为此功能可能有用,我建议您使用 this template 在 Issue Tracker 中提交功能请求。

参考: