Youssef Abdallah

Builds/003

Studentify

Deployed

An AI study scheduler that reads your Canvas and texts you a plan

Logged
2025.04
Timeframe
2025
Role
Project lead — 3-person team
Stack
PythonGemini 1.5 ProCanvas APITelegram Bot APITypeScriptUbuntu VPS
Source
FIG 01 — The end product — a study plan that knows your actual deadlines, delivered where you already are

Why I built it

Every generic study planner has the same flaw: you have to tell it everything. Your courses, your deadlines, how you’re doing, what’s hard for you. Nobody maintains that for more than a week — the planner becomes another chore.

But all of that data already exists, sitting in Canvas: course schedules, assignment deadlines, submission history, grades, past exam performance. Studentify’s premise was simple — stop asking students for data their university already has. Read Canvas, reason about it with an LLM, and deliver a plan where students actually look: their messages.

I led a 3-person team to design, build, and deploy it end-to-end.

The stack

Hardware builds get a bill of materials; software builds deserve one too.

Bill of materials

ItemQtyNotes
Canvas API token1 per userToken-based login — the backend only sees what the student authorizes.
Gemini 1.5 Pro API1The planning brain, orchestrated with OpenClaw.
Telegram bot1Delivery channel: daily plans, refinement, study Q&A.
Hostinger Ubuntu VPS1Where the whole stack lives.
FIG 02 — The pipeline — Canvas in, reasoning in the middle, Telegram out

Reading Canvas the hard way

The backend is Python, and its first job is authentication: token-based Canvas login, so each student connects with their own access token and the backend only touches what they’ve authorized.

From there it pulls the full academic picture:

  • Course schedules — including the gaps between classes, which turn out to be the most valuable study windows students waste
  • Assignment deadlines and submission history — what’s due, and whether you’re the type who submits early or at 11:58 PM
  • Grades and past exam performance — the signal for which subjects actually need the hours

The interesting engineering was normalization: every course structures its Canvas presence differently, and the pipeline has to turn that mess into one consistent workload model before any AI sees it.

Making Gemini plan like a human

Raw LLM scheduling is bad. Ask a model to “make a study plan” and you get a generic, evenly-spread grid that ignores reality. The work was in the orchestration — we integrated Gemini 1.5 Pro with OpenClaw and fed it a structured picture of the student:

  • Grade risk — courses where the current grade is drifting toward trouble get weighted hours
  • Weak subjects — inferred from exam history, not self-reporting
  • Deadline urgency — a real ranking, not just “sorted by due date”
  • Preferred study windows — plans land in the hours the student will actually use, including those between-class gaps
FIG 03 — A generated plan — hours flow toward grade risk and deadline pressure, not spread evenly like butter

Delivery via Telegram

A plan nobody sees is a plan nobody follows, so delivery went through a Telegram chatbot rather than another dashboard tab:

  • Daily schedule delivery — the day’s plan arrives as a message, every morning
  • Conversational refinement — “move my physics block to tonight” just works; the bot regenerates around the constraint
  • Study Q&A — the same pipeline answers questions with the student’s actual course context behind it

Meeting students inside an app they already check twenty times a day beat every engagement idea we had for a web UI.

Shipping it

The whole stack runs on a Hostinger Ubuntu VPS — Python backend, bot process, and scheduling jobs deployed and kept alive as services. This was the project where “works on my machine” became “survives a server reboot at 3 AM”: process supervision, logs you can actually read, and API failure handling for three external services that each have opinions about rate limits.

We validated it end-to-end with 10+ real users across 3+ live APIs — real Canvas accounts, real deadlines, real plans followed (or ignored, which is also data).

What I’d do differently

  • Schema-lock the LLM output from day one. We started with free-text plans and paid for it in parsing bugs. Structured output with validation should have been the first commit, not a refactor.
  • Build the feedback loop. We know when plans are delivered; we only anecdotally know when they’re followed. Lightweight completion tracking would turn the scheduler into something that learns.
  • Cache Canvas aggressively. Re-pulling course data on every planning cycle was simple but slow and rate-limit-hungry. A sync layer with change detection is the obvious v2 move.