Automated course availability monitor for UConn Student Admin. Checks the student admin Shopping Cart to determine whether classes are open.
Two-Phase Design:
-
Phase 1 (agent.py): Selenium-based authentication
- Handles CAS login
- Processes Duo MFA
- Captures session cookies, headers, and state tokens
- Only runs when session expires or is missing
-
Phase 2 (worker.py): HTTP-based polling
- Uses saved session data
- Fetches and parses Shopping Cart
- Detects session expiration
- Automatically triggers Selenium refresh
- Sends Discord notifications
- Python 3.8+
- Microsoft Edge browser
- Edge WebDriver (must be in PATH)
- Discord webhook URLs
-
Clone or download this repository
-
Install dependencies
pip install -r requirements.txt
- Create a Discord server and configure webhooks
Create webhooks
- Go to Server Settings → Integrations → Webhooks
- Click New Webhook
- Select the text channel you want the webhook to post to
- Copy the Webhook URL and paste to
creds.json - Repeat for each channel (you need at least 3 channels/webhooks total)
- Adjust credentials file at
creds/creds.json:
{
"username": "your_netid",
"password": "your_password",
"duo_webhook_url": "https://discord.com/api/webhooks/...",
"course_webhook_url": "https://discord.com/api/webhooks/...",
"error_webhook_url": "https://discord.com/api/webhooks/..."
}Run the worker directly:
python3 worker.pyThe worker will:
- Load or refresh session data
- Fetch Shopping Cart page
- Parse course availability
- Send Discord notification
- Exit
Add to crontab for periodic monitoring:
crontab -eExample (check every 15 minutes):
*/15 * * * * /usr/bin/python3 /full/path/to/worker.pyImportant: Only schedule worker.py in cron. Never schedule agent.py directly.
worker.pydetects missingsession.json- Calls
agent.pyto perform Selenium login - Duo verification code sent to Discord (duo_webhook_url)
- User approves Duo push notification
- Session data saved to
creds/session.json - Worker fetches and parses Shopping Cart
- Results sent to Discord (course_webhook_url)
- Worker loads existing session from
session.json - Fetches Shopping Cart via HTTP (no browser needed)
- Parses course data
- Sends Discord notification
When session expires:
- Worker detects CAS error message in response
- Automatically triggers Selenium refresh
- New Duo approval required
- Session data updated
- Worker continues polling
Two separate log files in logs/:
activities.txt
- INFO level only
- Normal workflow, successful fetches, etc.
errors.txt
- ERROR level only
- Selenium failures, HTTP errors, etc.
Both logs use 5MB rotation with 3 backup files
Ensure Edge WebDriver is installed and in PATH: For Linux
which msedgedriverFor Windows
where msedgedriver- Check system time accuracy
- Verify UConn hasn't changed authentication flow
- Check logs/errors.txt for details
- Verify Shopping Cart has courses added in PeopleSoft
- Check that course grid HTML structure hasn't changed
- Review logs/activities.txt for parsing details
- Verify webhook URLs are correct
- Check Discord server permissions
- Ensure webhook hasn't been deleted
- Verify Duo is enabled on your account
- Check duo_webhook_url is correct
- Ensure you approve push notification within timeout (30 seconds)
creds/creds.jsoncontains plaintext credentials (don't push creds.json onto GitHub)- Use file permissions to restrict access:
chmod 600 creds/creds.json
- Consider using environment variables instead of creds
- Element IDs in PeopleSoft are dynamic and may change
- Only Edge is officially supported
- Refactor code for clarity and optimization
- Add feature to switch/add classes when spots become open/available
- Add support for alternative browsers (Chrome, Firefox)
- Optional: Rewrite worker.py in compiled language for faster HTTP requests