Notifications repository + service (#4565)
* Notifications repository * feat: notifications repo + service * fix: remove use of notifications/notifications.go * Update persistence/notificationsrepository/notificationsrepository.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: remove unused method --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
package notifications
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/owncast/owncast/core/data"
|
||||
"github.com/owncast/owncast/notifications/browser"
|
||||
"github.com/owncast/owncast/notifications/discord"
|
||||
"github.com/owncast/owncast/persistence/configrepository"
|
||||
"github.com/owncast/owncast/persistence/notificationsrepository"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Service defines the interface for notification operations.
|
||||
type Service interface {
|
||||
Notify()
|
||||
}
|
||||
|
||||
// notificationService handles notification dispatching and channel management.
|
||||
type notificationService struct {
|
||||
repository notificationsrepository.NotificationsRepository
|
||||
configRepository configrepository.ConfigRepository
|
||||
browser *browser.Browser
|
||||
discord *discord.Discord
|
||||
}
|
||||
|
||||
// New creates a new instance of the notification service.
|
||||
func New(datastore *data.Datastore) (Service, error) {
|
||||
service := ¬ificationService{
|
||||
repository: notificationsrepository.New(datastore),
|
||||
configRepository: configrepository.Get(),
|
||||
}
|
||||
|
||||
if err := service.setupBrowserPush(datastore); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
if err := service.setupDiscord(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
return service, nil
|
||||
}
|
||||
|
||||
func (s *notificationService) setupBrowserPush(datastore *data.Datastore) error {
|
||||
if s.configRepository.GetBrowserPushConfig().Enabled {
|
||||
publicKey, err := s.configRepository.GetBrowserPushPublicKey()
|
||||
if err != nil || publicKey == "" {
|
||||
return errors.Wrap(err, "browser notifier disabled, failed to get browser push public key")
|
||||
}
|
||||
|
||||
privateKey, err := s.configRepository.GetBrowserPushPrivateKey()
|
||||
if err != nil || privateKey == "" {
|
||||
return errors.Wrap(err, "browser notifier disabled, failed to get browser push private key")
|
||||
}
|
||||
|
||||
browserNotifier, err := browser.New(datastore, publicKey, privateKey)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating browser notifier")
|
||||
}
|
||||
s.browser = browserNotifier
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *notificationService) setupDiscord() error {
|
||||
discordConfig := s.configRepository.GetDiscordConfig()
|
||||
if discordConfig.Enabled && discordConfig.Webhook != "" {
|
||||
var image string
|
||||
if serverURL := s.configRepository.GetServerURL(); serverURL != "" {
|
||||
image = serverURL + "/logo"
|
||||
}
|
||||
discordNotifier, err := discord.New(
|
||||
s.configRepository.GetServerName(),
|
||||
image,
|
||||
discordConfig.Webhook,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating discord notifier")
|
||||
}
|
||||
s.discord = discordNotifier
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *notificationService) notifyBrowserPush() {
|
||||
destinations, err := s.repository.GetNotificationDestinationsForChannel(notificationsrepository.BrowserPushNotification)
|
||||
if err != nil {
|
||||
log.Errorln("error getting browser push notification destinations", err)
|
||||
}
|
||||
for _, destination := range destinations {
|
||||
unsubscribed, err := s.browser.Send(destination, s.configRepository.GetServerName(), s.configRepository.GetBrowserPushConfig().GoLiveMessage)
|
||||
if unsubscribed {
|
||||
// If the error is "unsubscribed", then remove the destination from the database.
|
||||
if err := s.repository.RemoveNotificationForChannel(notificationsrepository.BrowserPushNotification, destination); err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
} else if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *notificationService) notifyDiscord() {
|
||||
goLiveMessage := s.configRepository.GetDiscordConfig().GoLiveMessage
|
||||
streamTitle := s.configRepository.GetStreamTitle()
|
||||
if streamTitle != "" {
|
||||
goLiveMessage += "\n" + streamTitle
|
||||
}
|
||||
message := fmt.Sprintf("%s\n\n%s", goLiveMessage, s.configRepository.GetServerURL())
|
||||
|
||||
if err := s.discord.Send(message); err != nil {
|
||||
log.Errorln("error sending discord message", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Notify will fire the different notification channels.
|
||||
func (s *notificationService) Notify() {
|
||||
if s.browser != nil {
|
||||
s.notifyBrowserPush()
|
||||
}
|
||||
|
||||
if s.discord != nil {
|
||||
s.notifyDiscord()
|
||||
}
|
||||
}
|
||||
|
||||
// Compile-time verification that notificationService implements Service.
|
||||
var _ Service = (*notificationService)(nil)
|
||||
Reference in New Issue
Block a user