โ† All skills
Tencent SkillHub ยท Developer Tools

Google Classroom

Google Classroom API integration with managed OAuth. Manage courses, assignments, students, teachers, and announcements. Use this skill when users want to cr...

skill openclawclawhub Free
0 Downloads
0 Stars
0 Installs
0 Score
High Signal

Google Classroom API integration with managed OAuth. Manage courses, assignments, students, teachers, and announcements. Use this skill when users want to cr...

โฌ‡ 0 downloads โ˜… 0 stars Unverified but indexed

Install for OpenClaw

Quick setup
  1. Download the package from Yavira.
  2. Extract the archive and review SKILL.md first.
  3. Import or place the package into your OpenClaw setup.

Requirements

Target platform
OpenClaw
Install method
Manual import
Extraction
Extract archive
Prerequisites
OpenClaw
Primary doc
SKILL.md

Package facts

Download mode
Yavira redirect
Package format
ZIP package
Source platform
Tencent SkillHub
What's included
SKILL.md, LICENSE.txt

Validation

  • Use the Yavira download entry.
  • Review SKILL.md after the package is downloaded.
  • Confirm the extracted package contains the expected setup assets.

Install with your agent

Agent handoff

Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.

  1. Download the package from Yavira.
  2. Extract it into a folder your agent can access.
  3. Paste one of the prompts below and point your agent at the extracted folder.
New install

I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.

Upgrade existing

I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.

Trust & source

Release facts

Source
Tencent SkillHub
Verification
Indexed source record
Version
1.0.2

Documentation

ClawHub primary doc Primary doc: SKILL.md 30 sections Open source page

Google Classroom

Access the Google Classroom API with managed OAuth authentication. Manage courses, coursework, students, teachers, announcements, and submissions.

Quick Start

# List all courses python3 <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-classroom/v1/courses') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF

Base URL

https://gateway.maton.ai/google-classroom/{api-path} The Google Classroom API uses the path pattern: https://gateway.maton.ai/google-classroom/v1/{resource}

Authentication

All requests require the Maton API key in the Authorization header: Authorization: Bearer $MATON_API_KEY Environment Variable: Set your API key as MATON_API_KEY: export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

Sign in or create an account at maton.ai Go to maton.ai/settings Copy your API key

Connection Management

Manage your Google Classroom OAuth connections at https://ctrl.maton.ai.

List Connections

python3 <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=google-classroom&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF

Create Connection

python3 <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'google-classroom'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF

Get Connection

python3 <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "connection": { "connection_id": "8efa1361-0e86-40b1-a63b-53a5051f8ac6", "status": "ACTIVE", "creation_time": "2026-02-14T00:00:00.000000Z", "last_updated_time": "2026-02-14T00:00:00.000000Z", "url": "https://connect.maton.ai/?session_token=...", "app": "google-classroom", "metadata": {} } } Open the returned url in a browser to complete OAuth authorization.

Delete Connection

python3 <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF

Specifying Connection

If you have multiple Google Classroom connections, specify which one to use with the Maton-Connection header: python3 <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-classroom/v1/courses') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '8efa1361-0e86-40b1-a63b-53a5051f8ac6') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF If omitted, the gateway uses the default (oldest) active connection.

Courses

List Courses GET /v1/courses GET /v1/courses?courseStates=ACTIVE GET /v1/courses?teacherId=me GET /v1/courses?studentId=me GET /v1/courses?pageSize=10 Query Parameters: courseStates - Filter by state: ACTIVE, ARCHIVED, PROVISIONED, DECLINED, SUSPENDED teacherId - Filter by teacher ID (use me for current user) studentId - Filter by student ID (use me for current user) pageSize - Number of results per page (max 100) pageToken - Token for next page Response: { "courses": [ { "id": "825635865485", "name": "Introduction to Programming", "section": "Section A", "descriptionHeading": "CS 101", "description": "Learn the basics of programming", "ownerId": "102753038276005039640", "creationTime": "2026-02-14T01:53:58.991Z", "updateTime": "2026-02-14T01:53:58.991Z", "enrollmentCode": "3qsua37m", "courseState": "ACTIVE", "alternateLink": "https://classroom.google.com/c/ODI1NjM1ODY1NDg1", "guardiansEnabled": false } ], "nextPageToken": "..." } Get Course GET /v1/courses/{courseId} Create Course POST /v1/courses Content-Type: application/json { "name": "Course Name", "section": "Section A", "descriptionHeading": "Course Title", "description": "Course description", "ownerId": "me" } Response: { "id": "825637533405", "name": "Course Name", "section": "Section A", "ownerId": "102753038276005039640", "courseState": "PROVISIONED", "enrollmentCode": "abc123" } Update Course PATCH /v1/courses/{courseId}?updateMask=name,description Content-Type: application/json { "name": "Updated Course Name", "description": "Updated description" } Note: Use updateMask query parameter to specify which fields to update. Delete Course DELETE /v1/courses/{courseId} Note: Courses must be archived before deletion. To archive, update the course with courseState: "ARCHIVED".

