mirror of
https://github.com/idanoo/autobrr
synced 2025-07-22 16:29:12 +00:00
feat(notifications): add Shoutrrr support (#1326)
This commit is contained in:
parent
3dd1629a3f
commit
57a91bb99a
9 changed files with 149 additions and 31 deletions
4
go.mod
4
go.mod
|
@ -60,7 +60,9 @@ require (
|
|||
github.com/anacrolix/missinggo/v2 v2.7.2 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/containrrr/shoutrrr v0.8.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/gdm85/go-rencode v0.1.8 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
|
@ -76,7 +78,7 @@ require (
|
|||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
|
|
6
go.sum
6
go.sum
|
@ -121,6 +121,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
|
||||
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cytec/releaseparser v0.0.0-20200706155913-2341b265c370 h1:g9q5BGfDdhcXn4EmVZD8UydPXrvhSvgz3FRBn7zAJNs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -145,6 +147,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
|||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ergochat/irc-go v0.4.0 h1:0YibCKfAAtwxQdNjLQd9xpIEPisLcJ45f8FNsMHAuZc=
|
||||
github.com/ergochat/irc-go v0.4.0/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
|
@ -309,6 +313,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
|||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
|
|
|
@ -82,6 +82,7 @@ const (
|
|||
NotificationTypeGotify NotificationType = "GOTIFY"
|
||||
NotificationTypeNtfy NotificationType = "NTFY"
|
||||
NotificationTypeLunaSea NotificationType = "LUNASEA"
|
||||
NotificationTypeShoutrrr NotificationType = "SHOUTRRR"
|
||||
)
|
||||
|
||||
type NotificationEvent string
|
||||
|
|
|
@ -124,16 +124,20 @@ func (s *service) registerSenders() {
|
|||
switch n.Type {
|
||||
case domain.NotificationTypeDiscord:
|
||||
s.senders = append(s.senders, NewDiscordSender(s.log, n))
|
||||
case domain.NotificationTypeNotifiarr:
|
||||
s.senders = append(s.senders, NewNotifiarrSender(s.log, n))
|
||||
case domain.NotificationTypeTelegram:
|
||||
s.senders = append(s.senders, NewTelegramSender(s.log, n))
|
||||
case domain.NotificationTypePushover:
|
||||
s.senders = append(s.senders, NewPushoverSender(s.log, n))
|
||||
case domain.NotificationTypeGotify:
|
||||
s.senders = append(s.senders, NewGotifySender(s.log, n))
|
||||
case domain.NotificationTypeLunaSea:
|
||||
s.senders = append(s.senders, NewLunaSeaSender(s.log, n))
|
||||
case domain.NotificationTypeNotifiarr:
|
||||
s.senders = append(s.senders, NewNotifiarrSender(s.log, n))
|
||||
case domain.NotificationTypeNtfy:
|
||||
s.senders = append(s.senders, NewNtfySender(s.log, n))
|
||||
case domain.NotificationTypePushover:
|
||||
s.senders = append(s.senders, NewPushoverSender(s.log, n))
|
||||
case domain.NotificationTypeShoutrrr:
|
||||
s.senders = append(s.senders, NewShoutrrrSender(s.log, n))
|
||||
case domain.NotificationTypeTelegram:
|
||||
s.senders = append(s.senders, NewTelegramSender(s.log, n))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,18 +245,20 @@ func (s *service) Test(ctx context.Context, notification domain.Notification) er
|
|||
switch notification.Type {
|
||||
case domain.NotificationTypeDiscord:
|
||||
agent = NewDiscordSender(s.log, notification)
|
||||
case domain.NotificationTypeNotifiarr:
|
||||
agent = NewNotifiarrSender(s.log, notification)
|
||||
case domain.NotificationTypeTelegram:
|
||||
agent = NewTelegramSender(s.log, notification)
|
||||
case domain.NotificationTypePushover:
|
||||
agent = NewPushoverSender(s.log, notification)
|
||||
case domain.NotificationTypeGotify:
|
||||
agent = NewGotifySender(s.log, notification)
|
||||
case domain.NotificationTypeNtfy:
|
||||
agent = NewNtfySender(s.log, notification)
|
||||
case domain.NotificationTypeLunaSea:
|
||||
agent = NewLunaSeaSender(s.log, notification)
|
||||
case domain.NotificationTypeNotifiarr:
|
||||
agent = NewNotifiarrSender(s.log, notification)
|
||||
case domain.NotificationTypeNtfy:
|
||||
agent = NewNtfySender(s.log, notification)
|
||||
case domain.NotificationTypePushover:
|
||||
agent = NewPushoverSender(s.log, notification)
|
||||
case domain.NotificationTypeShoutrrr:
|
||||
agent = NewShoutrrrSender(s.log, notification)
|
||||
case domain.NotificationTypeTelegram:
|
||||
agent = NewTelegramSender(s.log, notification)
|
||||
default:
|
||||
s.log.Error().Msgf("unsupported notification type: %v", notification.Type)
|
||||
return errors.New("unsupported notification type")
|
||||
|
|
69
internal/notification/shoutrrr.go
Normal file
69
internal/notification/shoutrrr.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package notification
|
||||
|
||||
import (
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
|
||||
"github.com/containrrr/shoutrrr"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type shoutrrrSender struct {
|
||||
log zerolog.Logger
|
||||
Settings domain.Notification
|
||||
builder NotificationBuilderPlainText
|
||||
}
|
||||
|
||||
func NewShoutrrrSender(log zerolog.Logger, settings domain.Notification) domain.NotificationSender {
|
||||
return &shoutrrrSender{
|
||||
log: log.With().Str("sender", "shoutrrr").Logger(),
|
||||
Settings: settings,
|
||||
builder: NotificationBuilderPlainText{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *shoutrrrSender) Send(event domain.NotificationEvent, payload domain.NotificationPayload) error {
|
||||
message := s.builder.BuildBody(payload)
|
||||
|
||||
if err := shoutrrr.Send(s.Settings.Host, message); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.log.Debug().Msg("notification successfully sent to via shoutrrr")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *shoutrrrSender) CanSend(event domain.NotificationEvent) bool {
|
||||
if s.isEnabled() && s.isEnabledEvent(event) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *shoutrrrSender) isEnabled() bool {
|
||||
if s.Settings.Enabled {
|
||||
if s.Settings.Host == "" {
|
||||
s.log.Warn().Msg("shoutrrr missing host")
|
||||
return false
|
||||
}
|
||||
|
||||
if s.Settings.Token == "" {
|
||||
s.log.Warn().Msg("shoutrrr missing application token")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *shoutrrrSender) isEnabledEvent(event domain.NotificationEvent) bool {
|
||||
for _, e := range s.Settings.Events {
|
||||
if e == string(event) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -390,30 +390,34 @@ export const NotificationTypeOptions: OptionBasicTyped<NotificationType>[] = [
|
|||
label: "Discord",
|
||||
value: "DISCORD"
|
||||
},
|
||||
{
|
||||
label: "Notifiarr",
|
||||
value: "NOTIFIARR"
|
||||
},
|
||||
{
|
||||
label: "Telegram",
|
||||
value: "TELEGRAM"
|
||||
},
|
||||
{
|
||||
label: "Pushover",
|
||||
value: "PUSHOVER"
|
||||
},
|
||||
{
|
||||
label: "Gotify",
|
||||
value: "GOTIFY"
|
||||
},
|
||||
{
|
||||
label: "LunaSea",
|
||||
value: "LUNASEA"
|
||||
},
|
||||
{
|
||||
label: "Notifiarr",
|
||||
value: "NOTIFIARR"
|
||||
},
|
||||
{
|
||||
label: "Ntfy",
|
||||
value: "NTFY"
|
||||
},
|
||||
{
|
||||
label: "LunaSea",
|
||||
value: "LUNASEA"
|
||||
}
|
||||
label: "Pushover",
|
||||
value: "PUSHOVER"
|
||||
},
|
||||
{
|
||||
label: "Shoutrrr",
|
||||
value: "SHOUTRRR"
|
||||
},
|
||||
{
|
||||
label: "Telegram",
|
||||
value: "TELEGRAM"
|
||||
},
|
||||
];
|
||||
|
||||
export const IrcAuthMechanismTypeOptions: OptionBasicTyped<IrcAuthMechanism>[] = [
|
||||
|
|
|
@ -239,6 +239,34 @@ function FormFieldsNtfy() {
|
|||
);
|
||||
}
|
||||
|
||||
function FormFieldsShoutrrr() {
|
||||
return (
|
||||
<div className="border-t border-gray-200 dark:border-gray-700 py-4">
|
||||
<div className="px-4 space-y-1">
|
||||
<Dialog.Title className="text-lg font-medium text-gray-900 dark:text-white">Settings</Dialog.Title>
|
||||
</div>
|
||||
|
||||
<TextFieldWide
|
||||
name="host"
|
||||
label="URL"
|
||||
help="URL"
|
||||
tooltip={
|
||||
<div><p>See full documentation </p>
|
||||
<ExternalLink
|
||||
href="https://containrrr.dev/shoutrrr/services/overview/"
|
||||
className="font-medium text-blue-500 underline underline-offset-1 hover:text-blue-400"
|
||||
>
|
||||
Services
|
||||
</ExternalLink>
|
||||
</div>
|
||||
}
|
||||
placeholder="smtp://username:password@host:port/?from=fromAddress&to=recipient1"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const componentMap: componentMapType = {
|
||||
DISCORD: <FormFieldsDiscord />,
|
||||
NOTIFIARR: <FormFieldsNotifiarr />,
|
||||
|
@ -246,6 +274,7 @@ const componentMap: componentMapType = {
|
|||
PUSHOVER: <FormFieldsPushover />,
|
||||
GOTIFY: <FormFieldsGotify />,
|
||||
NTFY: <FormFieldsNtfy />,
|
||||
SHOUTRRR: <FormFieldsShoutrrr />,
|
||||
LUNASEA: <FormFieldsLunaSea />
|
||||
};
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ const iconComponentMap: componentMapType = {
|
|||
PUSHOVER: <span className={iconStyle}><PushoverIcon /> Pushover</span>,
|
||||
GOTIFY: <span className={iconStyle}><GotifyIcon /> Gotify</span>,
|
||||
NTFY: <span className={iconStyle}><NtfyIcon /> ntfy</span>,
|
||||
SHOUTRRR: <span className={iconStyle}><NtfyIcon /> Shoutrrr</span>,
|
||||
LUNASEA: <span className={iconStyle}><LunaSeaIcon /> LunaSea</span>
|
||||
};
|
||||
|
||||
|
|
2
web/src/types/Notification.d.ts
vendored
2
web/src/types/Notification.d.ts
vendored
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
type NotificationType = "DISCORD" | "NOTIFIARR" | "TELEGRAM" | "PUSHOVER" | "GOTIFY" | "NTFY" | "LUNASEA";
|
||||
type NotificationType = "DISCORD" | "NOTIFIARR" | "TELEGRAM" | "PUSHOVER" | "GOTIFY" | "NTFY" | "LUNASEA" | "SHOUTRRR";
|
||||
type NotificationEvent =
|
||||
"PUSH_APPROVED"
|
||||
| "PUSH_REJECTED"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue