notifications.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package notifications
  2. import (
  3. "fmt"
  4. "github.com/owncast/owncast/config"
  5. "github.com/owncast/owncast/core/data"
  6. "github.com/owncast/owncast/models"
  7. "github.com/owncast/owncast/notifications/browser"
  8. "github.com/owncast/owncast/notifications/discord"
  9. "github.com/pkg/errors"
  10. log "github.com/sirupsen/logrus"
  11. )
  12. // Notifier is an instance of the live stream notifier.
  13. type Notifier struct {
  14. datastore *data.Datastore
  15. browser *browser.Browser
  16. discord *discord.Discord
  17. }
  18. // Setup will perform any pre-use setup for the notifier.
  19. func Setup(datastore *data.Datastore) {
  20. createNotificationsTable(datastore.DB)
  21. initializeBrowserPushIfNeeded()
  22. }
  23. func initializeBrowserPushIfNeeded() {
  24. pubKey, _ := data.GetBrowserPushPublicKey()
  25. privKey, _ := data.GetBrowserPushPrivateKey()
  26. // We need browser push keys so people can register for pushes.
  27. if pubKey == "" || privKey == "" {
  28. browserPrivateKey, browserPublicKey, err := browser.GenerateBrowserPushKeys()
  29. if err != nil {
  30. log.Errorln("unable to initialize browser push notification keys", err)
  31. }
  32. if err := data.SetBrowserPushPrivateKey(browserPrivateKey); err != nil {
  33. log.Errorln("unable to set browser push private key", err)
  34. }
  35. if err := data.SetBrowserPushPublicKey(browserPublicKey); err != nil {
  36. log.Errorln("unable to set browser push public key", err)
  37. }
  38. }
  39. // Enable browser push notifications by default.
  40. if !data.GetHasPerformedInitialNotificationsConfig() {
  41. _ = data.SetBrowserPushConfig(models.BrowserNotificationConfiguration{Enabled: true, GoLiveMessage: config.GetDefaults().FederationGoLiveMessage})
  42. _ = data.SetHasPerformedInitialNotificationsConfig(true)
  43. }
  44. }
  45. // New creates a new instance of the Notifier.
  46. func New(datastore *data.Datastore) (*Notifier, error) {
  47. notifier := Notifier{
  48. datastore: datastore,
  49. }
  50. if err := notifier.setupBrowserPush(); err != nil {
  51. log.Error(err)
  52. }
  53. if err := notifier.setupDiscord(); err != nil {
  54. log.Error(err)
  55. }
  56. return &notifier, nil
  57. }
  58. func (n *Notifier) setupBrowserPush() error {
  59. if data.GetBrowserPushConfig().Enabled {
  60. publicKey, err := data.GetBrowserPushPublicKey()
  61. if err != nil || publicKey == "" {
  62. return errors.Wrap(err, "browser notifier disabled, failed to get browser push public key")
  63. }
  64. privateKey, err := data.GetBrowserPushPrivateKey()
  65. if err != nil || privateKey == "" {
  66. return errors.Wrap(err, "browser notifier disabled, failed to get browser push private key")
  67. }
  68. browserNotifier, err := browser.New(n.datastore, publicKey, privateKey)
  69. if err != nil {
  70. return errors.Wrap(err, "error creating browser notifier")
  71. }
  72. n.browser = browserNotifier
  73. }
  74. return nil
  75. }
  76. func (n *Notifier) notifyBrowserPush() {
  77. destinations, err := GetNotificationDestinationsForChannel(BrowserPushNotification)
  78. if err != nil {
  79. log.Errorln("error getting browser push notification destinations", err)
  80. }
  81. for _, destination := range destinations {
  82. unsubscribed, err := n.browser.Send(destination, data.GetServerName(), data.GetBrowserPushConfig().GoLiveMessage)
  83. if unsubscribed {
  84. // If the error is "unsubscribed", then remove the destination from the database.
  85. if err := RemoveNotificationForChannel(BrowserPushNotification, destination); err != nil {
  86. log.Errorln(err)
  87. }
  88. } else if err != nil {
  89. log.Errorln(err)
  90. }
  91. }
  92. }
  93. func (n *Notifier) setupDiscord() error {
  94. discordConfig := data.GetDiscordConfig()
  95. if discordConfig.Enabled && discordConfig.Webhook != "" {
  96. var image string
  97. if serverURL := data.GetServerURL(); serverURL != "" {
  98. image = serverURL + "/logo"
  99. }
  100. discordNotifier, err := discord.New(
  101. data.GetServerName(),
  102. image,
  103. discordConfig.Webhook,
  104. )
  105. if err != nil {
  106. return errors.Wrap(err, "error creating discord notifier")
  107. }
  108. n.discord = discordNotifier
  109. }
  110. return nil
  111. }
  112. func (n *Notifier) notifyDiscord() {
  113. goLiveMessage := data.GetDiscordConfig().GoLiveMessage
  114. streamTitle := data.GetStreamTitle()
  115. if streamTitle != "" {
  116. goLiveMessage += "\n" + streamTitle
  117. }
  118. message := fmt.Sprintf("%s\n\n%s", goLiveMessage, data.GetServerURL())
  119. if err := n.discord.Send(message); err != nil {
  120. log.Errorln("error sending discord message", err)
  121. }
  122. }
  123. // Notify will fire the different notification channels.
  124. func (n *Notifier) Notify() {
  125. if n.browser != nil {
  126. n.notifyBrowserPush()
  127. }
  128. if n.discord != nil {
  129. n.notifyDiscord()
  130. }
  131. }