This is an example of an HTTP app (source), written in Go and runnable on http://localhost:8081
.
manifest.json
, declares itself an HTTP application, requests permissions, and binds itself to locations in the Mattermost user interface.bindings
function it declares two commands: info
and send
.info
command will post an ephemeral message containing a valid send
command.send
command sends a webhook message to the apps plugin which in turn sends the webhook request to the Hello, webhooks!
app/webhook
endpoint, and responds with an ephemeral message when the webhook is received.To install “Hello, Webhooks” on a locally-running instance of Mattermost follow these steps (go 1.16 is required):
Make sure you have followed the Quick Start Guide prerequisite steps.
git clone https://github.com/mattermost/mattermost-plugin-apps.git
cd mattermost-plugin-apps/examples/go/hello-webhooks
go run .
Run the following Mattermost slash command:
/apps install http http://localhost:8081/manifest.json
Hello, Webhooks!
is an HTTP app. It requests the permissions to act as a System Admin and bot to access the Mattermost REST API. It also requests permissions to receive third-party webhook messages. It binds itself to /
commands.
{
"app_id": "hello-webhooks",
"version": "0.8.0",
"display_name": "Hello, Webhooks!",
"app_type": "http",
"icon": "icon.png",
"homepage_url": "https://github.com/mattermost/mattermost-plugin-apps/examples/go/hello-webhooks",
"requested_permissions": [
"act_as_bot",
"remote_webhooks"
],
"requested_locations": [
"/command"
],
"on_install": {
"path": "/install",
"expand": {
"admin_access_token": "all"
}
},
"http": {
"root_url": "http://localhost:8081"
}
}
The Hello Webhooks!
app creates two commands: /hello-webhooks info | send
.
{
"type": "ok",
"data": [
{
"location": "/command",
"bindings": [
{
"icon": "icon.png",
"label": "hello-webhooks",
"description": "Hello Webhooks App",
"hint": "[ send ]",
"bindings": [
{
"location": "send",
"label": "send",
"call": {
"path": "/send"
}
},
{
"location": "info",
"label": "info",
"call": {
"path": "/info"
}
}
]
}
]
}
]
}
/hello-webhooks info
displays a valid /hello-webhooks send
command constructed with your mattermost-site-url, the path to the hello app webhook endpoint, and a secret.
func info(w http.ResponseWriter, req *http.Request) {
creq := apps.CallRequest{}
json.NewDecoder(req.Body).Decode(&creq)
json.NewEncoder(w).Encode(apps.CallResponse{
Markdown: md.Markdownf("Try `/hello-webhooks send %s`",
creq.Context.MattermostSiteURL+creq.Context.AppPath+apps.PathWebhook+
"/hello"+
"?secret="+creq.Context.App.WebhookSecret),
})
}
The /hello-webhooks send
command from the info
command response will send a webhook message to the apps plugin which verifies the secret and forwards the request to the hello app. The Hello, Webhooks!
app receives the webhook and posts an ephemeral message in Mattermost.
func send(w http.ResponseWriter, req *http.Request) {
creq := apps.CallRequest{}
json.NewDecoder(req.Body).Decode(&creq)
url, _ := creq.Values["url"].(string)
http.Post(
url,
"application/json",
bytes.NewReader([]byte(`"Hello from a webhook!"`)))
json.NewEncoder(w).Encode(apps.CallResponse{
Markdown: "posted a Hello webhook message",
})
}
The following image shows the displayed confirmation message after the webhook is sent using the /hello-webhooks send
command.
// Webhook handler
http.HandleFunc("/webhook/", webhookReceived)
webhookReceived
receives the webhook message and posts a confirmation message in the channel.
func webhookReceived(w http.ResponseWriter, req *http.Request) {
creq := apps.CallRequest{}
json.NewDecoder(req.Body).Decode(&creq)
asBot := appclient.AsBot(creq.Context)
channelID := ""
asBot.KVGet("channel_id", "", &channelID)
asBot.CreatePost(&model.Post{
ChannelId: channelID,
Message: fmt.Sprintf("received webhook, path `%s`, data: `%v`", creq.Path, creq.Values["data"]),
})
json.NewEncoder(w).Encode(apps.CallResponse{Type: apps.CallResponseTypeOK})
}
The following image shows the displayed confirmation message after the webhook is received.