package webhook import ( "context" "net/http" "time" eventsubapi "go.fifitido.net/twitch/api/eventsub" "go.fifitido.net/twitch/eventsub" ) const ( DefaultAddress = ":8080" ) type Transport struct { ctx context.Context cancel context.CancelFunc opts TransportOptions secret string srv *http.Server } func New(parentCtx context.Context, opts TransportOptions) *Transport { ctx, cancel := context.WithCancel(parentCtx) return &Transport{ ctx: ctx, cancel: cancel, opts: opts, srv: &http.Server{}, } } var _ eventsub.Transport = (*Transport)(nil) // ApiTransport implements eventsub.Transport. func (t *Transport) ApiTransport() *eventsubapi.Transport { return &eventsubapi.Transport{ Method: "webhook", Callback: &t.opts.CallbackURL, Secret: &t.secret, } } // Close implements eventsub.Transport. func (t *Transport) Close() error { t.cancel() return nil } // Run implements eventsub.Transport. func (t *Transport) Run() error { addr := DefaultAddress if t.opts.Address != nil { addr = *t.opts.Address } go func() { if err := http.ListenAndServe(addr, t); err != nil { if err == http.ErrServerClosed { return } panic(err) } }() <-t.ctx.Done() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := t.srv.Shutdown(ctx); err != nil { return err } return nil } // Start implements eventsub.Transport. func (t *Transport) Start() { go func() { if err := t.Run(); err != nil { panic(err) } }() }