package rest import ( "context" "encoding/json" "fmt" "net/http" "gitea.dwysokinski.me/Kichiyaki/notificationarr/internal/domain" "github.com/go-chi/chi/v5" ) //counterfeiter:generate -o internal/mock/sonarr_service.gen.go . SonarrService type SonarrService interface { Process(ctx context.Context, payload domain.SonarrWebhookPayload) error } type WebhookHandler struct { sonarrSvc SonarrService } func NewWebhookHandler(sonarrSvc SonarrService) *WebhookHandler { return &WebhookHandler{ sonarrSvc: sonarrSvc, } } func (h *WebhookHandler) Register(r chi.Router) { r.Post("/webhook/sonarr", h.handleSonarrWebhook) } type SonarrSeries struct { ID int64 `json:"id"` Title string `json:"title"` } type SonarrEpisode struct { ID int64 `json:"id"` EpisodeNumber int16 `json:"episodeNumber"` SeasonNumber int16 `json:"seasonNumber"` Title string `json:"title"` } type SonarrWebhookRequest struct { EventType string `json:"eventType"` Series SonarrSeries `json:"series"` Episodes []SonarrEpisode `json:"episodes"` } func (h *WebhookHandler) handleSonarrWebhook(w http.ResponseWriter, r *http.Request) { var req SonarrWebhookRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { renderErrorResponse(w, domain.NewError( domain.WithErr(err), domain.WithCode(domain.ErrorCodeValidation), domain.WithMessage("invalid request body"), )) return } eventType, err := domain.NewSonarrEventType(req.EventType) if err != nil { renderErrorResponse(w, fmt.Errorf("domain.NewSonarrEventType: %w", err)) return } payload := domain.SonarrWebhookPayload{ EventType: eventType, Series: domain.SonarrSeries{ ID: req.Series.ID, Title: req.Series.Title, }, Episodes: make([]domain.SonarrEpisode, 0, len(req.Episodes)), } for _, ep := range req.Episodes { payload.Episodes = append(payload.Episodes, domain.SonarrEpisode{ ID: ep.ID, EpisodeNumber: ep.EpisodeNumber, SeasonNumber: ep.SeasonNumber, Title: ep.Title, }) } if err := h.sonarrSvc.Process(r.Context(), payload); err != nil { renderErrorResponse(w, fmt.Errorf("SonarrService.Process: %w", err)) return } w.WriteHeader(http.StatusNoContent) }