github.com/space0122/mattermost-server@v5.11.1+incompatible/web/webhook.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package web 5 6 import ( 7 "fmt" 8 "io" 9 "net/http" 10 "strings" 11 12 "github.com/gorilla/mux" 13 "github.com/gorilla/schema" 14 15 "github.com/mattermost/mattermost-server/mlog" 16 "github.com/mattermost/mattermost-server/model" 17 ) 18 19 func (w *Web) InitWebhooks() { 20 w.MainRouter.Handle("/hooks/commands/{id:[A-Za-z0-9]+}", w.NewHandler(commandWebhook)).Methods("POST") 21 w.MainRouter.Handle("/hooks/{id:[A-Za-z0-9]+}", w.NewHandler(incomingWebhook)).Methods("POST") 22 } 23 24 func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) { 25 params := mux.Vars(r) 26 id := params["id"] 27 28 r.ParseForm() 29 30 var err *model.AppError 31 incomingWebhookPayload := &model.IncomingWebhookRequest{} 32 contentType := r.Header.Get("Content-Type") 33 if strings.Split(contentType, "; ")[0] == "application/x-www-form-urlencoded" { 34 payload := strings.NewReader(r.FormValue("payload")) 35 36 incomingWebhookPayload, err = decodePayload(payload) 37 if err != nil { 38 c.Err = err 39 return 40 } 41 } else if strings.HasPrefix(contentType, "multipart/form-data") { 42 r.ParseMultipartForm(0) 43 44 decoder := schema.NewDecoder() 45 err := decoder.Decode(incomingWebhookPayload, r.PostForm) 46 47 if err != nil { 48 c.Err = model.NewAppError("incomingWebhook", "api.webhook.incoming.error", nil, err.Error(), http.StatusBadRequest) 49 return 50 } 51 } else { 52 incomingWebhookPayload, err = decodePayload(r.Body) 53 if err != nil { 54 c.Err = err 55 return 56 } 57 } 58 59 if *c.App.Config().LogSettings.EnableWebhookDebugging { 60 mlog.Debug(fmt.Sprintf("Incoming webhook received. Id=%s Content=%s", id, incomingWebhookPayload.ToJson())) 61 } 62 63 err = c.App.HandleIncomingWebhook(id, incomingWebhookPayload) 64 if err != nil { 65 c.Err = err 66 return 67 } 68 69 w.Header().Set("Content-Type", "text/plain") 70 w.Write([]byte("ok")) 71 } 72 73 func commandWebhook(c *Context, w http.ResponseWriter, r *http.Request) { 74 params := mux.Vars(r) 75 id := params["id"] 76 77 response, err := model.CommandResponseFromHTTPBody(r.Header.Get("Content-Type"), r.Body) 78 if err != nil { 79 c.Err = model.NewAppError("commandWebhook", "web.command_webhook.parse.app_error", nil, err.Error(), http.StatusBadRequest) 80 return 81 } 82 83 appErr := c.App.HandleCommandWebhook(id, response) 84 if appErr != nil { 85 c.Err = appErr 86 return 87 } 88 89 w.Header().Set("Content-Type", "text/plain") 90 w.Write([]byte("ok")) 91 } 92 93 func decodePayload(payload io.Reader) (*model.IncomingWebhookRequest, *model.AppError) { 94 incomingWebhookPayload, decodeError := model.IncomingWebhookRequestFromJson(payload) 95 96 if decodeError != nil { 97 return nil, decodeError 98 } 99 100 return incomingWebhookPayload, nil 101 }