Course Work (Assignments)

List Course Work GET /v1/courses/{courseId}/courseWork GET /v1/courses/{courseId}/courseWork?courseWorkStates=PUBLISHED GET /v1/courses/{courseId}/courseWork?orderBy=dueDate Query Parameters: courseWorkStates - Filter by state: PUBLISHED, DRAFT, DELETED orderBy - Sort by: dueDate, updateTime pageSize - Number of results per page pageToken - Token for next page Get Course Work GET /v1/courses/{courseId}/courseWork/{courseWorkId} Create Course Work POST /v1/courses/{courseId}/courseWork Content-Type: application/json { "title": "Assignment Title", "description": "Assignment description", "workType": "ASSIGNMENT", "state": "PUBLISHED", "maxPoints": 100, "dueDate": { "year": 2026, "month": 3, "day": 15 }, "dueTime": { "hours": 23, "minutes": 59 } } Work Types: ASSIGNMENT - Regular assignment SHORT_ANSWER_QUESTION - Short answer question MULTIPLE_CHOICE_QUESTION - Multiple choice question States: DRAFT - Not visible to students PUBLISHED - Visible to students Update Course Work PATCH /v1/courses/{courseId}/courseWork/{courseWorkId}?updateMask=title,description Content-Type: application/json { "title": "Updated Title", "description": "Updated description" } Delete Course Work DELETE /v1/courses/{courseId}/courseWork/{courseWorkId}

Student Submissions

List Student Submissions GET /v1/courses/{courseId}/courseWork/{courseWorkId}/studentSubmissions GET /v1/courses/{courseId}/courseWork/{courseWorkId}/studentSubmissions?states=TURNED_IN Query Parameters: states - Filter by state: NEW, CREATED, TURNED_IN, RETURNED, RECLAIMED_BY_STUDENT userId - Filter by student ID pageSize - Number of results per page pageToken - Token for next page Note: Course work must be in PUBLISHED state to list submissions. Response: { "studentSubmissions": [ { "courseId": "825635865485", "courseWorkId": "825637404958", "id": "Cg4I8ufNwwYQ7tSZgYIB", "userId": "102753038276005039640", "creationTime": "2026-02-14T02:30:00.000Z", "state": "NEW", "alternateLink": "https://classroom.google.com/..." } ] } Get Student Submission GET /v1/courses/{courseId}/courseWork/{courseWorkId}/studentSubmissions/{submissionId} Grade Submission PATCH /v1/courses/{courseId}/courseWork/{courseWorkId}/studentSubmissions/{submissionId}?updateMask=assignedGrade,draftGrade Content-Type: application/json { "assignedGrade": 95, "draftGrade": 95 } Return Submission POST /v1/courses/{courseId}/courseWork/{courseWorkId}/studentSubmissions/{submissionId}:return Content-Type: application/json {}

Teachers

List Teachers GET /v1/courses/{courseId}/teachers Response: { "teachers": [ { "courseId": "825635865485", "userId": "102753038276005039640", "profile": { "id": "102753038276005039640", "name": { "givenName": "John", "familyName": "Doe", "fullName": "John Doe" }, "emailAddress": "john.doe@example.com" } } ] } Get Teacher GET /v1/courses/{courseId}/teachers/{userId} Add Teacher POST /v1/courses/{courseId}/teachers Content-Type: application/json { "userId": "teacher@example.com" } Remove Teacher DELETE /v1/courses/{courseId}/teachers/{userId}

Students

List Students GET /v1/courses/{courseId}/students Get Student GET /v1/courses/{courseId}/students/{userId} Add Student POST /v1/courses/{courseId}/students Content-Type: application/json { "userId": "student@example.com" } Remove Student DELETE /v1/courses/{courseId}/students/{userId}

Announcements

