Files
chirpy/internal/server/handlers_webhooks.go
T

90 lines
1.8 KiB
Go
Raw Normal View History

package server
import (
"encoding/json"
"net/http"
"github.com/StevanFreeborn/chirpy/internal/api"
"github.com/StevanFreeborn/chirpy/internal/auth"
"github.com/google/uuid"
)
type userUpgradeData struct {
UserId string `json:"user_id"`
}
type webhookEvent struct {
Event string `json:"event"`
Data any `json:"-"`
}
// UnmarshalJSON captures the raw event data so it can be decoded into the
// concrete type for the event name.
func (p *webhookEvent) UnmarshalJSON(b []byte) error {
type Alias webhookEvent
aux := &struct {
*Alias
RawData json.RawMessage `json:"data"`
}{
Alias: (*Alias)(p),
}
if err := json.Unmarshal(b, aux); err != nil {
return err
}
switch p.Event {
case "user.upgraded":
var data userUpgradeData
if err := json.Unmarshal(aux.RawData, &data); err != nil {
return err
}
p.Data = data
default:
}
return nil
}
// HandleWebhooks processes Polka webhook events, e.g. upgrading a user to
// Chirpy Red.
func (s *Server) HandleWebhooks(w http.ResponseWriter, r *http.Request) {
apiKey, err := auth.GetAPIKey(r.Header)
if err != nil || apiKey != s.polkaKey {
api.WriteError(w, http.StatusUnauthorized, "You are not authorized to perform this action")
return
}
event, err := api.DecodeJSON[webhookEvent](r)
if err != nil {
api.WriteError(w, http.StatusInternalServerError, "Unable to deserialize webhook event")
return
}
switch v := event.Data.(type) {
case userUpgradeData:
validUserId, err := uuid.Parse(v.UserId)
if err != nil {
api.WriteError(w, http.StatusNotFound, "Unable to upgrade user")
return
}
_, err = s.db.UpgradeUser(r.Context(), validUserId)
if err != nil {
api.WriteError(w, http.StatusNotFound, "Unable to upgrade user")
return
}
api.WriteJSON(w, http.StatusNoContent, nil)
default:
api.WriteJSON(w, http.StatusNoContent, nil)
}
}