Automatically sync your Canvas LMS assignments to Todoist tasks. This tool:
- Fetches assignments from your Canvas calendar feed (ICS format)
- Creates Todoist tasks with proper due dates
- Organizes assignments with labels by course name
- Sets priority based on how soon assignments are due
- Adds reminders 1 day before each due date
- Auto-completes tasks when you submit assignments in Canvas
- Runs automatically every 5 minutes via GitHub Actions
- Tracks synced assignments to prevent duplicates
git clone https://github.com/YOUR_USERNAME/canvas-todoist-sync.git
cd canvas-todoist-syncOr click "Use this template" / "Fork" on GitHub.
- Log into Canvas
- Go to Calendar (left sidebar)
- Click Calendar Feed (right side of the page)
- Copy the URL - it looks like:
https://your-school.instructure.com/feeds/calendars/user_XXXXXX.ics
- Go to Todoist Integrations Settings
- Scroll down to API token
- Copy the token
-
Go to your repository on GitHub
-
Click Settings -> Secrets and variables -> Actions
-
Click New repository secret and add:
Name Value TODOIST_API_TOKENYour Todoist API token CANVAS_ICS_URLYour Canvas calendar feed URL
- Go to the Actions tab in your repository
- Click I understand my workflows, go ahead and enable them
- The sync will now run automatically every 5 minutes
- Go to Actions tab
- Select Canvas to Todoist Sync
- Click Run workflow -> Run workflow
- Check your Todoist for new tasks!
- All assignments go into a "Canvas Assignments" project in Todoist
- Each course gets its own label (e.g.,
CHEM_350,MATH_241) - You can filter by label to see assignments for specific courses
Tasks are automatically prioritized based on due date:
| Due Date | Todoist Priority |
|---|---|
| Within 1 day | P1 (Urgent/Red) |
| Within 3 days | P2 (High/Orange) |
| Within 7 days | P3 (Medium/Yellow) |
| Later | P4 (Normal) |
The sync tracks assignments by their unique Canvas ID to prevent duplicates:
- New assignments are created as tasks
- Changed assignments (title, due date, description) are updated
- Already-synced, unchanged assignments are skipped
- Past assignments are ignored
Every task automatically gets a Todoist reminder 1 day before the due date. This ensures you get notified before assignments are due.
- Reminders are only added if the reminder time is in the future
- Configurable via
REMINDER_DAYS_BEFOREenvironment variable
When you submit an assignment in Canvas, it disappears from your calendar feed. The sync detects this and automatically marks the corresponding Todoist task as complete.
How it works:
- Assignment is synced to Todoist
- You submit the assignment in Canvas
- Assignment disappears from Canvas calendar feed
- Next sync detects it's missing (but due date is still future)
- Todoist task is automatically completed
# Clone the repository
git clone https://github.com/YOUR_USERNAME/canvas-todoist-sync.git
cd canvas-todoist-sync
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Copy and edit environment file
cp .env.example .env
# Edit .env with your actual values# With .env file
source venv/bin/activate
export $(cat .env | xargs)
python sync.py
# Or set environment variables directly
TODOIST_API_TOKEN="your_token" CANVAS_ICS_URL="your_url" python sync.pySet these as environment variables or GitHub secrets:
| Variable | Required | Default | Description |
|---|---|---|---|
TODOIST_API_TOKEN |
Yes | - | Your Todoist API token |
CANVAS_ICS_URL |
Yes | - | Your Canvas calendar feed URL |
TODOIST_PROJECT_NAME |
No | Canvas Assignments |
Name of Todoist project |
REMINDER_DAYS_BEFORE |
No | 1 |
Days before due date to set reminder (0 to disable) |
STATE_FILE |
No | sync_state.json |
Path to state tracking file |
Edit .github/workflows/sync.yml and modify the cron schedule:
schedule:
# Every 30 minutes
- cron: '*/30 * * * *'
# Every 2 hours
- cron: '0 */2 * * *'
# Every 6 hours
- cron: '0 */6 * * *'
# Once daily at 8 AM UTC
- cron: '0 8 * * *'Edit sync.py and modify the PRIORITY_THRESHOLDS dictionary:
PRIORITY_THRESHOLDS = {
1: 4, # Due within 1 day -> urgent
3: 3, # Due within 3 days -> high
7: 2, # Due within 7 days -> medium
}- Check that your secrets are correctly set in GitHub
- Look at the Actions tab for error logs
- Verify your Canvas calendar URL works by opening it in a browser
- Make sure there are future assignments in Canvas
The sync state is cached between runs. If you see duplicates:
- Go to Actions -> Clear all caches
- Manually delete duplicate tasks in Todoist
- Run the workflow again
Course names are extracted from Canvas event titles. If they look wrong:
- Check how assignments appear in your Canvas calendar
- You may need to adjust the
parse_course_name()function insync.py
- Never commit your API tokens - always use GitHub Secrets or environment variables
- Your Canvas ICS URL contains a private token - keep it confidential
- The
.gitignorefile prevents accidental commits of.envfiles
MIT License - feel free to modify and share!