package main import ( "encoding/json" "log" "net/http" ) type HookPayload[D HookPayloadData] struct { Type string `json:"type"` SigningToken string `json:"signing_token"` SystemID string `json:"system_id"` ID string `json:"id,omitempty"` Data D `json:"data,omitempty"` } type Switch struct { ID string `json:"id"` Timestamp string `json:"timestamp"` Members []string `json:"members"` } type Message struct { ID string `json:"id"` Timestamp string `json:"timestamp"` Member string `json:"member"` } type HookPayloadData interface { Switch | Message | interface{} } type hookHandler[D HookPayloadData] func(h HookPayload[D]) var ( hookHandlers map[string]hookHandler[HookPayloadData] = map[string]hookHandler[HookPayloadData]{ "CREATE_SWITCH": handleHookCreateSwitch, "CREATE_MESSAGE": handleHookCreateMessage, } ) func postGetHookToken(rw http.ResponseWriter, req *http.Request) { if req.Method != "POST" { errMethodNotAllowed(rw) return } var payload HookPayload[HookPayloadData] err := json.NewDecoder(req.Body).Decode(&payload) if err != nil { errBadRequest(rw) return } if payload.SigningToken != SigningToken { errUnauthorized(rw) return } if payload.Type == "PING" { basicOk(rw) return } handler, ok := hookHandlers[payload.Type] if !ok { basicNoContent(rw) return } go handler(payload) } func handleHookCreateSwitch(h HookPayload[HookPayloadData]) { hook, ok := h.Data.(Switch) if !ok { log.Printf("[handleHookCreateSwitch] could not cast hook payload data to Switch, got: %v\n", h) } log.Printf("[handleHookCreateSwitch] got hook: %v\n", hook) } func handleHookCreateMessage(h HookPayload[HookPayloadData]) { hook, ok := h.Data.(Message) if !ok { log.Printf("[handleHookCreateMessage] could not cast hook payload data to Message, got: %v\n", h) } log.Printf("[handleHookCreateMessage] got hook: %v\n", hook) }