From 3ea43c2f152f56b15dfa8400782d28db96596729 Mon Sep 17 00:00:00 2001 From: Nayyara Airlangga Date: Thu, 30 May 2024 00:55:12 +0700 Subject: [PATCH 1/4] feat: add support for string or array of strings in yaml --- cmd/brassite/main.go | 14 ++++++++------ configuration.go | 28 ++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/cmd/brassite/main.go b/cmd/brassite/main.go index e8a5c6d..7c0676c 100644 --- a/cmd/brassite/main.go +++ b/cmd/brassite/main.go @@ -196,12 +196,14 @@ func runWorker(feed brassite.Feed) { } // Deliver to Discord - if feed.Delivery.DiscordWebhookUrl != "" { - err := brassite.DeliverToDiscord(ctx, feed.Delivery.DiscordWebhookUrl, feedItem, feed.Logo) - if err != nil { - slog.Error("Failed to deliver to Discord", slog.String("feed_name", feed.Name), slog.Any("error", err)) - - sentry.CaptureException(err) + if len(feed.Delivery.DiscordWebhookUrl.Values) > 0 { + for _, url := range feed.Delivery.DiscordWebhookUrl.Values { + err := brassite.DeliverToDiscord(ctx, url, feedItem, feed.Logo) + if err != nil { + slog.Error("Failed to deliver to Discord", slog.String("feed_name", feed.Name), slog.Any("error", err)) + + sentry.CaptureException(err) + } } } diff --git a/configuration.go b/configuration.go index eb65ff1..46551a2 100644 --- a/configuration.go +++ b/configuration.go @@ -58,13 +58,37 @@ type BasicAuth struct { type Delivery struct { // Discord webhook URL - DiscordWebhookUrl string `json:"discord_webhook_url" yaml:"discord_webhook_url" toml:"discord_webhook_url"` + DiscordWebhookUrl DiscordWebhookUrl `json:"discord_webhook_url" yaml:"discord_webhook_url" toml:"discord_webhook_url"` // Telegram bot token TelegramBotToken string `json:"telegram_bot_token" yaml:"telegram_bot_token" toml:"telegram_bot_token"` // Telegram chat ID TelegramChatId string `json:"telegram_chat_id" yaml:"telegram_chat_id" toml:"telegram_chat_id"` } +type DiscordWebhookUrl struct { + Values []string +} + +// References: https://github.com/go-yaml/yaml/issues/100 +// +// Custom unmarshaller to support reading a field as string or array of strings +func (d *DiscordWebhookUrl) UnmarshalYAML(unmarshal func(any) error) error { + var multi []string + err := unmarshal(&multi) + if err != nil { + var single string + err := unmarshal(&single) + if err != nil { + return err + } + d.Values = make([]string, 1) + d.Values[0] = single + } else { + d.Values = multi + } + return nil +} + func ParseConfiguration(configPath string) (Configuration, error) { if configPath == "" { return Configuration{}, fmt.Errorf("config path is empty") @@ -130,7 +154,7 @@ func (c Configuration) Validate() (ok bool, issues *ValidationError) { ok = false } } - if feed.Delivery.DiscordWebhookUrl == "" && feed.Delivery.TelegramBotToken == "" { + if len(feed.Delivery.DiscordWebhookUrl.Values) == 0 && feed.Delivery.TelegramBotToken == "" { issues.AddIssue(fmt.Sprintf("feeds.%d.delivery", i), "at least one delivery method is required (otherwise what's the point?)") ok = false } From 3aaa4077d48e555a55bc7b91d9fe1255f439921c Mon Sep 17 00:00:00 2001 From: Nayyara Airlangga Date: Thu, 30 May 2024 01:16:43 +0700 Subject: [PATCH 2/4] feat: add support for string or array of strings in json --- configuration.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/configuration.go b/configuration.go index 46551a2..b5567aa 100644 --- a/configuration.go +++ b/configuration.go @@ -89,6 +89,23 @@ func (d *DiscordWebhookUrl) UnmarshalYAML(unmarshal func(any) error) error { return nil } +func (d *DiscordWebhookUrl) UnmarshalJSON(data []byte) error { + var multi []string + err := json5.Unmarshal(data, &multi) + if err != nil { + var single string + err := json5.Unmarshal(data, &single) + if err != nil { + return err + } + d.Values = make([]string, 1) + d.Values[0] = single + } else { + d.Values = multi + } + return nil +} + func ParseConfiguration(configPath string) (Configuration, error) { if configPath == "" { return Configuration{}, fmt.Errorf("config path is empty") From e816f4e125633b27a3d8c83441b3e76b5a88c3b3 Mon Sep 17 00:00:00 2001 From: Nayyara Airlangga Date: Thu, 30 May 2024 01:52:30 +0700 Subject: [PATCH 3/4] feat: add support for string or array of strings in toml --- configuration.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configuration.go b/configuration.go index b5567aa..49f220c 100644 --- a/configuration.go +++ b/configuration.go @@ -106,6 +106,25 @@ func (d *DiscordWebhookUrl) UnmarshalJSON(data []byte) error { return nil } +func (d *DiscordWebhookUrl) UnmarshalTOML(data any) error { + multi, ok := data.([]any) + if ok { + var multiStrs []string + for _, item := range multi { + str, _ := item.(string) + multiStrs = append(multiStrs, str) + } + d.Values = multiStrs + return nil + } else if single, ok := data.(string); ok { + d.Values = make([]string, 1) + d.Values[0] = single + return nil + } + + return fmt.Errorf("provided %T, expected string or []string", data) +} + func ParseConfiguration(configPath string) (Configuration, error) { if configPath == "" { return Configuration{}, fmt.Errorf("config path is empty") From 3e4e11f693a238fd9321738d1cf9c0319a9e0e4d Mon Sep 17 00:00:00 2001 From: Nayyara Airlangga Date: Thu, 30 May 2024 03:08:59 +0700 Subject: [PATCH 4/4] fix: improve error message for toml invalid webhook url --- configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.go b/configuration.go index 49f220c..a365f4d 100644 --- a/configuration.go +++ b/configuration.go @@ -122,7 +122,7 @@ func (d *DiscordWebhookUrl) UnmarshalTOML(data any) error { return nil } - return fmt.Errorf("provided %T, expected string or []string", data) + return fmt.Errorf("the value %v is not a string or []string", data) } func ParseConfiguration(configPath string) (Configuration, error) {