summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/42wim/matterbridge/matterhook/matterhook.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/42wim/matterbridge/matterhook/matterhook.go')
-rw-r--r--vendor/github.com/42wim/matterbridge/matterhook/matterhook.go154
1 files changed, 154 insertions, 0 deletions
diff --git a/vendor/github.com/42wim/matterbridge/matterhook/matterhook.go b/vendor/github.com/42wim/matterbridge/matterhook/matterhook.go
new file mode 100644
index 00000000..0b023d39
--- /dev/null
+++ b/vendor/github.com/42wim/matterbridge/matterhook/matterhook.go
@@ -0,0 +1,154 @@
+//Package matterhook provides interaction with mattermost incoming/outgoing webhooks
+package matterhook
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "github.com/gorilla/schema"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "strconv"
+)
+
+// OMessage for mattermost incoming webhook. (send to mattermost)
+type OMessage struct {
+ Channel string `json:"channel,omitempty"`
+ IconURL string `json:"icon_url,omitempty"`
+ IconEmoji string `json:"icon_emoji,omitempty"`
+ UserName string `json:"username,omitempty"`
+ Text string `json:"text"`
+ Attachments interface{} `json:"attachments,omitempty"`
+ Type string `json:"type,omitempty"`
+}
+
+// IMessage for mattermost outgoing webhook. (received from mattermost)
+type IMessage struct {
+ Token string `schema:"token"`
+ TeamID string `schema:"team_id"`
+ TeamDomain string `schema:"team_domain"`
+ ChannelID string `schema:"channel_id"`
+ ServiceID string `schema:"service_id"`
+ ChannelName string `schema:"channel_name"`
+ Timestamp string `schema:"timestamp"`
+ UserID string `schema:"user_id"`
+ UserName string `schema:"user_name"`
+ Text string `schema:"text"`
+ TriggerWord string `schema:"trigger_word"`
+}
+
+// Client for Mattermost.
+type Client struct {
+ Url string // URL for incoming webhooks on mattermost.
+ In chan IMessage
+ Out chan OMessage
+ httpclient *http.Client
+ Config
+}
+
+// Config for client.
+type Config struct {
+ Port int // Port to listen on.
+ BindAddress string // Address to listen on
+ Token string // Only allow this token from Mattermost. (Allow everything when empty)
+ InsecureSkipVerify bool // disable certificate checking
+ DisableServer bool // Do not start server for outgoing webhooks from Mattermost.
+}
+
+// New Mattermost client.
+func New(url string, config Config) *Client {
+ c := &Client{Url: url, In: make(chan IMessage), Out: make(chan OMessage), Config: config}
+ if c.Port == 0 {
+ c.Port = 9999
+ }
+ c.BindAddress += ":"
+ tr := &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify},
+ }
+ c.httpclient = &http.Client{Transport: tr}
+ if !c.DisableServer {
+ go c.StartServer()
+ }
+ return c
+}
+
+// StartServer starts a webserver listening for incoming mattermost POSTS.
+func (c *Client) StartServer() {
+ mux := http.NewServeMux()
+ mux.Handle("/", c)
+ log.Printf("Listening on http://%v:%v...\n", c.BindAddress, c.Port)
+ if err := http.ListenAndServe((c.BindAddress + strconv.Itoa(c.Port)), mux); err != nil {
+ log.Fatal(err)
+ }
+}
+
+// ServeHTTP implementation.
+func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ log.Println("invalid " + r.Method + " connection from " + r.RemoteAddr)
+ http.NotFound(w, r)
+ return
+ }
+ msg := IMessage{}
+ err := r.ParseForm()
+ if err != nil {
+ log.Println(err)
+ http.NotFound(w, r)
+ return
+ }
+ defer r.Body.Close()
+ decoder := schema.NewDecoder()
+ err = decoder.Decode(&msg, r.PostForm)
+ if err != nil {
+ log.Println(err)
+ http.NotFound(w, r)
+ return
+ }
+ if msg.Token == "" {
+ log.Println("no token from " + r.RemoteAddr)
+ http.NotFound(w, r)
+ return
+ }
+ if c.Token != "" {
+ if msg.Token != c.Token {
+ log.Println("invalid token " + msg.Token + " from " + r.RemoteAddr)
+ http.NotFound(w, r)
+ return
+ }
+ }
+ c.In <- msg
+}
+
+// Receive returns an incoming message from mattermost outgoing webhooks URL.
+func (c *Client) Receive() IMessage {
+ for {
+ select {
+ case msg := <-c.In:
+ return msg
+ }
+ }
+}
+
+// Send sends a msg to mattermost incoming webhooks URL.
+func (c *Client) Send(msg OMessage) error {
+ buf, err := json.Marshal(msg)
+ if err != nil {
+ return err
+ }
+ resp, err := c.httpclient.Post(c.Url, "application/json", bytes.NewReader(buf))
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ // Read entire body to completion to re-use keep-alive connections.
+ io.Copy(ioutil.Discard, resp.Body)
+
+ if resp.StatusCode != 200 {
+ return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
+ }
+ return nil
+}