Skip to content

Commit

Permalink
Merge pull request #9 from Teamwork/webhooks
Browse files Browse the repository at this point in the history
Extract and expose webhook handler logic as http.Handler
  • Loading branch information
jrdnull authored May 26, 2020
2 parents e13a0a7 + 637f783 commit d662f16
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,21 @@ import (
"net/http"
)

// WebhookListener receives requests from a Nylas webhook.
// See: https://docs.nylas.com/reference#webhooks
type WebhookListener struct {
clientSecret string
}

// NewWebhookListener returns a new WebhookListener..
func NewWebhookListener(clientSecret string) *WebhookListener {
return &WebhookListener{clientSecret}
}

// Listen for webhooks on the given address.
// The callback will be called for each webhook and a non-nil error will respond
// with a 500 including the error message.
// WebhookHandler returns a new http.Handler for handling Nylas webhooks.
//
// Note: the callback is handled synchronously, so if you need to do slow work
// in response to a webhook return nil and handle it in another routine.
// The X-Nylas-Signature will be verified and any non-nil error returned from fn
// will result in a 500 response with the error message.
//
// When mounting this route it should be called for both GET and POST requests
// to handle the initial webhook setup.
//
// See: https://docs.nylas.com/reference#receiving-notifications
func (l *WebhookListener) Listen(addr string, fn func(WebhookDelta) error) error {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
func WebhookHandler(clientSecret string, fn func(WebhookDelta) error) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
challenge := r.URL.Query().Get("challenge")
if r.Method == http.MethodGet && challenge != "" {
w.Header().Add("Content-Type", "text/plain")
_, _ = io.WriteString(w, challenge)
return
}
Expand All @@ -52,7 +42,7 @@ func (l *WebhookListener) Listen(addr string, fn func(WebhookDelta) error) error
}

signature := r.Header.Get("X-Nylas-Signature")
if err := checkSignature(l.clientSecret, signature, data); err != nil {
if err := checkSignature(clientSecret, signature, data); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
Expand All @@ -73,6 +63,30 @@ func (l *WebhookListener) Listen(addr string, fn func(WebhookDelta) error) error
}
}
})
}

// WebhookListener receives requests from a Nylas webhook.
// See: https://docs.nylas.com/reference#webhooks
type WebhookListener struct {
clientSecret string
}

// NewWebhookListener returns a new WebhookListener..
func NewWebhookListener(clientSecret string) *WebhookListener {
return &WebhookListener{clientSecret}
}

// Listen for webhooks on the given address.
// The callback will be called for each webhook and a non-nil error will respond
// with a 500 including the error message.
//
// Note: the callback is handled synchronously, so if you need to do slow work
// in response to a webhook return nil and handle it in another routine.
//
// See: https://docs.nylas.com/reference#receiving-notifications
func (l *WebhookListener) Listen(addr string, fn func(WebhookDelta) error) error {
mux := http.NewServeMux()
mux.Handle("/", WebhookHandler(l.clientSecret, fn))
return http.ListenAndServe(addr, mux)
}

Expand Down

0 comments on commit d662f16

Please sign in to comment.