Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
5b47d46
fix(area): improve error handling for incompatible action-reaction co…
Arkteus Nov 2, 2025
d14e062
fix(validators): update Gmail reaction schemas to require message_id …
Arkteus Nov 2, 2025
a8c5d21
feat(celery): add periodic task for checking YouTube actions every 5 …
Arkteus Nov 2, 2025
81332e9
feat(oauth2): add YouTube API scopes for read and force-ssl access
Arkteus Nov 2, 2025
5c891a2
feat(serializers): map YouTube service to Google OAuth
Arkteus Nov 2, 2025
3e339e0
feat(youtube): add YouTube reaction handling and polling task
Arkteus Nov 2, 2025
1742e22
feat(youtube): implement YouTube webhook signature validation and sub…
Arkteus Nov 2, 2025
86ca4a4
feat(youtube): add helper functions for YouTube Data API interactions
Arkteus Nov 2, 2025
1c48adc
feat(youtube): add YouTube service with actions and reactions for vid…
Arkteus Nov 2, 2025
fa17db7
feat(youtube): add YouTube to OAuth service name resolution
Arkteus Nov 2, 2025
8707dfb
feat(youtube): add YouTube to token mapping for OAuth service resolution
Arkteus Nov 2, 2025
04e0731
chore(env): clean up comment formatting for webhook secrets section
Arkteus Nov 2, 2025
e4a3d0f
fix(validators): remove unnecessary whitespace in error handling for …
Arkteus Nov 2, 2025
966936f
fix(webhooks): remove unnecessary whitespace in extract_event_id and …
Arkteus Nov 2, 2025
ae46258
fix(youtube_helper): remove unnecessary whitespace in function implem…
Arkteus Nov 2, 2025
fb0a6c5
feat(calendar): add Google Calendar polling task for event actions
Arkteus Nov 2, 2025
26221df
feat(celery): add periodic task for Google Calendar actions
Arkteus Nov 2, 2025
fa3da78
fix(debug): remove unnecessary text in external events trigger message
Arkteus Nov 2, 2025
10ca163
feat(youtube): add schemas for YouTube actions and reactions
Arkteus Nov 2, 2025
fadfe49
feat(youtube): update reaction schemas to include default values and …
Arkteus Nov 2, 2025
29a88d1
feat(youtube): update check_youtube_actions to track last checked tim…
Arkteus Nov 2, 2025
8c00e60
fix(youtube): replace get_or_create_action_state with ActionState's g…
Arkteus Nov 2, 2025
ff2ce42
feat: Implement Google Webhook (Push Notification) Management
Arkteus Nov 2, 2025
db3eb34
feat(tests): add script to verify Google webhook infrastructure setup
Arkteus Nov 2, 2025
b3306bb
fix(urls): update Google webhook paths to remove 'api/' prefix
Arkteus Nov 2, 2025
f412995
feat(google-webhooks): add configuration for Gmail, Calendar, and You…
Arkteus Nov 2, 2025
6497fc1
refactor(webhooks): replace require_http_methods with api_view and pe…
Arkteus Nov 2, 2025
7c77310
feat(about-service): add YouTube logo URL to AboutServiceSerializer
Arkteus Nov 2, 2025
f4c3e61
feat(oauth-callback): automate Google webhook setup during OAuth call…
Arkteus Nov 2, 2025
b27b7a8
fix(about-service): update YouTube logo URL in AboutServiceSerializer
Arkteus Nov 2, 2025
3fbcc73
fix(webhooks): update Gmail and Calendar webhook URLs to remove '/api'
Arkteus Nov 2, 2025
0ff5d8e
feat(settings): add BACKEND_URL for webhook callbacks configuration
Arkteus Nov 2, 2025
de0b198
fix(webhooks): update Gmail and Calendar webhook URLs to use BACKEND_URL
Arkteus Nov 2, 2025
69447e0
feat(gmail): update Gmail watch creation to use Credentials for authe…
Arkteus Nov 2, 2025
e64eb1f
refactor(webhooks): remove csrf_exempt decorator from webhook views
Arkteus Nov 2, 2025
984c518
fix: reorder webhook routes - Google webhooks before generic
Arkteus Nov 2, 2025
dff316c
feat(youtube): enhance parse_atom_feed_entry to handle XML and extrac…
Arkteus Nov 2, 2025
89cf08f
feat(calendar): add calendar_id parameter to list_upcoming_events fun…
Arkteus Nov 2, 2025
dba98b1
fix(calendar): correct formatting of parameters in list_upcoming_even…
Arkteus Nov 2, 2025
dce1a2e
fix(youtube): improve XML parsing in parse_atom_feed_entry function
Arkteus Nov 2, 2025
fe8e271
fix(celery): disable polling for Google Calendar and YouTube actions …
Arkteus Nov 2, 2025
fcd5007
fix(celery): disable polling for Twitch actions when webhooks are con…
Arkteus Nov 2, 2025
9d85a12
fix(celery): remove unnecessary whitespace in get_beat_schedule function
Arkteus Nov 2, 2025
18c160b
refactor(settings): improve readability of webhook configuration in b…
Arkteus Nov 2, 2025
249da19
refactor(google_webhook_views): clean up imports and improve code for…
Arkteus Nov 2, 2025
825dac2
fix(GoogleWebhookWatch): format string in __str__ method for better r…
Arkteus Nov 2, 2025
68f102b
fix(serializers): improve error message formatting in AreaSerializer …
Arkteus Nov 2, 2025
97c98db
refactor(tasks): improve code readability by formatting conditional s…
Arkteus Nov 2, 2025
1edb907
refactor(urls): reorder import statements for better organization
Arkteus Nov 2, 2025
ca17507
fix(validators): improve error message formatting in validate_reactio…
Arkteus Nov 2, 2025
74778ea
refactor(webhook_receiver): improve log message formatting for YouTub…
Arkteus Nov 2, 2025
4234f4c
fix(calendar_helper): add missing comma in list_upcoming_events funct…
Arkteus Nov 2, 2025
c0442c1
refactor(google_webhook_helper): improve import organization and simp…
Arkteus Nov 2, 2025
3884e13
refactor(youtube_helper): simplify function calls and improve code re…
Arkteus Nov 2, 2025
1c7853a
refactor(test_google_webhooks): improve import organization and enhan…
Arkteus Nov 2, 2025
828174f
refactor(oauth_views): simplify log message formatting in OAuthCallba…
Arkteus Nov 2, 2025
c56cda8
refactor(gmail_webhook): simplify message matching logic in _gmail_me…
Arkteus Nov 2, 2025
19ff923
refactor(check_google_calendar_actions): remove unnecessary target_ti…
Arkteus Nov 2, 2025
cae075d
refactor(youtube_helper): enhance XML parsing error handling and impr…
Arkteus Nov 2, 2025
e21e67a
refactor(test_google_webhooks): reorder imports for better organization
Arkteus Nov 2, 2025
8affd15
refactor(Debug): simplify external event trigger message display
Arkteus Nov 2, 2025
914309a
refactor(ServiceDetail): update OAuth comments for clarity and comple…
Arkteus Nov 2, 2025
d8e9b64
feat(GoogleWebhookBanner): add informative banner for Google webhook …
Arkteus Nov 2, 2025
cce615f
feat(ServiceDetail): add Google Webhook Banner for Calendar and YouTu…
Arkteus Nov 2, 2025
f12009f
fix(gmail_webhook): handle missing history in Gmail notifications
Arkteus Nov 2, 2025
0003d1b
fix(google_webhook_helper): update Gmail and Calendar service credent…
Arkteus Nov 2, 2025
cc8f9d0
fix(google_webhook_helper): clarify parameters for stopping Gmail wat…
Arkteus Nov 2, 2025
d7e63dd
fix(gmail_webhook): standardize quotes for history retrieval checks
Arkteus Nov 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ NOTION_REDIRECT_URI=http://localhost:8080/auth/oauth/notion/callback/
# JSON dictionary format for webhook secrets
# Generate secure random strings: openssl rand -base64 32
# Format: WEBHOOK_SECRETS='{"service_name":"secret_key",...}'
#
#
# To enable webhooks for a service:
# 1. Generate a secure secret: openssl rand -base64 32
# 2. Add it to this JSON dictionary
Expand Down
36 changes: 24 additions & 12 deletions backend/area_project/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,31 @@ def get_beat_schedule():
},
"check-gmail-actions": {
"task": "automations.check_gmail_actions",
"schedule": 180.0, # Every 3 minutes (no webhook support yet)
"schedule": 180.0, # Every 3 minutes (polling fallback)
},
# Google Calendar: Webhooks enabled, polling disabled
# "check-google-calendar-actions": {
# "task": "automations.check_google_calendar_actions",
# "schedule": 180.0, # Every 3 minutes (polling fallback)
# },
# YouTube: Webhooks enabled, polling disabled
# "check-youtube-actions": {
# "task": "automations.check_youtube_actions",
# "schedule": 300.0, # Every 5 minutes (polling fallback)
# },
"check-weather-actions": {
"task": "automations.check_weather_actions",
"schedule": 300.0, # Every 5 minutes (no webhook support)
},
# Google Push Notification (Watch) Management
"renew-google-watches": {
"task": "automations.renew_google_watches",
"schedule": 3600.0, # Every hour - auto-renew expiring watches
},
"setup-youtube-watches": {
"task": "automations.setup_youtube_watches",
"schedule": 7200.0, # Every 2 hours - ensure YouTube subscriptions active
},
"collect-execution-metrics": {
"task": "automations.collect_execution_metrics",
"schedule": crontab(minute=0), # Every hour
Expand Down Expand Up @@ -112,17 +131,6 @@ def get_beat_schedule():
else:
print("✅ [CELERY BEAT] PROD: GitHub webhooks active, polling disabled")

if not webhook_secrets.get("twitch"):
schedule["check-twitch-actions"] = {
"task": "automations.check_twitch_actions",
"schedule": 60.0, # Every minute
}
print(
"⚠️ [CELERY BEAT] PROD: Twitch polling enabled (webhook not configured)"
)
else:
print("✅ [CELERY BEAT] PROD: Twitch webhooks active, polling disabled")

if not webhook_secrets.get("slack"):
schedule["check-slack-actions"] = {
"task": "automations.check_slack_actions",
Expand All @@ -141,6 +149,10 @@ def get_beat_schedule():
}
print("✅ [CELERY BEAT] Notion polling enabled (every 5 minutes)")

# Google services: Webhooks active
print("✅ [CELERY BEAT] Google Calendar webhooks active, polling disabled")
print("✅ [CELERY BEAT] YouTube webhooks active, polling disabled")

return schedule


Expand Down
29 changes: 29 additions & 0 deletions backend/area_project/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/calendar.readonly",
"https://www.googleapis.com/auth/calendar.events",
"https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/youtube.force-ssl",
],
"requires_refresh": True,
},
Expand Down Expand Up @@ -347,6 +349,28 @@
logger.debug(f"Raw value: {webhook_secrets_raw[:50]}...")
WEBHOOK_SECRETS = {}