List Announcements GET /v1/courses/{courseId}/announcements GET /v1/courses/{courseId}/announcements?announcementStates=PUBLISHED Get Announcement GET /v1/courses/{courseId}/announcements/{announcementId} Create Announcement POST /v1/courses/{courseId}/announcements Content-Type: application/json { "text": "Announcement text content", "state": "PUBLISHED" } States: DRAFT - Not visible to students PUBLISHED - Visible to students Update Announcement PATCH /v1/courses/{courseId}/announcements/{announcementId}?updateMask=text Content-Type: application/json { "text": "Updated announcement text" } Delete Announcement DELETE /v1/courses/{courseId}/announcements/{announcementId}

Topics

List Topics GET /v1/courses/{courseId}/topics Get Topic GET /v1/courses/{courseId}/topics/{topicId} Create Topic POST /v1/courses/{courseId}/topics Content-Type: application/json { "name": "Topic Name" } Update Topic PATCH /v1/courses/{courseId}/topics/{topicId}?updateMask=name Content-Type: application/json { "name": "Updated Topic Name" } Delete Topic DELETE /v1/courses/{courseId}/topics/{topicId}

Course Work Materials

List Course Work Materials GET /v1/courses/{courseId}/courseWorkMaterials Get Course Work Material GET /v1/courses/{courseId}/courseWorkMaterials/{courseWorkMaterialId}

Invitations

List Invitations GET /v1/invitations?courseId={courseId} GET /v1/invitations?userId=me Note: Either courseId or userId is required. Create Invitation POST /v1/invitations Content-Type: application/json { "courseId": "825635865485", "userId": "user@example.com", "role": "STUDENT" } Roles: STUDENT TEACHER OWNER Accept Invitation POST /v1/invitations/{invitationId}:accept Delete Invitation DELETE /v1/invitations/{invitationId}

User Profiles

Get Current User GET /v1/userProfiles/me Response: { "id": "102753038276005039640", "name": { "givenName": "John", "familyName": "Doe", "fullName": "John Doe" }, "emailAddress": "john.doe@example.com", "permissions": [ { "permission": "CREATE_COURSE" } ], "verifiedTeacher": false } Get User Profile GET /v1/userProfiles/{userId}

Course Aliases

List Course Aliases GET /v1/courses/{courseId}/aliases

Pagination

The Google Classroom API uses token-based pagination. Responses include a nextPageToken when more results are available. GET /v1/courses?pageSize=10 Response: { "courses": [...], "nextPageToken": "Ci8KLRIrEikKDmIMCLK8v8wGEIDQrsYBCgsI..." } To get the next page: GET /v1/courses?pageSize=10&pageToken=Ci8KLRIrEikKDmIMCLK8v8wGEIDQrsYBCgsI...

JavaScript

// List all courses const response = await fetch( 'https://gateway.maton.ai/google-classroom/v1/courses', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); console.log(data.courses);

Python

import os import requests # List all courses response = requests.get( 'https://gateway.maton.ai/google-classroom/v1/courses', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json() print(data['courses'])

Create Assignment Example

import os import requests course_id = "825635865485" # Create an assignment assignment = { "title": "Week 1 Homework", "description": "Complete exercises 1-10", "workType": "ASSIGNMENT", "state": "PUBLISHED", "maxPoints": 100, "dueDate": {"year": 2026, "month": 3, "day": 15}, "dueTime": {"hours": 23, "minutes": 59} } response = requests.post( f'https://gateway.maton.ai/google-classroom/v1/courses/{course_id}/courseWork', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }, json=assignment ) print(response.json())

Notes

updateMask Required: PATCH requests require the updateMask query parameter specifying which fields to update Course Deletion: Courses must be archived (courseState: "ARCHIVED") before they can be deleted Student Submissions: Course work must be in PUBLISHED state to access student submissions User IDs: Use me to refer to the current authenticated user Timestamps: Dates use {year, month, day} format; times use {hours, minutes} format IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments

Error Handling

StatusMeaning400Bad request, invalid argument, or precondition failed401Invalid API key or expired token403Permission denied404Resource not found409Conflict (e.g., user already enrolled)429Rate limited4xx/5xxPassthrough error from Google Classroom API

Common Errors

Precondition check failed (400) When deleting a course: Course must be archived first When listing submissions: Course work must be published Permission denied (403) User doesn't have required role (teacher/owner) for the operation Attempting to access guardian information without proper scopes

Resources

Google Classroom API Documentation Course Resource Reference CourseWork Resource Reference StudentSubmissions Reference Maton Community Maton Support

Category context

Code helpers, APIs, CLIs, browser automation, testing, and developer operations.

Source: Tencent SkillHub

Largest current source with strong distribution and engagement signals.

Package contents

Included in package
1 Docs1 Files
  • SKILL.md Primary doc
  • LICENSE.txt Files