docs: update vide docs

This commit is contained in:
2025-08-04 19:30:48 -06:00
parent f191811e23
commit 770761b3f9
2 changed files with 132 additions and 10 deletions

View File

@@ -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

View File

@@ -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.*