79 lines
2.3 KiB
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)
|
|
}
|