Skip to content

Commit

Permalink
Allow configuring notification client
Browse files Browse the repository at this point in the history
  • Loading branch information
ahobsonsayers committed Oct 7, 2024
1 parent f05460c commit ab8ca61
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 20 deletions.
12 changes: 11 additions & 1 deletion cmd/twitchets/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (c Config) Validate() error {
return nil
}

func (c Config) CombineGlobalAndTicketConfig() []TicketConfig {
func (c Config) CombineGlobalAndTicketConfig() []TicketConfig { // nolint: revive // TODO Remove nolint
combinedConfigs := make([]TicketConfig, 0, len(c.TicketsConfig))
for _, ticketConfig := range c.TicketsConfig {

Expand Down Expand Up @@ -77,6 +77,16 @@ func (c Config) CombineGlobalAndTicketConfig() []TicketConfig {
combinedConfig.Discount = ticketConfig.Discount
}

// Set notification methods
if ticketConfig.Notification == nil {
combinedConfig.Notification = c.GlobalConfig.Notification
if len(combinedConfig.Notification) == 0 {
combinedConfig.Notification = NotificationTypes.Members()
}
} else {
combinedConfig.Notification = ticketConfig.Notification
}

combinedConfigs = append(combinedConfigs, combinedConfig)
}

Expand Down
29 changes: 25 additions & 4 deletions cmd/twitchets/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
)

func TestLoadConfig(t *testing.T) {
func TestLoadConfig(t *testing.T) { // nolint: revive
configPath := testutils.ProjectDirectoryJoin(t, "test", "testdata", "config", "config.yaml")
actualConfig, err := config.Load(configPath)
require.NoError(t, err)
Expand Down Expand Up @@ -69,21 +69,27 @@ func TestLoadConfig(t *testing.T) {
Event: "Event 5",
Discount: lo.ToPtr(15.0),
},
{
// Ticket with notification set
Event: "Event 6",
Notification: []config.NotificationType{config.NotificationTypeNtfy},
},
{
// Ticket with globals unset
Event: "Event 6",
Event: "Event 7",
EventSimilarity: lo.ToPtr(-1.0),
Regions: []twickets.Region{},
NumTickets: lo.ToPtr(-1),
Discount: lo.ToPtr(-1.0),
Notification: []config.NotificationType{},
},
},
}

require.EqualValues(t, expectedConfig, actualConfig)
}

