Complete step-by-step instructions for setting up WebUntis to Google Calendar sync.
- System Requirements
- Installation
- Google Calendar API Setup
- WebUntis Configuration
- First Sync
- Automation Setup
- Verification
- Linux/macOS/WSL
- Python 3.8 or higher
- Git
- Chrome or Chromium browser
- WebUntis account with valid credentials
- Google account with Calendar access
git clone https://github.com/YOUR_USERNAME/untis-calendar-sync.git
cd untis-calendar-syncpython3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install -r requirements.txtpython3 --version
pip list | grep google-api
pip list | grep selenium- Go to Google Cloud Console
- Click "Select a project" → "New Project"
- Name: "WebUntis Calendar Sync"
- Click "Create"
- In the project dashboard, go to "APIs & Services" → "Library"
- Search for "Google Calendar API"
- Click "Enable"
- Go to "APIs & Services" → "Credentials"
- Click "Create Credentials" → "OAuth 2.0 Client ID"
- If prompted, configure OAuth consent screen:
- User Type: External
- App name: "WebUntis Sync"
- Support email: your email
- Scopes: Skip (we'll add later)
- Test users: Add your email
- Application type: "Desktop app"
- Name: "WebUntis Desktop Client"
- Click "Create"
- Click the download icon next to your new OAuth 2.0 Client ID
- Save the file as
credentials.jsonin the project root - Verify file structure matches
credentials.json.example
cp .env.example .envOpen .env and fill in your details:
UNTIS_SCHOOL='YourSchoolName' # e.g., 'Example High School'
UNTIS_USERNAME='your.username' # Your WebUntis username
UNTIS_PASSWORD='your_password' # Your WebUntis password
UNTIS_WEEKS=4 # Number of weeks to sync (1-8)
UNTIS_HEADLESS=true # Run browser in backgroundYour school name is in the WebUntis URL:
https://[SERVER].webuntis.com/WebUntis/?school=[SCHOOL_NAME]
Example:
https://neilo.webuntis.com/WebUntis/?school=Example+School
→ UNTIS_SCHOOL='Example School'
source .env
echo "School: $UNTIS_SCHOOL"
echo "User: $UNTIS_USERNAME"
echo "Weeks: $UNTIS_WEEKS"chmod +x *.sh *.py./run_full_sync.shThis will:
- Open browser for Google authentication (first time only)
- Log into WebUntis
- Extract schedule data
- Create calendar events
On first run:
- Browser opens automatically
- Log in to your Google account
- Click "Allow" to grant calendar access
- Close browser when done
Token is saved to token.pickle for future use.
Check extracted data:
ls -lh weekly_data/
cat weekly_data/week_1.json | python3 -m json.tool | lessOpen Google Calendar and verify events were created.
Look for:
- Orange colored events
- Subject names as titles
- Room locations
- 10-minute reminder
# Open crontab
crontab -e
# Add this line (adjust path):
*/30 * * * * /full/path/to/untis-calendar-sync/auto_sync.sh >> /full/path/to/logs/cron.log 2>&1Save and exit.
Create /etc/systemd/system/untis-sync.service:
[Unit]
Description=WebUntis Calendar Sync
After=network.target
[Service]
Type=oneshot
User=your_username
WorkingDirectory=/path/to/untis-calendar-sync
ExecStart=/path/to/untis-calendar-sync/auto_sync.sh
StandardOutput=append:/path/to/logs/cron.log
StandardError=append:/path/to/logs/cron.logCreate /etc/systemd/system/untis-sync.timer:
[Unit]
Description=Run WebUntis sync every 30 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
[Install]
WantedBy=timers.targetEnable:
sudo systemctl enable untis-sync.timer
sudo systemctl start untis-sync.timer- Open Task Scheduler
- Create Basic Task
- Name: "WebUntis Calendar Sync"
- Trigger: Daily, repeat every 30 minutes
- Action: Start a program
- Program:
C:\path\to\python.exe - Arguments:
C:\path\to\auto_sync.sh - Finish
./check_status.shExpected output:
System Status
=============
CRONTAB: Active
STATUS SERVER: Running
SYNC STATUS:
Last Sync: 2025-10-23 23:00:00
Next in: 27 minutes
Weeks: 4 | Lessons: 67
# Latest sync log
tail -f logs/full_sync_*.log
# Cron log
tail -f logs/cron.log
# All logs
ls -lth logs/Run sync twice:
./run_full_sync.sh
# Wait for completion
./run_full_sync.shSecond run should show:
✓ Neu erstellt: 0
⊘ Übersprungen (Duplikate): 67
python3 status_server.pyOpen browser: http://localhost:8080/dashboard
source venv/bin/activate
pip install -r requirements.txt- Delete
token.pickle - Run
./run_full_sync.shagain - Re-authenticate in browser
- Verify credentials in
.env - Test login manually on WebUntis website
- Check school name format
- Check parsed data:
cat parsed_lessons_all_weeks.json - Verify Calendar ID in
auth.py - Check Google Calendar API quota
# Install Chrome/Chromium
sudo apt update
sudo apt install chromium-browser
# Or on macOS
brew install --cask google-chromepython3 remove_duplicates.py- Customize Colors: Edit
untis_sync_improved.pyline 448 - Adjust Reminders: Edit
untis_sync_improved.pyline 451 - Change Sync Frequency: Edit crontab timing
- Monitor Dashboard: Keep
status_server.pyrunning
- Read the README for detailed documentation
- Check GitHub Issues
- Review logs in
logs/directory
- Never commit
.envfile - Never commit
credentials.json - Never commit
token.pickle - Keep these files secure and private
- Use
.gitignoreproperly
source venv/bin/activate
pip install --upgrade -r requirements.txtfind logs/ -name "*.log" -mtime +30 -deletecp .env .env.backup
cp credentials.json credentials.json.backup# Stop automation
crontab -r
# Clear data
rm -rf weekly_data/*.json
rm -f parsed_lessons_all_weeks.json
rm -f sync_status.json
rm -f token.pickle
# Start fresh
./run_full_sync.sh