mirror of
https://github.com/hanzoui/registry-backend.git
synced 2026-10-30 20:30:45 +00:00
97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package discord
|
|
|
|
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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// 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 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")
|
|
}
|
|
|
|
body, err := json.Marshal(discordRequestBody{Content: msg})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req, err := http.NewRequest(http.MethodPost, discordWebhookURL, bytes.NewBuffer(body))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 400 {
|
|
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
|
|
}
|