go-twitch/eventsub/webhook/handler.go

79 lines
2.3 KiB
Go

package webhook
import (
"encoding/json"
"net/http"
"time"
"go.fifitido.net/twitch/api/eventsub"
"go.fifitido.net/twitch/eventsub/webhook/messages"
)
var _ http.Handler = (*Transport)(nil)
// ServeHTTP implements http.Handler.
func (t *Transport) ServeHTTP(w http.ResponseWriter, r *http.Request) {
timestamp, err := time.Parse(time.RFC3339, r.Header.Get("Twitch-Eventsub-Message-Timestamp"))
if err != nil {
http.Error(w, "failed to parse timestamp", http.StatusBadRequest)
return
}
msg := &messages.Message{
Id: r.Header.Get("Twitch-Eventsub-Message-Id"),
Retry: r.Header.Get("Twitch-Eventsub-Message-Retry"),
Type: messages.Type(r.Header.Get("Twitch-Eventsub-Message-Type")),
Signature: r.Header.Get("Twitch-Eventsub-Message-Signature"),
Timestamp: timestamp,
SubscriptionType: &eventsub.SubscriptionType{
Name: r.Header.Get("Twitch-Eventsub-Subscription-Type"),
Version: r.Header.Get("Twitch-Eventsub-Subscription-Version"),
},
}
switch msg.Type {
case messages.TypeNotification:
var payload messages.Notification
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "failed to parse message", http.StatusBadRequest)
return
}
msg.Data = &payload
if t.opts.EventsHandler != nil {
if err := t.opts.EventsHandler.Handle(msg); err != nil {
http.Error(w, "failed to handle message", http.StatusInternalServerError)
return
}
}
case messages.TypeWebhookCallbackVerification:
var payload messages.WebhookCallbackVerification
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "failed to parse message", http.StatusBadRequest)
return
}
msg.Data = &payload
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(payload.Challenge))
w.WriteHeader(http.StatusOK)
return
case messages.TypeRevocation:
var payload messages.Revocation
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "failed to parse message", http.StatusBadRequest)
return
}
msg.Data = &payload
if t.opts.RevocationHandler != nil {
if err := t.opts.RevocationHandler.Handle(); err != nil {
http.Error(w, "failed to handle message", http.StatusInternalServerError)
return
}
}
}
w.WriteHeader(http.StatusNoContent)
}