diff --git a/server/README.md b/server/README.md index e94ad88..2faf648 100644 --- a/server/README.md +++ b/server/README.md @@ -88,6 +88,17 @@ This demo implementation sends back whether or not the plugin hooks are currentl is used by the web app to recover from a network reconnection and synchronize the state of the plugin's hooks. +It also implements a receiver for outgoing webhooks. To utilize that, create an Outgoing Webhook +using the following configuration: +- Title: Choose as you want +- Content Type: `application/json` +- Channel: Pick any channel +- Callback URLs: `http://localhost:8065/plugins/com.mattermost.demo-plugin/webhook/outgoing` + +Leave the rest of the fields with their default value. + +Now post a message in the selected channel. You will see a webhook response, which contains the payload the plugin received. + ## [message_hooks.go](message_hooks.go) ### MessageWillBePosted diff --git a/server/http_hooks.go b/server/http_hooks.go index d6363e9..ba2f56d 100644 --- a/server/http_hooks.go +++ b/server/http_hooks.go @@ -32,6 +32,10 @@ func (p *Plugin) initializeAPI() { router.HandleFunc("/dynamic_arg_test_url", p.handleDynamicArgTest) router.HandleFunc("/check_auth_header", p.handleCheckAuthHeader) + webhook := router.PathPrefix("/webhook").Subrouter() + webhook.Use(p.withDelay) + webhook.HandleFunc("/outgoing", p.handleOutgoingWebhook).Methods(http.MethodPost) + interativeRouter := router.PathPrefix("/interactive").Subrouter() interativeRouter.Use(p.withDelay) interativeRouter.HandleFunc("/button/1", p.handleInteractiveAction) @@ -103,6 +107,30 @@ func (p *Plugin) handleCheckAuthHeader(w http.ResponseWriter, r *http.Request) { } } +func (p *Plugin) handleOutgoingWebhook(w http.ResponseWriter, r *http.Request) { + var request model.OutgoingWebhookPayload + err := json.NewDecoder(r.Body).Decode(&request) + if err != nil { + p.API.LogError("Failed to decode OutgoingWebhookPayload", "err", err) + w.WriteHeader(http.StatusBadRequest) + return + } + defer r.Body.Close() + + s, err := PrettyJSON(request) + if err != nil { + p.API.LogError("Failed to Marshal payload back to JSON", "err", err.Error()) + return + } + + text := "```\n" + s + "\n```" + resp := model.OutgoingWebhookResponse{ + Text: &text, + } + + p.writeJSON(w, resp) +} + func (p *Plugin) handleDialog1(w http.ResponseWriter, r *http.Request) { var request model.SubmitDialogRequest err := json.NewDecoder(r.Body).Decode(&request) diff --git a/server/utils.go b/server/utils.go new file mode 100644 index 0000000..edf8e0d --- /dev/null +++ b/server/utils.go @@ -0,0 +1,13 @@ +package main + +import ( + "encoding/json" +) + +func PrettyJSON(in interface{}) (string, error) { + bb, err := json.MarshalIndent(in, "", " ") + if err != nil { + return "", err + } + return string(bb), nil +}