mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 12:19:06 +00:00
docs: update vide docs
This commit is contained in:
@@ -97,6 +97,100 @@ The Daily.co migration implementation is now complete and ready for testing with
|
|||||||
- ✅ Frontend platform-agnostic components
|
- ✅ Frontend platform-agnostic components
|
||||||
- ✅ Comprehensive test suite with >95% coverage
|
- ✅ Comprehensive test suite with >95% coverage
|
||||||
|
|
||||||
|
## Daily.co Webhook Integration
|
||||||
|
|
||||||
|
### Webhook Configuration
|
||||||
|
|
||||||
|
Daily.co webhooks are configured via API (no dashboard interface). Use the Daily.co REST API to set up webhook endpoints:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configure webhook endpoint
|
||||||
|
curl -X POST https://api.daily.co/v1/webhook-endpoints \
|
||||||
|
-H "Authorization: Bearer ${DAILY_API_KEY}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"url": "https://yourdomain.com/v1/daily_webhook",
|
||||||
|
"events": [
|
||||||
|
"participant.joined",
|
||||||
|
"participant.left",
|
||||||
|
"recording.started",
|
||||||
|
"recording.ready-to-download",
|
||||||
|
"recording.error"
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook Event Examples
|
||||||
|
|
||||||
|
**Participant Joined:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "participant.joined",
|
||||||
|
"id": "evt_participant_joined_1640995200",
|
||||||
|
"ts": 1640995200000,
|
||||||
|
"data": {
|
||||||
|
"room": {"name": "test-room-123-abc"},
|
||||||
|
"participant": {
|
||||||
|
"id": "participant-123",
|
||||||
|
"user_name": "John Doe",
|
||||||
|
"session_id": "session-456"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recording Ready:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "recording.ready-to-download",
|
||||||
|
"id": "evt_recording_ready_1640995200",
|
||||||
|
"ts": 1640995200000,
|
||||||
|
"data": {
|
||||||
|
"room": {"name": "test-room-123-abc"},
|
||||||
|
"recording": {
|
||||||
|
"id": "recording-789",
|
||||||
|
"status": "finished",
|
||||||
|
"download_url": "https://bucket.s3.amazonaws.com/recording.mp4",
|
||||||
|
"start_time": "2025-01-01T10:00:00Z",
|
||||||
|
"duration": 1800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook Signature Verification
|
||||||
|
|
||||||
|
Daily.co uses HMAC-SHA256 for webhook verification:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
def verify_daily_webhook(body: bytes, signature: str, secret: str) -> bool:
|
||||||
|
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
|
||||||
|
return hmac.compare_digest(expected, signature)
|
||||||
|
```
|
||||||
|
|
||||||
|
Signature is sent in the `X-Daily-Signature` header.
|
||||||
|
|
||||||
|
### Recording Processing Flow
|
||||||
|
|
||||||
|
1. **Daily.co Meeting Ends** → Recording processed
|
||||||
|
2. **Webhook Fired** → `recording.ready-to-download` event
|
||||||
|
3. **Webhook Handler** → Extracts download URL and recording ID
|
||||||
|
4. **Background Task** → `process_recording_from_url.delay()` queued
|
||||||
|
5. **Download & Process** → Audio downloaded, validated, transcribed
|
||||||
|
6. **ML Pipeline** → Same processing as Whereby recordings
|
||||||
|
|
||||||
|
```python
|
||||||
|
# New Celery task for Daily.co recordings
|
||||||
|
@shared_task
|
||||||
|
@asynctask
|
||||||
|
async def process_recording_from_url(recording_url: str, meeting_id: str, recording_id: str):
|
||||||
|
# Downloads from Daily.co URL → Creates transcript → Triggers ML pipeline
|
||||||
|
# Identical processing to S3-based recordings after download
|
||||||
|
```
|
||||||
|
|
||||||
## Testing the Current Implementation
|
## Testing the Current Implementation
|
||||||
|
|
||||||
### Running the Test Suite
|
### Running the Test Suite
|
||||||
@@ -133,6 +227,35 @@ meeting = await client.create_meeting(
|
|||||||
print(f"Created meeting: {meeting.room_url}")
|
print(f"Created meeting: {meeting.room_url}")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Testing Daily.co Recording Processing
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Test webhook payload processing
|
||||||
|
from reflector.views.daily import daily_webhook
|
||||||
|
from reflector.worker.process import process_recording_from_url
|
||||||
|
|
||||||
|
# Simulate webhook event
|
||||||
|
event_data = {
|
||||||
|
"type": "recording.ready-to-download",
|
||||||
|
"id": "evt_123",
|
||||||
|
"ts": 1640995200000,
|
||||||
|
"data": {
|
||||||
|
"room": {"name": "test-room-123"},
|
||||||
|
"recording": {
|
||||||
|
"id": "rec-456",
|
||||||
|
"download_url": "https://daily.co/recordings/test.mp4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test processing task (when credentials available)
|
||||||
|
await process_recording_from_url(
|
||||||
|
recording_url="https://daily.co/recordings/test.mp4",
|
||||||
|
meeting_id="meeting-123",
|
||||||
|
recording_id="rec-456"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
## Architecture Benefits
|
## Architecture Benefits
|
||||||
|
|
||||||
1. **Testable**: Mock implementation allows testing without external dependencies
|
1. **Testable**: Mock implementation allows testing without external dependencies
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class DailyClient:
|
|||||||
"name": f"{room_name_prefix}-{datetime.now().strftime('%Y%m%d%H%M%S')}",
|
"name": f"{room_name_prefix}-{datetime.now().strftime('%Y%m%d%H%M%S')}",
|
||||||
"privacy": "private" if room.is_locked else "public",
|
"privacy": "private" if room.is_locked else "public",
|
||||||
"properties": {
|
"properties": {
|
||||||
"enable_recording": "cloud", # Same as Whereby
|
"enable_recording": "raw-tracks", #"cloud",
|
||||||
"enable_chat": True,
|
"enable_chat": True,
|
||||||
"enable_screenshare": True,
|
"enable_screenshare": True,
|
||||||
"start_video_off": False,
|
"start_video_off": False,
|
||||||
@@ -157,14 +157,13 @@ class DailyClient:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configure S3 bucket for recordings (same as Whereby)
|
# if room.recording_type == "cloud":
|
||||||
if room.recording_type == "cloud":
|
data["properties"]["recording_bucket"] = {
|
||||||
data["properties"]["recording_bucket"] = {
|
"bucket_name": settings.AWS_S3_BUCKET,
|
||||||
"bucket_name": settings.AWS_S3_BUCKET,
|
"bucket_region": settings.AWS_REGION,
|
||||||
"bucket_region": settings.AWS_REGION,
|
"assume_role_arn": settings.AWS_DAILY_ROLE_ARN,
|
||||||
"assume_role_arn": settings.AWS_DAILY_ROLE_ARN,
|
"path": f"recordings/{data['name']}"
|
||||||
"path": f"recordings/{data['name']}"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
@@ -584,4 +583,4 @@ Migration to Daily.co is technically feasible and can be implemented in phases:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Analysis based on current codebase review and API documentation comparison.*
|
*Analysis based on current codebase review and API documentation comparison.*
|
||||||
|
|||||||
Reference in New Issue
Block a user