Fetch, sync, and organize EdStem discussion threads for any course or institution. Use when checking for new EdStem posts, syncing course discussion forums, reviewing student/staff questions and answers, or when the user asks to check EdStem, review course discussions, or stay updated on class forums.
Fetch and organize EdStem discussion threads from any course or institution with automatic staff/student differentiation.
Fetch recent threads for any course:
cd /home/axel/.openclaw/workspace/skills/edstem/scripts
python3 fetch-edstem.py <course_id> [output_dir] [--course-name "Course Name"]
Examples:
# Fetch to default directory (./edstem-<course_id>)
python3 fetch-edstem.py 92041
# Fetch to specific directory
python3 fetch-edstem.py 92041 ./machine-learning
# Specify course name for clearer output
python3 fetch-edstem.py 92041 --course-name "Machine Learning"
# Combine directory and course name
python3 fetch-edstem.py 92041 ./ml-course --course-name "Machine Learning"
# Fetch more threads (default is 10)
python3 fetch-edstem.py 92041 --limit 25
To find your EdStem course ID:
https://edstem.org/us/courses/<course_id>/Alternatively, use the API to list your courses:
curl -H "Authorization: Bearer YOUR_TOKEN" https://us.edstem.org/api/user | jq '.courses[] | {id: .course.id, name: .course.name}'
For each course:
The skill uses a bearer token stored in the Python script. To use with your own account:
Authorization: Bearer ... tokenED_TOKEN in scripts/fetch-edstem.pyCurrent token location: Line 20 in scripts/fetch-edstem.py
If API calls fail (401 Unauthorized), your token likely expired and needs refresh.
Full-featured Python script with markdown formatting and staff/student differentiation.
Usage:
python3 scripts/fetch-edstem.py <course_id> [output_dir] [options]
Options:
output_dir - Where to save threads (default: ./edstem-<course_id>)--course-name NAME - Display name for the course--limit N - Number of threads to fetch (default: 10)Features:
Bash/curl version for raw JSON fetching without dependencies.
Usage:
bash scripts/fetch-edstem.sh <course_id> [output_dir]
Outputs:
python3 scripts/fetch-edstem.py 92041 ~/courses/ml-spring-2025
# Create a simple sync script
for course in "92041:machine-learning" "94832:advanced-rl"; do
IFS=':' read -r id name <<< "$course"
python3 scripts/fetch-edstem.py $id ~/courses/$name --course-name "$name"
done
After fetching, check the markdown files:
ls -lt ./edstem-92041/*.md | head
cat ./edstem-92041/thread-001.md
grep -r "gradient descent" ./edstem-92041/*.md
<output_dir>/
├── threads.json # Thread metadata
├── thread-001.md # Individual threads
├── thread-002.md
└── ...
Each markdown file contains:
# Fetch threads and analyze with your agent
python3 fetch-edstem.py 92041 ./course-data
# Then: "Summarize the most common questions in ./course-data/"
# Add to cron for daily sync
0 9 * * * cd /path/to/skills/edstem/scripts && python3 fetch-edstem.py 92041 ~/courses/ml
# Organize by semester and institution
python3 fetch-edstem.py 92041 ~/school/stanford/2025-spring/cs229
python3 fetch-edstem.py 94832 ~/school/mit/2025-spring/6.7920
401 Unauthorized: Token expired. Re-authenticate and update ED_TOKEN in the script.
Course not found: Verify the course ID and that your account has access.
Empty threads: Check that the course has discussion posts and you're enrolled.
Rate limiting: EdStem may rate-limit API requests. Add delays between fetches if needed.
This skill is open-source and institution-agnostic by design. Improvements welcome: