func Handler(handler func(*Event) error) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if r := recover(); r != nil {
				w.WriteHeader(http.StatusInternalServerError)
				nodego.ErrorLogger.Printf("%s:\n\n%s\n", r, debug.Stack())
			}
		}()
		defer r.Body.Close()
		var event Event
		if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
			nodego.ErrorLogger.Print("Failed to decode event: ", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if err := handler(&event); err != nil {
			nodego.ErrorLogger.Print(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}
Handler returns http.Handler that parses the body for a function event.
package events
import (
	"encoding/base64"
	"encoding/json"
	"net/http"
	"runtime/debug"
	"time"
	"google.golang.org/api/pubsub/v1"
	"google.golang.org/api/storage/v1"
	"../nodego"
)
type JSTime struct {
	time.Time
}
func (t *JSTime) UnmarshalJSON(b []byte) (err error) {
	if string(b) == `"null"` {
		t.Time = time.Time{}
		return
	}
	t.Time, err = time.Parse(`"2006-01-02T15:04:05.000Z"`, string(b))
	return
}
type EventContext struct {
	EventID   string `json:"eventId"`
	Timestamp JSTime `json:"timestamp"`
	EventType string `json:"eventType"`
	Resource  string `json:"resource"`
}
type Event struct {
	Context EventContext
	Data    json.RawMessage
}
func (e *Event) UnmarshalJSON(b []byte) error {
	raws := map[string]json.RawMessage{}
	if err := json.Unmarshal(b, &raws); err != nil {
		return err
	}
	rawContext, ok := raws["context"]
	if !ok {
		rawContext = b
	}
	if err := json.Unmarshal(rawContext, &e.Context); err != nil {
		return err
	}
	e.Data = raws["data"]
	return nil
}
type PubSubMessage struct {
	pubsub.PubsubMessage
	Data []byte
}
func (e *Event) PubSubMessage() (*PubSubMessage, error) {
	var msg pubsub.PubsubMessage
	if err := json.Unmarshal(e.Data, &msg); err != nil {
		return nil, err
	}
	decoded, err := base64.StdEncoding.DecodeString(msg.Data)
	if err != nil {
		return nil, err
	}
	return &PubSubMessage{
		PubsubMessage: msg,
		Data:          decoded,
	}, nil
}
type StorageObject struct {
	storage.Object
}
func (e *Event) StorageObject() (*StorageObject, error) {
	var obj storage.Object
	if err := json.Unmarshal(e.Data, &obj); err != nil {
		return nil, err
	}
	return &StorageObject{
		Object: obj,
	}, nil
}