-
Notifications
You must be signed in to change notification settings - Fork 67
Open
Labels
agentdealsDealAgent: price tracking and deal discoveryDealAgent: price tracking and deal discoveryenhancementNew feature or requestNew feature or requestp1medium prioritymedium priority
Milestone
Description
Summary
Implement a notification system for the DealAgent that sends alerts when tracked product prices drop below configured thresholds. Support Windows desktop toast notifications (primary) and webhooks (for Slack/Discord/Teams integration).
Motivation
Notifications are the core value proposition of price tracking. Without them, users must manually check prices. CamelCamelCamel's #1 feature is email alerts on price drops — our equivalent uses desktop toasts (private, local-first) with optional webhook integration.
Design
Notification Architecture
# src/gaia/agents/deals/notifications.py
from abc import ABC, abstractmethod
class NotificationChannel(ABC):
@abstractmethod
def send(self, title: str, message: str, url: str = "", image: str = "") -> bool:
"""Send a notification. Returns True if delivered."""
class DesktopNotification(NotificationChannel):
"""Windows toast notification via win10toast or plyer."""
def send(self, title, message, url="", image=""):
# Windows: win10toast-persist or plyer
# Linux: plyer (uses libnotify)
pass
class WebhookNotification(NotificationChannel):
"""Send notification to a webhook URL (Slack, Discord, Teams, custom)."""
def __init__(self, webhook_url: str, format: str = "auto"):
self.webhook_url = webhook_url
self.format = format # 'slack', 'discord', 'teams', 'generic'
def send(self, title, message, url="", image=""):
# Auto-detect format from URL or use explicit format
pass
class NotificationManager:
"""Manages notification channels and alert delivery."""
def __init__(self, channels: List[NotificationChannel]):
self.channels = channels
def notify_price_drop(self, product_name: str, old_price: float,
new_price: float, target_price: float, url: str = ""):
title = f"Price Drop: {product_name}"
pct = ((old_price - new_price) / old_price) * 100
message = f"${new_price:.2f} (was ${old_price:.2f}, -{pct:.0f}%)"
if new_price <= target_price:
message += f" — Below your target of ${target_price:.2f}!"
for channel in self.channels:
channel.send(title, message, url)Configuration
# In DealAgentConfig
notification_channels: List[str] = ["desktop"] # 'desktop', 'webhook'
webhook_url: str = "" # For Slack/Discord integration
alert_cooldown_hours: int = 24 # Don't re-alert for same product within this windowEnvironment Variables
| Variable | Required | Description |
|---|---|---|
GAIA_DEALS_WEBHOOK_URL |
No | Webhook URL for Slack/Discord notifications |
GAIA_DEALS_ALERT_COOLDOWN |
No | Hours between alerts for same product (default: 24) |
Alert Flow
Price check detects drop → Check watchlist threshold → Check cooldown timer
→ If threshold met AND cooldown expired:
1. Send to all configured channels
2. Update last_alerted_at in watchlist table
3. Log alert in notification_history table
Notification History Table
CREATE TABLE notification_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER NOT NULL,
channel TEXT NOT NULL,
old_price REAL,
new_price REAL,
delivered BOOLEAN DEFAULT 1,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES products(id)
);Acceptance Criteria
- Windows desktop toast notifications work (via
plyerorwin10toast) - Webhook notifications work for Slack, Discord, and generic endpoints
- Alert cooldown prevents duplicate notifications
- Notification history stored in SQLite
- Graceful fallback: if desktop notification fails, log warning (don't crash)
-
gaia dealscan show recent alerts:list_alertstool - Unit tests with mocked notification channels
- Integration test sending to a test webhook endpoint
Phase
Phase 2 — Tracking & Alerts
Dependencies
- Watchlist management (Phase 2)
- Scheduled price checking (Phase 2)
New Dependencies
| Package | Version | License | Purpose |
|---|---|---|---|
plyer |
>=2.1 | MIT | Cross-platform desktop notifications |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
agentdealsDealAgent: price tracking and deal discoveryDealAgent: price tracking and deal discoveryenhancementNew feature or requestNew feature or requestp1medium prioritymedium priority