func TestCombineConfigs(t *testing.T) {
func TestCombineConfigs(t *testing.T) { // nolint: revive
configPath := testutils.ProjectDirectoryJoin(t, "test", "testdata", "config", "config.yaml")
conf, err := config.Load(configPath)
require.NoError(t, err)
Expand All @@ -103,6 +109,7 @@ func TestCombineConfigs(t *testing.T) {
Regions: globalRegions,
NumTickets: &globalNumTickets,
Discount: &globalDiscount,
Notification: config.NotificationTypes.Members(),
},
{
// Ticket with event similarity set
Expand All @@ -111,6 +118,7 @@ func TestCombineConfigs(t *testing.T) {
Regions: globalRegions,
NumTickets: &globalNumTickets,
Discount: &globalDiscount,
Notification: config.NotificationTypes.Members(),
},
{
// Ticket with regions set
Expand All @@ -119,6 +127,7 @@ func TestCombineConfigs(t *testing.T) {
Regions: []twickets.Region{twickets.RegionSouthWest},
NumTickets: &globalNumTickets,
Discount: &globalDiscount,
Notification: config.NotificationTypes.Members(),
},
{
// Ticket with num tickets set
Expand All @@ -127,6 +136,7 @@ func TestCombineConfigs(t *testing.T) {
Regions: globalRegions,
NumTickets: lo.ToPtr(1),
Discount: &globalDiscount,
Notification: config.NotificationTypes.Members(),
},
{
// Ticket with discount set
Expand All @@ -135,14 +145,25 @@ func TestCombineConfigs(t *testing.T) {
Regions: globalRegions,
NumTickets: &globalNumTickets,
Discount: lo.ToPtr(15.0),
Notification: config.NotificationTypes.Members(),
},
{
// Ticket with globals unset
// Ticket with notification set
Event: "Event 6",
EventSimilarity: &globalEventSimilarity,
Regions: globalRegions,
NumTickets: &globalNumTickets,
Discount: &globalDiscount,
Notification: []config.NotificationType{config.NotificationTypeNtfy},
},
{
// Ticket with globals unset
Event: "Event 7",
EventSimilarity: nil,
Regions: []twickets.Region{},
NumTickets: nil,
Discount: nil,
Notification: []config.NotificationType{},
},
}

Expand Down
9 changes: 5 additions & 4 deletions cmd/twitchets/config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import "github.com/ahobsonsayers/twitchets/twickets"
// unless an event explicitly overwrites its.
// Country is required.
type GlobalEventConfig struct {
EventSimilarity float64 `json:"eventSimilarity"`
Regions []twickets.Region `json:"regions"`
NumTickets int `json:"numTickets"`
Discount float64 `json:"discount"`
EventSimilarity float64 `json:"eventSimilarity"`
Regions []twickets.Region `json:"regions"`
NumTickets int `json:"numTickets"`
Discount float64 `json:"discount"`
Notification []NotificationType `json:"notification"`
}

func (c GlobalEventConfig) Validate() error {
Expand Down
50 changes: 46 additions & 4 deletions cmd/twitchets/config/notification.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,73 @@
package config

import (
"encoding/json"
"fmt"

"github.com/ahobsonsayers/twitchets/cmd/twitchets/notification"
"github.com/orsinium-labs/enum"
)

type NotificationType enum.Member[string]

var (
notificationType = enum.NewBuilder[string, NotificationType]()

NotificationTypeNtfy = notificationType.Add(NotificationType{"ntfy"})
NotificationTypeTelegram = notificationType.Add(NotificationType{"telegram"})

NotificationTypes = notificationType.Enum()
)

func (c *NotificationType) UnmarshalJSON(data []byte) error {
var notificationTypeString string
err := json.Unmarshal(data, &notificationTypeString)
if err != nil {
return err
}

notificationType := NotificationTypes.Parse(notificationTypeString)
if notificationType == nil {
return fmt.Errorf("notificationType '%s' is not valid", notificationTypeString)
}

*c = *notificationType
return nil
}

func (c *NotificationType) UnmarshalText(data []byte) error {
notificationTypeString := string(data)
notificationType := NotificationTypes.Parse(notificationTypeString)
if notificationType == nil {
return fmt.Errorf("notificationType '%s' is not valid", notificationTypeString)
}

*c = *notificationType
return nil
}

type NotificationConfig struct {
Ntfy *notification.NtfyConfig `json:"ntfy"`
Telegram *notification.TelegramConfig `json:"telegram"`
}

func (c NotificationConfig) Clients() ([]notification.Client, error) {
clients := []notification.Client{}
func (c NotificationConfig) Clients() (map[NotificationType]notification.Client, error) {
clients := map[NotificationType]notification.Client{}

if c.Ntfy != nil {
ntfyClient, err := notification.NewNtfyClient(*c.Ntfy)
if err != nil {
return nil, err
}
clients = append(clients, ntfyClient)
clients[NotificationTypeNtfy] = ntfyClient
}

if c.Telegram != nil {
telegramClient, err := notification.NewTelegramClient(*c.Telegram)
if err != nil {
return nil, err
}
clients = append(clients, telegramClient)
clients[NotificationTypeTelegram] = telegramClient
}

return clients, nil
Expand Down
17 changes: 12 additions & 5 deletions cmd/twitchets/config/ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
)

type TicketConfig struct {
Event string `json:"event"`
EventSimilarity *float64 `json:"eventSimilarity"`
Regions []twickets.Region `json:"regions"`
NumTickets *int `json:"numTickets"`
Discount *float64 `json:"discount"`
Event string `json:"event"`
EventSimilarity *float64 `json:"eventSimilarity"`
Regions []twickets.Region `json:"regions"`
NumTickets *int `json:"numTickets"`
Discount *float64 `json:"discount"`
Notification []NotificationType `json:"notification"`
}

func (t TicketConfig) Validate() error {
Expand All @@ -26,6 +27,12 @@ func (t TicketConfig) Validate() error {
}
}

for _, notification := range t.Notification {
if !NotificationTypes.Contains(notification) {
return fmt.Errorf("notification type '%s' is not valid", notification)
}
}

return nil
}

Expand Down
10 changes: 8 additions & 2 deletions cmd/twitchets/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func main() {
func fetchAndProcessTickets(
twicketsClient *twickets.Client,
conf config.Config,
notificationClients []notification.Client,
notificationClients map[config.NotificationType]notification.Client,
) {
checkTime := time.Now()
defer func() {
Expand Down Expand Up @@ -120,7 +120,13 @@ func fetchAndProcessTickets(
"link", ticket.Link(),
)

for _, notificationClient := range notificationClients {
for _, notificationType := range ticketConfig.Notification {

notificationClient, ok := notificationClients[notificationType]
if !ok {
continue
}

err := notificationClient.SendTicketNotification(ticket)
if err != nil {
slog.Error(
Expand Down
16 changes: 16 additions & 0 deletions test/testdata/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,33 @@ global:
discount: 25

tickets:
# Ticket with only event set
- event: Event 1

# Ticket with name similarity set
- event: Event 2
eventSimilarity: 90

# Ticket with regions set
- event: Event 3
regions: [GBSW]

# Ticket with num tickets set
- event: Event 4
numTickets: 1

# Ticket with discount set
- event: Event 5
discount: 15

# Ticket with notification set
- event: Event 6
notification: [ntfy]

# Ticket with globals unset
- event: Event 7
eventSimilarity: -1
regions: []
numTickets: -1
discount: -1
notification: []

0 comments on commit ab8ca61

Please sign in to comment.