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  }