A comprehensive Python-based webhook server for receiving and processing Agora video calling notifications. This server provides real-time analytics, monitoring, and a beautiful web dashboard for your Agora applications.
- Webhook Reception: Receives Agora webhooks via HTTPS POST requests with route-based App ID handling
- Real-time Processing: Processes webhook events and calculates usage metrics with intelligent session tracking
- Duplicate Prevention: Advanced in-memory and database-based duplicate webhook detection
- Session Management: Automatic channel session tracking with join/leave event correlation
- Smart Caching: In-memory caching for performance optimization
- Beautiful UI: Modern, responsive web interface with gradient design
- Real-time Analytics: Live channel statistics and user metrics
- Interactive Search: Search channels by name with pagination
- Advanced Filtering: Filter channels by date, platform, client type, and role with URL persistence
- Detailed Views: Comprehensive channel and user session details
- Mobile Responsive: Works perfectly on desktop and mobile devices
- Shareable Links: Permalink functionality for sharing specific channels with team members
- Visual Channel Flags: Color-coded indicators showing client types (Cloud Recording, Media Push/Pull, Conversational AI, etc.)
- Role Analytics: Track host vs audience minutes with role switching detection
- Concurrent Users Graph: Visualize concurrent users over time for each channel session
- Role Indicators: Visual mic/ear icons showing user roles (π€ Host, π Audience) with stacked indicators for role switches
- Chart Drill-Down: Click data points in Minutes Analytics to filter channels automatically
- SQLite Database: Lightweight, file-based database for easy deployment
- Comprehensive Metrics: Track total minutes, unique users, session counts
- Platform Detection: Automatic platform identification (Android, iOS, Web, etc.)
- Product Mapping: Support for RTC, Cloud Recording, Media Push/Pull
- Historical Data: Store and analyze historical webhook events
- SSL/TLS Support: Full HTTPS encryption for production deployments
- Systemd Integration: Service management with automatic startup
- Nginx Reverse Proxy: Production-grade web server configuration
- Health Monitoring: Built-in health checks and monitoring endpoints
- Logging: Comprehensive logging with configurable levels
- Security: Firewall configuration and security headers
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Agora Cloud βββββΆβ Webhook Server βββββΆβ SQLite DB β
β β β (FastAPI) β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β
βΌ
ββββββββββββββββββββ
β Web Dashboard β
β (HTML/JS) β
ββββββββββββββββββββ
git clone https://github.com/frank005/AgoraWebhooks.git
cd AgoraWebhookspython3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtCreate your environment configuration:
cp env.example .env
# Edit .env with your settingspython start_dev.pyThe server will start on http://localhost:8000
Prerequisites:
- Ubuntu 24.04 server
- Sudo access
- Domain name pointing to your server's IP address
- Port 80 must be open in your cloud provider's firewall/security group (required for Let's Encrypt certbot)
- The script configures UFW firewall, but you must also open port 80 in your cloud provider's security group/firewall
- Certbot needs port 80 to validate domain ownership
Run the deployment script on your Ubuntu 24.04 server:
./deploy.shThe script will:
- Install all dependencies (Python, nginx, certbot, etc.)
- Prompt for your domain name
- Configure the firewall (ports 22, 80, 443)
- Set up SSL certificates via Let's Encrypt (optional)
- Configure and start the service
Important: Before running certbot, ensure port 80 is open in your cloud provider's firewall/security group. Certbot needs port 80 to validate domain ownership.
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
SQLite database path | sqlite:///./agora_webhooks.db |
HOST |
Server host | 0.0.0.0 |
PORT |
Server port | 443 |
SSL_CERT_PATH |
SSL certificate path | None |
SSL_KEY_PATH |
SSL private key path | None |
LOG_LEVEL |
Logging level | INFO |
LOG_FILE |
Log file path | agora_webhooks.log |
MAX_WORKERS |
Background processing workers | 4 |
- Log in to Agora Console
- Navigate to your project
- Go to All Features β Notifications
- Configure:
- Event: Select events you want to monitor (e.g., User joined/left channel)
- Receiving Server URL Endpoint:
https://your-domain.com/{app_id}/webhooks - Whitelist: Add your server's IP addresses
POST /{app_id}/webhooks
Receives Agora webhook notifications for the specified App ID.
Headers:
Content-Type:application/json
Example:
curl -X POST https://your-domain.com/your-app-id/webhooks \
-H "Content-Type: application/json" \
-d '{
"noticeId": "12345",
"productId": 1,
"eventType": 1,
"payload": {
"clientSeq": 67890,
"uid": 123,
"channelName": "test_channel",
"ts": 1560496834
}
}'GET /api/channels/{app_id}- Get list of channels for an App ID with pagination and optional filters- Query Parameters:
page(int, default: 1) - Page number for paginationper_page(int, default: 30) - Number of results per pagestart_date(string, optional) - Filter by start date (ISO format:YYYY-MM-DDTHH:MM:SSZ)end_date(string, optional) - Filter by end date (ISO format:YYYY-MM-DDTHH:MM:SSZ)platform(int, optional) - Filter by platform ID (1=Android, 2=iOS, 5=Windows, 6=Linux, 7=Web, 8=macOS)client_type(int, optional) - Filter by client type (e.g., 10=Cloud Recording, 28=Media Pull, 30=Media Push, 60=Conversational AI, -1=NULL)role(string, optional) - Filter by role ("host"or"audience")
- Query Parameters:
GET /api/channel/{app_id}/{channel_name}- Get detailed channel information with role-split metricsGET /api/channel/{app_id}/{channel_name}/role-analytics- Get role and product analytics with wall clock timeGET /api/channel/{app_id}/{channel_name}/quality-metrics- Get quality metrics with concurrent users graph dataGET /api/user/{app_id}/{uid}- Get user metrics and session historyGET /api/user/{app_id}/{uid}/detailed- Get detailed user analytics including SID, quality insights, and platform distributionGET /health- Health check endpointGET /debug/cache- Debug cache status
GET /- Main dashboard interface with search and analyticsGET /?appId={app_id}&channel={channel_name}&sessionId={session_id}- Direct channel view with permalink supportGET /?appId={app_id}&filterDate={date}&filterPlatform={platform}&filterClientType={client_type}&filterRole={role}- Channels list with filters
The dashboard supports comprehensive filtering to help you analyze your Agora channel data efficiently. Filters can be applied in multiple ways and persist in the URL for easy bookmarking and sharing.
- Format:
YYYY-MM-DD(e.g.,2025-11-01) - Purpose: Filter channels to show only sessions that occurred on a specific date
- Usage: When filtering by date, the system shows channels that have sessions overlapping with the specified date
- Example:
?appId=your-app-id&filterDate=2025-11-01
- Values: Platform ID numbers
1- Android2- iOS5- Windows6- Linux7- Web8- macOS
- Purpose: Filter channels to show only sessions from a specific platform
- Example:
?appId=your-app-id&filterPlatform=7(Web only)
- Values: Client type ID numbers or
-1for NULL3- Local Recording8- Applets10- Cloud Recording28- Media Pull30- Media Push43- Media Relay47- STT PubBot48- STT SubBot50- Media Gateway60- Conversational AI68- Real-Time STT-1- NULL (no client type specified)
- Purpose: Filter channels to show only sessions using a specific client type
- Example:
?appId=your-app-id&filterClientType=10(Cloud Recording only) - Special Case: Use
-1to filter for sessions with NULL client type (typically Linux platform sessions)
- Values:
"host"or"audience" - Purpose: Filter channels to show only sessions for users with a specific role
host- Shows only host/broadcaster sessionsaudience- Shows only audience/listener sessions
- Example:
?appId=your-app-id&filterRole=host - Note: If both roles are selected in the minutes analytics chart, no role filter is applied (shows all roles)
-
Via URL Parameters: Add filter parameters directly to the URL
https://your-domain.com/?appId=your-app-id&filterDate=2025-11-01&filterPlatform=7&filterRole=host -
Via Chart Drill-Down: Click on any data point in the Minutes Analytics chart
- The system automatically extracts filters from the clicked data point
- Navigates to the channels list with filters applied
- URL is updated with all relevant filter parameters
-
Filter Combinations: Multiple filters can be combined
- Filters work together (AND logic)
- Example:
filterDate=2025-11-01&filterPlatform=7&filterRole=hostshows only Web host sessions on Nov 1, 2025
When filters are active, a blue banner appears at the top of the channels list showing:
- Active Filters: Lists all currently applied filters
- Clear Filters Button: One-click removal of all filters
Example display:
π Active Filters: Date: 2025-11-01 | Platform: 7 | Client Type: 10 | Role: host [Clear Filters]
- URL Preservation: All filters are stored in the URL query parameters
- Bookmarkable: You can bookmark filtered views for quick access
- Shareable: Share filtered URLs with team members
- Auto-Restoration: When navigating between pages, filters are automatically preserved
-
Role Filter Logic:
- When filtering from the minutes analytics chart:
- If one role was selected in the chart β role filter is applied
- If both roles were selected β no role filter (shows all roles)
- This ensures that clicking a data point when viewing all roles doesn't restrict the results
- When filtering from the minutes analytics chart:
-
Date Filter Behavior:
- Single date filter (
filterDate) filters for sessions that overlap with that date - When both
start_dateandend_dateare the same, it filters for that single day - Sessions are included if they overlap with the date range, even if they started before or ended after
- Single date filter (
-
Client Type NULL Handling:
- Use
filterClientType=-1to filter for sessions with NULL client type - Commonly seen in Linux platform sessions where client type may not be specified
- Use
Example 1: Filter by Date
?appId=your-app-id&filterDate=2025-11-01
Shows all channels with sessions on November 1, 2025.
Example 2: Filter by Platform and Role
?appId=your-app-id&filterPlatform=7&filterRole=host
Shows only Web platform host sessions.
Example 3: Filter by Date, Platform, and Client Type
?appId=your-app-id&filterDate=2025-11-01&filterPlatform=6&filterClientType=-1
Shows Linux platform sessions with NULL client type on November 1, 2025.
Example 4: Complex Filter Combination
?appId=your-app-id&filterDate=2025-11-01&filterPlatform=7&filterClientType=10&filterRole=host
Shows Web platform Cloud Recording host sessions on November 1, 2025.
- Clear Filters Button: Click the "Clear Filters" button in the filter indicator banner
- Manual Removal: Remove filter parameters from the URL
- New Search: Start a new search without filters
-
webhook_events - Raw webhook events from Agora
- Stores all incoming webhook data with timestamps
- Includes platform, product, and event type information
-
channel_sessions - Calculated user sessions with join/leave times
- Tracks individual user sessions within channels
- Calculates session duration and tracks completion status
-
channel_metrics - Aggregated metrics per channel per day
- Daily summaries of channel activity
- Total minutes, unique users, and session counts
-
user_metrics - Aggregated metrics per user per channel per day
- User-specific analytics and usage patterns
- Cross-channel user activity tracking
- Comprehensive Filters: Filter channels by date, platform, client type, and role
- URL-Based Filtering: All filters persist in URL for bookmarking and sharing
- Chart Drill-Down: Click data points in Minutes Analytics to filter channels
- Filter Combinations: Combine multiple filters for precise analysis
- Filter Indicator: Visual banner showing active filters with one-click clear
- See the Filtering System section for detailed documentation
- Shareable URLs: Direct links to specific channels and sessions
- URL Parameters: Support for
?appId={app_id}&channel={channel_name}&sessionId={session_id} - Filter Support: Permalinks include filter parameters for filtered views
- Auto-navigation: Automatically loads specified channels when visiting permalinks
- Share Button: One-click URL copying with visual feedback
- Browser History: Proper URL updates without page reloads
- Role Flags: Visual indicators showing user roles and communication modes
- Supported Combinations:
- π΄ RTC/Host - Real-time communication host (communication_mode=1, is_host=true)
- π‘ ILS/Host - Interactive live streaming host (communication_mode=0, is_host=true)
- π΅ ILS/Audience - Interactive live streaming audience (communication_mode=0, is_host=false)
- Event Type Mapping:
- Events 103/104: Broadcaster Join/Leave β ILS/Host
- Events 105/106: Audience Join/Leave β ILS/Audience
- Events 107/108: Communication Join/Leave β RTC/Host
- Events 111/112: Role Change β Tracks role switches (broadcaster β audience)
- Smart Session Assignment: Correctly assigns users to channel sessions even when leave events arrive after channel destroy events
- Role Indicators: Visual icons in session tables:
- π€ Mic icon (purple circle) = Host/Broadcaster
- π Ear icon (blue circle) = Audience/Listener
- Stacked icons = Role switch detected (bottom = initial role, top = final role)
- Role-Split Metrics: Separate tracking of host minutes, audience minutes, unique hosts, and unique audiences
- Client Type Indicators: Color-coded flags showing what types of clients were used
- Supported Types:
- βοΈ Cloud Recording (red) - Client type 10
- β¬οΈ Media Pull (blue) - Client type 28
- β¬οΈ Media Push (green) - Client type 30
- π€ Conversational AI (purple) - Client type 60
- π Media Relay (orange) - Client type 43
- π€ STT PubBot (teal) - Client type 47
- π§ STT SubBot (teal) - Client type 48
- ποΈ Real-Time STT (teal) - Client type 68
- π Media Gateway (gray) - Client type 50
- πΉ Local Recording (yellow) - Client type 3
- π± Applets (pink) - Client type 8
- Raw Numeric Values: Platform and Product ID display includes raw numeric values in muted text (e.g., "Web (7)", "RTC (1)") to avoid mapping errors
- In-memory caching: Fast detection of recent duplicate webhooks
- Database verification: Comprehensive duplicate checking against historical data
- Configurable cache size: Adjustable cache size for different deployment scenarios
- Automatic correlation: Links join and leave events to create complete sessions
- Duration calculation: Accurate session duration tracking
- Platform detection: Identifies user platforms (Android, iOS, Web, etc.)
- Product mapping: Supports RTC, Cloud Recording, Media Push/Pull
- Async processing: Non-blocking webhook processing
- Smart caching: In-memory caches for frequently accessed data
- Efficient queries: Optimized database queries with proper indexing
- Background processing: Separate worker processes for heavy operations
sudo systemctl status agora-webhooks# Service logs
sudo journalctl -u agora-webhooks -f
# Application logs
tail -f /var/log/agora-webhooks.log
# Monitor script logs
tail -f /var/log/agora-webhooks-monitor.logcurl https://your-domain.com/healthcurl https://your-domain.com/debug/cache- HTTPS Only: Production deployment uses SSL/TLS encryption
- Security Headers: Nginx configured with security headers
- Firewall: UFW configured to allow only necessary ports
- No Signature Verification: Webhooks are accepted without signature validation for simplified operation
- Input Validation: Comprehensive webhook payload validation
-
Service won't start
sudo systemctl status agora-webhooks sudo journalctl -u agora-webhooks -n 50
-
Webhook processing fails
- Check webhook payload format matches expected structure
- Verify App ID in URL path is valid
- Review logs for specific error messages
-
Database issues
# Check database file permissions ls -la agora_webhooks.db # Reset database (WARNING: deletes all data) rm agora_webhooks.db python -c "from database import create_tables; create_tables()"
-
SSL certificate issues
# Renew Let's Encrypt certificate sudo certbot renew sudo systemctl reload nginx -
Performance issues
- Check cache hit rates in debug endpoint
- Monitor database query performance
- Review background worker status
AgoraWebhooks/
βββ main.py # FastAPI application
βββ config.py # Configuration management
βββ database.py # Database models and setup
βββ models.py # Pydantic models
βββ webhook_processor.py # Webhook processing logic
βββ mappings.py # Platform and product mappings
βββ fix_emojis.py # Utility script to fix broken emojis
βββ templates/ # HTML templates
β βββ index.html # Web dashboard
βββ old/ # Archived files and tests
β βββ tests/ # Test scripts
βββ requirements.txt # Python dependencies
βββ deploy.sh # Deployment script
βββ start_dev.py # Development startup script
βββ README.md # This file
fix_emojis.py - Fixes UTF-8 encoding issues that corrupt emojis to '??' or '?'
- Automatically runs before git commits (via pre-commit hook)
- Automatically runs after git pull/merge (via post-merge hook)
- Automatically runs during deployment (via deploy.sh)
- Run manually if needed:
python3 fix_emojis.py - Automatically fixes all emojis in
main.pyandtemplates/index.html - Includes verification to ensure all emojis are properly restored
- Enhanced Protection: The script now handles partial emoji corruption and edge cases
Emoji Protection System:
- β Git Hooks: Pre-commit and post-merge hooks automatically fix emojis
- β
EditorConfig:
.editorconfigfile ensures UTF-8 encoding for all editors - β Deploy Script: Deployment automatically fixes emojis before deploying
- β
Manual Fix: Run
python3 fix_emojis.pyanytime to fix broken emojis
Note: Emojis may get corrupted when files are edited through certain tools that don't preserve UTF-8 encoding properly. The git hooks and EditorConfig file help prevent this, but if you notice broken emojis, simply run python3 fix_emojis.py to fix them automatically.
- New Webhook Events: Update
webhook_processor.pyto handle new event types - New Metrics: Add new tables in
database.pyand update processing logic - New API Endpoints: Add routes in
main.py - UI Changes: Modify
templates/index.html - Platform Support: Update
mappings.pyfor new platforms or products
Test scripts are available in the old/tests/ directory:
test_webhook.py- Basic webhook testingtest_complete_session.py- Session simulationtest_duplicate_prevention.py- Duplicate detection testing
- Webhook Processing: < 50ms average response time
- Database Queries: Optimized with proper indexing
- Memory Usage: < 100MB typical usage
- Concurrent Users: Supports 1000+ concurrent webhook requests
- Use SSD storage for database files
- Configure appropriate cache sizes based on traffic
- Monitor memory usage and adjust worker counts
- Regular database maintenance and cleanup
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License.
For issues and questions:
- Check the troubleshooting section
- Review the logs
- Create an issue in the repository
- Check the
old/tests/directory for test examples
- β
Fixed Date and Client Type Filters: Resolved issue where date and client_type filters were not working correctly
- Fixed SQLite datetime comparison by converting timezone-aware datetimes to naive UTC format
- Fixed client_type parameter parsing to ensure proper integer conversion
- Added comprehensive debug logging for filter troubleshooting
- Filters now work correctly for date ranges and client type filtering
- Important: Service restart required after code changes for filters to take effect
- β
Enhanced Emoji Fix Script: Improved
fix_emojis.pywith comprehensive pattern matching- Now handles all emoji patterns including template literals, flag mappings, analytics buttons, and section headers
- Added direct string replacements for reliable emoji restoration
- Fixed all broken emojis across the application (flag mappings, analytics buttons, role icons, section headers)
- Script now automatically fixes 40+ emoji patterns reliably
- β
Emoji Fixes: Fixed all broken emojis across the application
- Fixed emojis in role quality view, multi-user view, and quality insights
- Fixed analytics buttons (Role Analytics, Quality Metrics, Multi-User View)
- Fixed user analytics button and Jump to Top button
- Fixed flag mappings (Local Recording, Applets, Cloud Recording, Media Pull/Push, etc.)
- Fixed all section headers (Overview, Platform Distribution, Quality Metrics, etc.)
- Fixed role icons (π€ for Host, π for Audience)
- All emojis now display correctly throughout the dashboard
- β
Session ID (SID) Support: Added Agora session ID tracking and display in user analytics
- SID extracted from webhook payloads and stored in database
- Displayed in User Analytics title with small grey text formatting (matching date display style)
- Populated from historical webhook logs for existing sessions
- β
Emoji Fix Script: Created
fix_emojis.pyutility script to fix UTF-8 encoding issues that corrupt emojis- Run
python3 fix_emojis.pywhenever emojis get broken - Automatically fixes all emojis in
main.pyandtemplates/index.html - Includes verification to ensure all emojis are properly restored
- Run
- β Role and Communication Mode Indicators: Added visual indicators to distinguish between different communication modes and roles (RTC/Host, ILS/Host, ILS/Audience)
- β Fixed Channel Session Assignment: Resolved issue where users were incorrectly assigned to different channel sessions when leave events came after channel destroy events
- β Enhanced Session Tracking: Improved logic to correctly match leave events to their corresponding channel sessions using timestamp-based correlation
- β Communication Mode Support: Added support for tracking communication mode (RTC vs ILS) in session data and API responses
- β Role Flag Display: Frontend now displays short role indicators (RTC/Host, ILS/Host, ILS/Audience) for better user understanding
- β Permalink Functionality: Share specific channels with team members via direct URLs
- β Visual Channel Flags: Color-coded indicators for different client types (Cloud Recording, Media Push/Pull, Conversational AI, etc.)
- β Enhanced Channel Display: Improved channel cards with client type information and visual indicators
- β Share Button: One-click URL copying for easy channel sharing
- β Repository cleanup and organization
- β Advanced duplicate prevention system
- β Improved session tracking and correlation
- β Enhanced web dashboard with modern UI
- β Platform and product mapping system
- β Performance optimizations and caching
- β Comprehensive logging and monitoring
- β Production deployment improvements