summaryrefslogtreecommitdiffstats
path: root/hook/rockethook
diff options
context:
space:
mode:
Diffstat (limited to 'hook/rockethook')
-rw-r--r--hook/rockethook/rockethook.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/hook/rockethook/rockethook.go b/hook/rockethook/rockethook.go
new file mode 100644
index 00000000..eafd4f43
--- /dev/null
+++ b/hook/rockethook/rockethook.go
@@ -0,0 +1,108 @@
+package rockethook
+
+import (
+ "crypto/tls"
+ "encoding/json"
+ "io/ioutil"
+ "log"
+ "net"
+ "net/http"
+)
+
+// Message for rocketchat outgoing webhook.
+type Message struct {
+ Token string `json:"token"`
+ ChannelID string `json:"channel_id"`
+ ChannelName string `json:"channel_name"`
+ Timestamp string `json:"timestamp"`
+ UserID string `json:"user_id"`
+ UserName string `json:"user_name"`
+ Text string `json:"text"`
+}
+
+// Client for Rocketchat.
+type Client struct {
+ In chan Message
+ httpclient *http.Client
+ Config
+}
+
+// Config for client.
+type Config struct {
+ BindAddress string // Address to listen on
+ Token string // Only allow this token from Rocketchat. (Allow everything when empty)
+ InsecureSkipVerify bool // disable certificate checking
+}
+
+// New Rocketchat client.
+func New(url string, config Config) *Client {
+ c := &Client{In: make(chan Message), Config: config}
+ tr := &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify},
+ }
+ c.httpclient = &http.Client{Transport: tr}
+ _, _, err := net.SplitHostPort(c.BindAddress)
+ if err != nil {
+ log.Fatalf("incorrect bindaddress %s", c.BindAddress)
+ }
+ 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...\n", c.BindAddress)
+ if err := http.ListenAndServe(c.BindAddress, 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 := Message{}
+ body, err := ioutil.ReadAll(r.Body)
+ log.Println(string(body))
+ if err != nil {
+ log.Println(err)
+ http.NotFound(w, r)
+ return
+ }
+ defer r.Body.Close()
+ err = json.Unmarshal(body, &msg)
+ 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
+ }
+ msg.ChannelName = "#" + msg.ChannelName
+ 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() Message {
+ for {
+ select {
+ case msg := <-c.In:
+ return msg
+ }
+ }
+}