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 moodle
bot → portal URL?
you → https://lms.myuniversity.edu
bot → assignment id?
you → 48212
bot → uploading assignment.pdf → moodle
bot → ✓ submitted — status: Submitted for grading

Credentials

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 wizard
studentsync portals list # see which portals have saved creds
studentsync portals remove # forget credentials

Dry-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.