Skip to content

Commit

Permalink
Add NoOp DiscordService Implemnetation for staging/dev environments (#…
Browse files Browse the repository at this point in the history
…106)

Co-authored-by: James Kwon <[email protected]>
  • Loading branch information
james03160927 and james03160927 authored Jan 1, 2025
1 parent 5126abf commit 4d8f856
Showing 1 changed file with 36 additions and 17 deletions.
53 changes: 36 additions & 17 deletions gateways/discord/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,55 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/rs/zerolog/log"
"net/http"
"registry-backend/config"
)

// DiscordService defines the interface for interacting with Discord notifications.
type DiscordService interface {
SendSecurityCouncilMessage(msg string, private bool) error
}

type DripDiscordService struct {
// Ensure discordService struct implements DiscordService interface
var _ DiscordService = (*discordService)(nil)

// discordService struct holds the configuration and webhook URLs.
type discordService struct {
securityDiscordChannelWebhook string
securityDiscordPrivateChannelWebhook string
config *config.Config
}

func NewDiscordService(config *config.Config) *DripDiscordService {
return &DripDiscordService{
config: config,
securityDiscordChannelWebhook: config.DiscordSecurityChannelWebhook,
securityDiscordPrivateChannelWebhook: config.DiscordSecurityPrivateChannelWebhook,
// NewDiscordService creates a new Discord service using the provided config or returns a no-op implementation if the config is missing.
func NewDiscordService(cfg *config.Config) DiscordService {
if cfg == nil || cfg.DiscordSecurityChannelWebhook == "" || cfg.DiscordSecurityPrivateChannelWebhook == "" {
log.Info().Msg("No Discord configuration found, using no-op implementation")
return &discordNoop{}
}

return &discordService{
config: cfg,
securityDiscordChannelWebhook: cfg.DiscordSecurityChannelWebhook,
securityDiscordPrivateChannelWebhook: cfg.DiscordSecurityPrivateChannelWebhook,
}
}

type discordRequestBody struct {
Content string `json:"content"`
}

func (s *DripDiscordService) SendSecurityCouncilMessage(msg string, private bool) error {
if s.config.DripEnv == "prod" {
webhookURL := s.securityDiscordChannelWebhook
if private {
webhookURL = s.securityDiscordPrivateChannelWebhook
}
return sendDiscordNotification(msg, webhookURL)
} else {
println("Skipping sending message to Discord in non-prod environment. " + msg)
// SendSecurityCouncilMessage sends a message to the appropriate Discord channel.
func (s *discordService) SendSecurityCouncilMessage(msg string, private bool) error {
webhookURL := s.securityDiscordChannelWebhook
if private {
webhookURL = s.securityDiscordPrivateChannelWebhook
}
return nil

return sendDiscordNotification(msg, webhookURL)
}

// sendDiscordNotification sends the message to the provided Discord webhook URL.
func sendDiscordNotification(msg string, discordWebhookURL string) error {
if discordWebhookURL == "" {
return fmt.Errorf("no Discord webhook URL provided, skipping sending message to Discord")
Expand All @@ -69,9 +79,18 @@ func sendDiscordNotification(msg string, discordWebhookURL string) error {
defer resp.Body.Close()

if resp.StatusCode >= 400 {
// You can handle or log the HTTP error status code here
return fmt.Errorf("request to Discord returned error status: %d", resp.StatusCode)
}

return nil
}

// discordNoop is a no-op implementation of the DiscordService interface.
// It does nothing and is used when no valid config is provided.
type discordNoop struct{}

// SendSecurityCouncilMessage is a no-op implementation that simply returns nil.
func (s *discordNoop) SendSecurityCouncilMessage(msg string, private bool) error {
log.Info().Msgf("No-op: Skipping Discord message: %s (private: %v)", msg, private)
return nil
}

0 comments on commit 4d8f856

Please sign in to comment.