# =============================================================================
# GOOGLE PUSH NOTIFICATIONS (WEBHOOKS)
# =============================================================================
# Configuration for Gmail, Calendar, and YouTube webhooks
GMAIL_WEBHOOK_ENABLED = os.getenv("GMAIL_WEBHOOK_ENABLED", "false").lower() == "true"
CALENDAR_WEBHOOK_ENABLED = (
os.getenv("CALENDAR_WEBHOOK_ENABLED", "false").lower() == "true"
)
YOUTUBE_WEBHOOK_ENABLED = (
os.getenv("YOUTUBE_WEBHOOK_ENABLED", "false").lower() == "true"
)

# Webhook URLs (must be set in environment variables)
GMAIL_WEBHOOK_URL = os.getenv("GMAIL_WEBHOOK_URL", "")
CALENDAR_WEBHOOK_URL = os.getenv("CALENDAR_WEBHOOK_URL", "")
YOUTUBE_WEBHOOK_URL = os.getenv("YOUTUBE_WEBHOOK_URL", "")

# Watch renewal interval (in seconds) - default 6 days
GOOGLE_WATCH_RENEWAL_INTERVAL = int(
os.getenv("GOOGLE_WATCH_RENEWAL_INTERVAL", "518400")
)

# Security Settings (base - extended per environment)
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
Expand Down Expand Up @@ -530,6 +554,11 @@
# In production: https://your-frontend-domain.com
FRONTEND_URL = os.getenv("FRONTEND_URL", "http://localhost:5173")

# Backend URL for webhook callbacks
# In development: http://localhost:8000
# In production: https://your-backend-domain.com
BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:8000")

# CORS Configuration
# Base allowed origins (extended per environment)
CORS_ALLOWED_ORIGINS = [
Expand Down
Loading
Loading