A powerful Node.js package to scrape Moodle LMS data including assignments, grades, files, and Zybook integrations.
- π Assignments: Retrieve assignment details, due dates, and submission status
- π Grades: Extract gradebook data and feedback
- π Files: List and download course files and resources
- π Zybook Integration: Access Zybook activities and progress
- π Secure Authentication: Handle login with email and password
- π‘οΈ 2FA Support: Automatic detection and handling of Two-Factor Authentication
- β‘ Fast & Reliable: Built with Puppeteer for robust web scraping
- π¦ Easy to Use: Simple API with TypeScript support
npm install moodletracerconst { scrapeMoodle } = require('moodletracer');
async function getMoodleData() {
const credentials = {
email: 'your-email@example.com',
password: 'your-password',
classUrl: 'https://your-moodle-site.com/course/view.php?id=123'
};
try {
const data = await scrapeMoodle(credentials);
console.log('Assignments:', data.assignments);
console.log('Grades:', data.grades);
console.log('Files:', data.files);
console.log('Zybook Integrations:', data.zybookIntegrations);
} catch (error) {
console.error('Error:', error.message);
}
}
getMoodleData();const { MoodleScraper } = require('moodletracer');
async function advancedScraping() {
const scraper = new MoodleScraper({
email: 'your-email@example.com',
password: 'your-password',
classUrl: 'https://your-moodle-site.com/course/view.php?id=123'
}, {
headless: true, // Run in background
timeout: 60000, // 60 second timeout
waitForElements: true
});
try {
await scraper.initialize();
await scraper.login();
await scraper.navigateToClass();
// Scrape specific data types
const assignments = await scraper.scrapeAssignments();
const grades = await scraper.scrapeGrades();
return { assignments, grades };
} finally {
await scraper.close();
}
}If your Moodle instance uses 2FA, the scraper can handle it automatically:
const scraper = new MoodleScraper(credentials, {
headless: false, // Show browser for 2FA completion
timeout: 60000 // Extended timeout for manual intervention
});
await scraper.initialize();
await scraper.login(); // Will detect and wait for 2FA if needed2FA Methods Supported:
- Manual completion: Browser window stays open for you to complete 2FA
- Session persistence: Save login state to avoid repeated 2FA
- Multiple 2FA types: SMS, authenticator apps, email verification
See examples/2fa-example.js and docs/2fa-handling-guide.md for detailed 2FA handling strategies.
For production deployments, this package includes enterprise-grade containerization using Red Hat technologies:
# Build with Red Hat Universal Base Image (UBI)
npm run container:build
# Set environment variables
export MOODLE_EMAIL="your-email@university.edu"
export MOODLE_PASSWORD="your-password"
export MOODLE_CLASS_URL="https://moodle.university.edu/course/view.php?id=12345"
# Run containerized scraping
npm run container:run- π Red Hat UBI: Built on enterprise-grade Universal Base Images
- π‘οΈ Podman Ready: Rootless, daemonless container execution
- β‘ Security First: No-new-privileges, capability dropping, read-only filesystem
- π Production Ready: Resource limits, health checks, SELinux support
npm run container:build # Build container with UBI
npm run container:run # Run scraping in container
npm run container:debug # Interactive debugging container
npm run container:info # Show container information
npm run container:cleanup # Clean up containersSee docs/redhat-integration.md and examples/podman-container-example.js for comprehensive container usage.
Quick function to scrape all Moodle data.
Parameters:
credentials: Object withemail,password, andclassUrloptions: Optional scraper configuration
Returns: Promise resolving to ScrapedData object
new MoodleScraper(credentials, options?)initialize(): Initialize browser instancelogin(): Authenticate with MoodlenavigateToClass(): Navigate to the specified classscrapeAssignments(): Get all assignmentsscrapeGrades(): Get grade informationscrapeFiles(): Get course filesscrapeZybookIntegrations(): Get Zybook activitiesscrapeAll(): Get all data at onceclose(): Close browser instance
{
id: string;
title: string;
description: string;
dueDate: Date | null;
submissionStatus: 'submitted' | 'not_submitted' | 'late';
maxGrade: number;
currentGrade: number | null;
url: string;
}{
itemName: string;
grade: string;
maxGrade: string;
percentage: number | null;
feedback: string | null;
dateModified: Date | null;
}{
name: string;
url: string;
size: string;
type: string;
downloadUrl: string;
}{
title: string;
url: string;
dueDate: Date | null;
completionStatus: string;
progress: number | null;
}{
headless: true, // Run browser in background (default: true)
timeout: 30000, // Request timeout in ms (default: 30000)
waitForElements: true // Wait for page elements to load (default: true)
}- Never commit credentials: Use environment variables or secure config files
- Rate limiting: Be respectful of Moodle server resources
- Terms of service: Ensure compliance with your institution's policies
- Node.js 16.0.0 or higher
- Chrome/Chromium browser (installed automatically with Puppeteer)
-
Login Failed:
- Verify credentials are correct
- Check if Moodle site uses SSO or 2FA
- Ensure class URL is accessible
-
Two-Factor Authentication:
- Set
headless: falseto see 2FA prompts - Use session persistence to avoid repeated 2FA
- See 2FA handling guide for detailed solutions
- Set
-
Elements Not Found:
- Different Moodle versions may have different HTML structures
- Try increasing timeout values
- Set
headless: falseto debug visually
-
Memory Issues:
- Always call
scraper.close()when done - Use
headless: truefor production
- Always call
MIT License - see LICENSE file for details
Contributions welcome! Please read our contributing guidelines and submit pull requests.
This tool is for educational purposes.