Custom Portal Submission
When there's no clean API, Scuba drives the browser. Puppeteer handles Moodle, Canvas, Blackboard, GitHub Classroom, and whatever bespoke thing your uni wrote.
Officially supported
- Moodle (3.x and 4.x)
- Canvas
- Blackboard Learn
- GitHub Classroom (via API + browser fallback for oddities)
Unrecognized portals still work — Scuba falls back to a scripted login + upload flow you can customize.
Recipes
Each portal is defined by a recipe — a JSON file that tells Puppeteer how to log in, navigate, and submit. Built-in recipes live in ~/.studentsync/recipes/.
~/.studentsync/recipes/moodle.json
{ "name": "moodle", "login": { "url": "{{base}}/login/index.php", "username": "#username", "password": "#password", "submit": "#loginbtn" }, "assignment": { "url": "{{base}}/mod/assign/view.php?id={{id}}", "addSubmission": "input[name='addsubmit']", "fileInput": "input[type='file']", "save": "input[name='submit']", "confirm": "input[name='submitbutton']" }, "selectors": { "status": ".submissionstatussubmitted" }}Submit from Telegram
bash
you → /submit custom moodlebot → portal URL?you → https://lms.myuniversity.edubot → assignment id?you → 48212bot → uploading assignment.pdf → moodlebot → ✓ submitted — status: Submitted for gradingCredentials
Portal credentials are encrypted at rest with a machine-local key and never sent to any LLM. Manage them with:
bash
studentsync portals add # interactive wizardstudentsync portals list # see which portals have saved credsstudentsync portals remove # forget credentialsDry-run it first
Pass
--dry to /submit and Scuba will walk the flow in a visible browser window without clicking the final Submit. Great for debugging new recipes.Bring your own recipe
Drop a JSON file into ~/.studentsync/recipes/ and reference its name in /submit custom <name>. PRs for school-specific recipes are very welcome.