Skip to content

Commit 303b335

Browse files
committed
Create price alert service
1 parent 515f6b6 commit 303b335

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

services/price_alert.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package services
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strconv"
7+
"time"
8+
9+
"github.com/Jetlum/WalletAlertService/models"
10+
"github.com/Jetlum/WalletAlertService/repository"
11+
)
12+
13+
type PriceAlertService struct {
14+
priceMonitor *PriceMonitor
15+
alertRepo *repository.PriceAlertRepository
16+
emailNotifier EmailNotifier
17+
}
18+
19+
func NewPriceAlertService(
20+
priceMonitor *PriceMonitor,
21+
alertRepo *repository.PriceAlertRepository,
22+
emailNotifier EmailNotifier,
23+
) *PriceAlertService {
24+
return &PriceAlertService{
25+
priceMonitor: priceMonitor,
26+
alertRepo: alertRepo,
27+
emailNotifier: emailNotifier,
28+
}
29+
}
30+
31+
func (s *PriceAlertService) StartMonitoring() {
32+
ticker := time.NewTicker(1 * time.Minute)
33+
go func() {
34+
for range ticker.C {
35+
s.checkAlerts()
36+
}
37+
}()
38+
}
39+
40+
func (s *PriceAlertService) checkAlerts() {
41+
alerts, err := s.alertRepo.GetActiveAlerts()
42+
if err != nil {
43+
log.Printf("Error fetching active alerts: %v", err)
44+
return
45+
}
46+
47+
for _, alert := range alerts {
48+
price, err := s.priceMonitor.GetPrice(alert.CryptocurrencyID)
49+
if err != nil {
50+
log.Printf("Error getting price for %s: %v", alert.CryptocurrencyID, err)
51+
continue
52+
}
53+
54+
threshold, _ := strconv.ParseFloat(alert.ThresholdPrice, 64)
55+
if s.shouldTriggerAlert(price, threshold, alert.IsUpperBound) {
56+
s.triggerAlert(&alert, price)
57+
}
58+
}
59+
}
60+
61+
func (s *PriceAlertService) shouldTriggerAlert(currentPrice, threshold float64, isUpperBound bool) bool {
62+
if isUpperBound {
63+
return currentPrice >= threshold
64+
}
65+
return currentPrice <= threshold
66+
}
67+
68+
func (s *PriceAlertService) triggerAlert(alert *models.PriceAlert, currentPrice float64) {
69+
message := fmt.Sprintf(
70+
"Price Alert: %s has reached $%.2f (Threshold: $%s)",
71+
alert.CryptocurrencyID,
72+
currentPrice,
73+
alert.ThresholdPrice,
74+
)
75+
76+
if alert.EmailNotification {
77+
// Create event for notification
78+
event := &models.Event{
79+
EventType: "PRICE_ALERT",
80+
Value: fmt.Sprintf("%.2f", currentPrice),
81+
}
82+
83+
userPref := &models.UserPreference{
84+
UserID: alert.UserID,
85+
EmailNotification: true,
86+
}
87+
88+
if err := s.emailNotifier.Send(event, userPref); err != nil {
89+
log.Printf("Failed to send price alert email: %v", err)
90+
}
91+
}
92+
93+
// Deactivate the alert after triggering
94+
if err := s.alertRepo.DeactivateAlert(alert.ID); err != nil {
95+
log.Printf("Failed to deactivate alert: %v", err)
96+
}
97+
}

0 commit comments

Comments
 (0)