Automated license management system for Zoom that assigns and unassigns licenses based on a predefined schedule.
To automatically run the license manager at 1 AM from Monday to Friday, set up a cron job as follows:
Open your crontab configuration:
crontab -e
Add this line to run the script at 1 AM on weekdays (Monday-Friday):
0 1 * * 1-5 cd /path/to/zoom-license-manager && /path/to/venv/bin/python app.py >> /var/log/zoom_license_manager.log 2>&1
Replace:
/path/to/zoom-license-manager with the actual path to your project directory/path/to/venv/bin/python with the path to your virtual environmentβs Python executableSave and exit. The cron job will now run automatically.
(Optional) To monitor the logs:
tail -f /var/log/zoom_license_manager.log
To prevent log files from growing too large, set up log rotation by creating a new file at /etc/logrotate.d/zoom-license-manager with:
/var/log/zoom_license_manager.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root root
}
Clone the repository:
git clone https://github.com/yourusername/zoom-license-manager.git
cd zoom-license-manager
Create and activate a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
Install dependencies:
pip install -r requirements.txt
Copy the example environment file and update with your credentials:
cp .env.example .env
# Edit .env with your actual credentials
Edit the .env file with your configuration:
# Zoom API Configuration
ZOOM_ACCOUNT_ID=your_account_id
ZOOM_CLIENT_ID=your_client_id
ZOOM_CLIENT_SECRET=your_client_secret
# Database Configuration
DB_HOST=localhost
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_NAME=your_db_name
# Telegram Bot Configuration
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id
# Exempt Users (never unassigned)
EXEMPT_USERS=admin@example.com,user@example.com
python app.py
For manual interventions, two specialized scripts are available:
To clear licenses from users in bulk (e.g., at the end of a semester), use unassign_massive.py. It reads from zoomus_users.csv.
python3 unassign_massive.py
python3 unassign_massive.py --execute
[!NOTE]
This script automatically skips users in yourEXEMPT_USERSlist.
To quickly assign licenses to everyone scheduled for today without waiting for the automated cron job or relying on differential logic:
python3 assign_today.py
python3 assign_today.py --execute
The system sends detailed notifications to Telegram with the following format:
π License Management Summary
==========================
π
Date: 2023-09-20
β° Time: 00:40:03 EAT
π΄ Unassigned: 5/5
π’ Assigned: 3/3
π License Usage:
β’ Total Licenses: 100
β’ Used Licenses: 85
β’ Available Licenses: 15
β οΈ Warning: Running low on available licenses!
π‘οΈ Exempt Users (Never Unassigned):
β’ admin@example.com
β’ manager@example.com
π‘οΈ Exempted in This Run:
β’ user1@example.com
β’ user2@example.com
β Failed Unassignments:
β’ user3@example.com: User not found
β Failed Assignments:
β’ user4@example.com: No available licenses
β
Completed Successfully
The system includes a comprehensive license usage report showing:
You can also check license usage programmatically:
from assign import get_license_usage
usage = get_license_usage()
if usage:
print(f"Total Licenses: {usage['total_licenses']}")
print(f"Used Licenses: {usage['used_licenses']}")
print(f"Available Licenses: {usage['available_licenses']}")
π Starting license management...
==================================================
π
Today is: Friday
π
Yesterday was: Thursday
π Fetching schedule...
β
Successfully connected to the database.
π License Usage:
β’ Total Licenses: 100
β’ Used Licenses: 85
β’ Available Licenses: 15
π Summary:
- Found 5 users to unassign
- Found 3 users to assign
π΄ Unassigning licenses for 5 users...
1. Unassigning from user1@example.com... β
Done
...
π’ Assigning licenses to 3 users...
1. Assigning to newuser@example.com... β
Done
...
==================================================
β
License management completed!
π± Notification sent to Telegram
EXEMPT_USERS list will never have their licenses unassignedThis project is licensed under the MIT License - see the LICENSE file for details.