Technical Manual: Seiue Attendance Automation
Document Purpose
This document details the technical implementation of an automated attendance script for the Seiue teaching management platform. It covers two major versions: the initial Selenium-based implementation (V1) and the current, stable API-based implementation (V2). The focus is on the technical details of the final API version, providing a clear guide for maintenance, updates, and future deployment on a Virtual Private Server (VPS) for multi-user support.
✅ Mandatory Fixes & Required Optimizations
These items are not optional. They prevent runtime failures or materially improve reliability and safety.
-
Correct Retry import (prevents import errors across environments)
UseRetry
fromurllib3.util.retry
instead ofrequests.adapters
. -
macOS network check
ping -t
is TTL on macOS (not timeout). Use-W
(milliseconds) or a curl probe. -
BSD
date
lacks%N
Millisecond formatting via%N
fails on BSDdate
. Fallback togdate
(coreutils) or Python for timestamps. -
launchd
PATH must include Homebrew prefix
Add/opt/homebrew/bin
so the venv and coreutils are resolvable on Apple Silicon. -
Stable result tokens from Python
EmitSUMMARY:<YYYY-MM-DD>:status=<...>
once per date; the shell reads only these lines (no brittle greps). -
401 auto-refresh
When an API call returns 401, re-authenticate once and retry the request to survive token expiry. -
Chunked submits
Splitattendance_records
into chunks (e.g., 600) to avoid API 413/422 on large classes × sessions. -
Safety: avoid future classes by default
Do not submit attendance for sessions in the future unless explicitly enabled (ALLOW_FUTURE_SUBMIT=false
). -
Post-submit verification
Re-fetch the day’s lessons and confirm no pending records remain for the processed set. -
Safer Telegram notifications
POST JSON; avoid brittle URL-encoding with query strings. (Plain text is fine; you can add Markdown later with proper escaping.) -
Shell robustness
Useset -Eeuo pipefail
and a simple file lock to prevent overlapping runs.
Chapter 1: Version 1.0 - UI Automation (Legacy)
1.1 Overview
The initial approach (attendance_script_robust.py
) utilized the Selenium WebDriver library to automate browser interactions. It successfully simulated a user logging in, navigating to the course schedule, and clicking the necessary buttons to submit attendance.
1.2 Methodology
- Technology Stack: Python, Selenium, webdriver-manager.
- Authentication: Simulated user input into the login form fields (
#usin
,#password
) and programmatically clicked the submit button. - Core Logic:
- Initialize a headless Chrome browser instance.
- Navigate to the login URL.
- Find and fill username/password fields.
- Click the login button.
- Handle an optional “Skip phone binding” screen.
- Navigate to the main dashboard (
chalk-c3.seiue.com
). - Locate the calendar/schedule container (
#export-class
). - Find all “Record Attendance” (
录入考勤
) buttons within course card elements. - Iterate through each button, click it to open the attendance modal.
- Within the modal, click “Batch Set” (
批量设置
), then “All Present” (全部出勤
). - Click the “Submit Attendance” (
提交考勤
) button. - Wait for the modal to disappear as confirmation.
- Automation: The script was executed by a shell script (
run_attendance.sh
) which was triggered by a macOSlaunchd
agent (com.ylsuen.seiue.attendance.plist
) on a schedule.
1.3 Limitations
This method proved to be unstable due to its dependency on the frontend’s Document Object Model (DOM). The platform’s dynamically generated CSS class names for buttons and containers changed frequently, causing the script to fail. This required constant maintenance and made the solution unreliable. This led to the development of Version 2.0.
Chapter 2: Version 2.0 - API Interaction (Current)
Version 2.0 abandons UI automation in favor of direct communication with the platform’s backend API. This approach is significantly faster, more stable, and more resource-efficient.
2.1 Key API Endpoints & Data
The following API endpoints and parameters are critical for the script’s operation. They were identified by analyzing browser network traffic during a manual attendance submission process.
Authentication Endpoints:
-
Login Form Submission:
- URL:
https://passport.seiue.com/login?school_id=3
- Method:
POST
- Content-Type:
application/x-www-form-urlencoded
- Form Data:
email
: [Your Username]password
: [Your Password]
- Success Response:
302 Found
redirect to the/bindings
page, with session cookies set for thepassport.seiue.com
domain.
- URL:
-
Token Authorization:
- URL:
https://passport.seiue.com/authorize
- Method:
POST
- Content-Type:
application/x-www-form-urlencoded
- Form Data:
client_id
:GpxvnjhVKt56qTmnPWH1sA
(web app client; may change in future).response_type
:token
- Success Response:
201 Created
with a JSON body containing theaccess_token
andactive_reflection_id
.
- URL:
Data & Action Endpoints:
-
Get Calendar Events (Lessons):
- URL:
https://api.seiue.com/chalk/calendar/personals/{reflection_id}/events
- Method:
GET
- URL Parameters:
start_time
:YYYY-MM-DD HH:MM:SS
end_time
:YYYY-MM-DD HH:MM:SS
expand
:address,initiators
- Key Response Fields: A JSON array of event objects. For lessons (
type: "lesson"
), the crucial fields are:title
: Course name.start_time
: Lesson start time.subject.id
: The unique ID for the class group (biz_id
).custom.id
: The unique ID for the specific class session (attendance_time_id
).custom.attendance_status
:0
indicates pending attendance.
- URL:
-
Get Student List:
- URL:
https://api.seiue.com/scms/class/classes/{group_id}/group-members
- Method:
GET
- URL Parameters:
expand
:reflection
member_type
:student
- Key Response Fields: A JSON array of student objects. The crucial field is:
reflection.id
: The student’s unique ID (owner_id
for submission).
- URL:
-
Submit Attendance Records:
- URL:
https://api.seiue.com/sams/attendance/class/{group_id}/records/sync
- Method:
PUT
- Content-Type:
application/json
- Request Payload (JSON Body):
1 2 3 4 5 6 7 8 9 10 11
{ "abnormal_notice_roles": [], "attendance_records": [ { "tag": "正常", "attendance_time_id": 12345678, "owner_id": 987654, "source": "web" } ] }
- URL:
Terminology quick map:
subject.id
→ class group ID;custom.id
→ attendance_time_id (this session);reflection.id
→ person ID (student).
2.2 Final Code Implementation (Updated)
The implementation consists of three files: the core Python script, a shell wrapper for orchestration, and a launchd
plist for scheduling.
File 1: APIFinal.py
(Python Core Logic)
|
|
File 2: run_attendance.sh
(Orchestration Script, Updated)
|
|
File 3: com.ylsuen.seiue.attendance.api.plist
(Scheduler, Updated PATH)
|
|
Chapter 3: Deployment on a VPS for Multi-User Support
Transitioning this single-user script to a multi-user service on a VPS (e.g., a Linux server) requires architectural changes.
3.1 Core Concepts
- Centralized Scheduler: Instead of each user running their own
launchd
agent, a singlesystemd timer
(recommended) orcron
job on the VPS will trigger the master script. - User Database: A simple database (like SQLite) or a JSON file is needed to store user credentials (
username
, encryptedpassword
) and their desired attendance schedule. - State Management: Track the last successful run for each user to avoid duplicates and support retries with backoff.
- Web Interface (Optional): A simple web front-end (Flask/Django) for user self-service.
3.2 VPS Implementation Steps
-
Server Setup
- Provision a Linux VPS (e.g., Ubuntu 22.04).
- Install Python 3, pip, and create a virtual environment.
- Install required libraries:
1
pip install requests urllib3 pytz cryptography
-
User Data Storage
- Example
users.json
:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[ { "username": "user1_username", "encrypted_password": "encrypted_password_string_1", "telegram_chat_id": "user1_chat_id", "timezone": "Asia/Shanghai", "enabled": true }, { "username": "user2_username", "encrypted_password": "encrypted_password_string_2", "telegram_chat_id": "user2_chat_id", "timezone": "America/Los_Angeles", "enabled": true } ]
- Encrypt passwords with
cryptography.Fernet
; keep the key in an env file (not in Git).
- Example
-
Refactor the Python Script
- Multi-user runner should:
a. Load & decrypt user data from
users.json
b. Iterate enabled users
c. Compute each user’s yesterday/today/tomorrow in their timezone
d. InstantiateSeiueAPIClient
and run the three dates
e. Send per-user Telegram status
- Multi-user runner should:
a. Load & decrypt user data from
-
Scheduling
- systemd timer (recommended):
OnCalendar=*-*-* 00:05:00 UTC
(08:05 Beijing).
Or usecron
:5 0 * * * /path/to/venv/bin/python3 /path/to/APIFinal.py >> /path/to/cron.log 2>&1
- systemd timer (recommended):
Environment & Dependencies
Create a requirements.txt
and pin versions you’ve tested:
requests>=2.32
urllib3>=2.2
pytz>=2024.1
cryptography>=42.0
Mac (Homebrew Python) quickstart:
|
|
Security & Compliance Notes
- Default
abnormal_notice_roles
to[]
(no guardian pings) unless explicitly intended. - Store secrets outside the repo; rotate periodically.
- Ensure usage complies with platform ToS and local policies.
- Keep logs; avoid exposing PII in notifications.