From 0b10cdcc7011775860bd3cce0c7aa79a212abb03 Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Thu, 19 Sep 2019 16:30:59 -0400 Subject: [PATCH] slackApp: add reaction logging --- connectors/slackapp/fix_text.go | 10 +-- connectors/slackapp/slackApp.go | 126 +++++++++++++++++++++++--------- go.mod | 12 +-- go.sum | 48 +----------- 4 files changed, 101 insertions(+), 95 deletions(-) diff --git a/connectors/slackapp/fix_text.go b/connectors/slackapp/fix_text.go index a4a7c2f..cdce8d8 100644 --- a/connectors/slackapp/fix_text.go +++ b/connectors/slackapp/fix_text.go @@ -1,7 +1,6 @@ package slackapp import ( - "github.com/nlopes/slack" "unicode/utf8" ) @@ -14,7 +13,7 @@ import ( // • Strips < and > surrounding links. // // This was directly bogarted from velour/chat with emoji conversion removed. -func fixText(findUser func(id string) (*slack.User, error), text string) string { +func fixText(findUser func(id, defaultName string) string, text string) string { var output []rune for len(text) > 0 { r, i := utf8.DecodeRuneInString(text) @@ -49,16 +48,15 @@ func fixText(findUser func(id string) (*slack.User, error), text string) string return string(output) } -func fixTag(findUser func(string) (*slack.User, error), tag []rune) ([]rune, bool) { +func fixTag(findUser func(string, string) string, tag []rune) ([]rune, bool) { switch { case hasPrefix(tag, "@U"): if i := indexRune(tag, '|'); i >= 0 { return tag[i+1:], true } if findUser != nil { - if u, err := findUser(string(tag[1:])); err == nil { - return []rune(u.Name), true - } + u := findUser(string(tag[1:]), "unknown") + return []rune(u), true } return tag, true diff --git a/connectors/slackapp/slackApp.go b/connectors/slackapp/slackApp.go index 07b9a8d..edca675 100644 --- a/connectors/slackapp/slackApp.go +++ b/connectors/slackapp/slackApp.go @@ -28,7 +28,8 @@ import ( "github.com/velour/catbase/config" ) -const DefaultRing = 5 +const DefaultIDRing = 10 +const DefaultMsgRing = 50 const defaultLogFormat = "[{{fixDate .Time \"2006-01-02 15:04:05\"}}] {{if .TopicChange}}*** {{.User.Name}}{{else if .Action}}* {{.User.Name}}{{else}}<{{.User.Name}}>{{end}} {{.Body}}\n" // 11:10AM DBG connectors/slackapp/slackApp.go:496 > Slack event dir=logs raw={"Action":false,"AdditionalData": @@ -58,6 +59,7 @@ type SlackApp struct { event bot.Callback msgIDBuffer *ring.Ring + msgBuffer *ring.Ring logFormat *template.Template } @@ -73,17 +75,11 @@ func New(c *config.Config) *SlackApp { api := slack.New(token, slack.OptionDebug(false)) - idBuf := ring.New(c.GetInt("ringSize", DefaultRing)) - for i := 0; i < idBuf.Len(); i++ { - idBuf.Value = "" - idBuf = idBuf.Next() - } - - tplTxt := c.GetString("slackapp.log.format", defaultLogFormat) + tplTxt := c.GetString("slackapp.logMessage.format", defaultLogFormat) funcs := template.FuncMap{ "fixDate": fixDate, } - tpl := template.Must(template.New("log").Funcs(funcs).Parse(tplTxt)) + tpl := template.Must(template.New("logMessage").Funcs(funcs).Parse(tplTxt)) return &SlackApp{ api: api, @@ -96,7 +92,8 @@ func New(c *config.Config) *SlackApp { users: make(map[string]*slack.User), emoji: make(map[string]string), channels: make(map[string]*slack.Channel), - msgIDBuffer: idBuf, + msgIDBuffer: ring.New(c.GetInt("idRingSize", DefaultIDRing)), + msgBuffer: ring.New(c.GetInt("msgRingSize", DefaultMsgRing)), logFormat: tpl, } } @@ -130,12 +127,22 @@ func (s *SlackApp) Serve() error { } else if eventsAPIEvent.Type == slackevents.CallbackEvent { innerEvent := eventsAPIEvent.InnerEvent switch ev := innerEvent.Data.(type) { + case *slackevents.MessageAction: + log.Debug().Interface("ev", ev).Msg("MessageAction") + case *slackevents.MessageActionResponse: + log.Debug().Interface("ev", ev).Msg("MessageActionResponse") case *slackevents.AppMentionEvent: // This is a bit of a problem. AppMentionEvent also needs to // End up in msgReceived //s.msgReceivd(ev) case *slackevents.MessageEvent: s.msgReceivd(ev) + case *slack.ReactionAddedEvent: + s.reactionReceived(ev) + default: + log.Debug(). + Interface("ev", ev). + Msg("Unknown CallbackEvent") } } else { log.Debug(). @@ -152,6 +159,9 @@ func (s *SlackApp) Serve() error { func (s *SlackApp) checkRingOrAdd(ts string) bool { found := false s.msgIDBuffer.Do(func(p interface{}) { + if p == nil { + return + } if p.(string) == ts { found = true } @@ -193,7 +203,7 @@ func (s *SlackApp) msgReceivd(msg *slackevents.MessageEvent) { Msg("Ignoring message") return } - if err := s.log(m); err != nil { + if err := s.logMessage(m); err != nil { log.Fatal().Err(err).Msg("Error logging message") } if !isItMe && msg.ThreadTimeStamp == "" { @@ -209,6 +219,9 @@ func (s *SlackApp) msgReceivd(msg *slackevents.MessageEvent) { Str("text", msg.Text). Msg("Unknown message is hidden") } + + s.msgBuffer.Value = msg + s.msgBuffer = s.msgBuffer.Next() } func (s *SlackApp) Send(kind bot.Kind, args ...interface{}) (string, error) { @@ -407,12 +420,8 @@ func (s *SlackApp) buildMessage(m *slackevents.MessageEvent) msg.Message { isAction := m.SubType == "me_message" // We have to try a few layers to get a valid name for the user because Slack - name := "UNKNOWN" - u, _ := s.getUser(m.User) - if u != nil { - name = u.Profile.DisplayName - } - if m.Username != "" && u == nil { + name := s.getUser(m.User, "unknown") + if m.Username != "" && name == "unknown" { name = m.Username } @@ -459,21 +468,29 @@ func (s *SlackApp) getChannel(id string) (*slack.Channel, error) { return s.channels[id], nil } +func stringForUser(user *slack.User) string { + if user.Profile.DisplayName != "" { + return user.Profile.DisplayName + } + return user.Name +} + // Get username for Slack user ID -func (s *SlackApp) getUser(id string) (*slack.User, error) { - if name, ok := s.users[id]; ok { - return name, nil +func (s *SlackApp) getUser(id, defaultName string) string { + if u, ok := s.users[id]; ok { + return stringForUser(u) } log.Debug(). Str("id", id). Msg("User not already found, requesting info") + u, err := s.api.GetUserInfo(id) if err != nil { - return nil, err + return defaultName } s.users[id] = u - return s.users[id], nil + return stringForUser(u) } // Who gets usernames out of a channel @@ -500,8 +517,8 @@ func (s *SlackApp) Who(id string) []string { ret := []string{} for _, m := range members { - u, err := s.getUser(m) - if err != nil { + u := s.getUser(m, "unknown") + if u != "unknown" { log.Error(). Err(err). Str("user", m). @@ -509,15 +526,14 @@ func (s *SlackApp) Who(id string) []string { continue /**/ } - ret = append(ret, u.Name) + ret = append(ret, u) } return ret } -// log writes to a /.log -// Uses slackapp.log.format to write entries -func (s *SlackApp) log(raw msg.Message) error { - +// logMessage writes to a /.logMessage +// Uses slackapp.logMessage.format to write entries +func (s *SlackApp) logMessage(raw msg.Message) error { // Do some filtering and fixing up front if raw.Body == "" { return nil @@ -536,20 +552,29 @@ func (s *SlackApp) log(raw msg.Message) error { data.TopicChange = true } - dir := path.Join(s.config.Get("slackapp.log.dir", "logs"), raw.ChannelName) + buf := bytes.Buffer{} + if err := s.logFormat.Execute(&buf, data); err != nil { + return err + } + + return s.log(buf.String(), raw.ChannelName) +} + +func (s *SlackApp) log(msg, channel string) error { + dir := path.Join(s.config.Get("slackapp.logMessage.dir", "logs"), channel) now := time.Now() fname := now.Format("20060102") + ".log" path := path.Join(dir, fname) log.Debug(). - Interface("raw", raw). + Interface("raw", msg). Str("dir", dir). Msg("Slack event") if err := os.MkdirAll(dir, 0755); err != nil { log.Error(). Err(err). - Msg("Could not create log directory") + Msg("Could not create logMessage directory") return err } @@ -557,13 +582,46 @@ func (s *SlackApp) log(raw msg.Message) error { if err != nil { log.Fatal(). Err(err). - Msg("Error opening log file") + Msg("Error opening logMessage file") } defer f.Close() - if err := s.logFormat.Execute(f, data); err != nil { + if _, err := fmt.Fprint(f, msg); err != nil { return err } return f.Sync() } + +func (s *SlackApp) reactionReceived(event *slack.ReactionAddedEvent) error { + name := s.getUser(event.User, "unknown") + + ch, err := s.getChannel(event.Item.Channel) + if err != nil { + return err + } + channel := ch.Name + + body := "unknown message" + + // Iterate through the ring and print its contents + s.msgBuffer.Do(func(p interface{}) { + switch m := p.(type) { + case nil: + case *slackevents.MessageEvent: + if m.TimeStamp == event.Item.Timestamp { + u := s.getUser(m.User, "unknown") + body = fmt.Sprintf("%s: %s", u, m.Text) + } + default: + log.Debug().Interface("msg", m).Msg("Unexpected type") + } + }) + + tstamp := slackTStoTime(event.EventTimestamp) + msg := fmt.Sprintf("[%s] <%s> reacted to %s with :%s:\n", + fixDate(tstamp, "2006-01-02 15:04:05"), + name, body, event.Reaction) + + return s.log(msg, channel) +} diff --git a/go.mod b/go.mod index 3cb56db..78e1799 100644 --- a/go.mod +++ b/go.mod @@ -3,20 +3,15 @@ module github.com/velour/catbase require ( github.com/PaulRosset/go-hacknews v0.0.0-20170815075127-4aad99273a3c github.com/PuerkitoBio/goquery v1.5.0 - github.com/ajstarks/svgo v0.0.0-20181006003313-6ce6a3bcf6cd // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff - github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect - github.com/fogleman/gg v1.3.0 // indirect github.com/go-sql-driver/mysql v1.4.1 // indirect - github.com/golang/protobuf v1.3.2 // indirect github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 // indirect github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 // indirect github.com/gorilla/websocket v1.4.0 // indirect github.com/james-bowman/nlp v0.0.0-20190408090549-143ee6f41889 github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7 // indirect github.com/jmoiron/sqlx v1.2.0 - github.com/jung-kurt/gofpdf v1.7.0 // indirect github.com/lib/pq v1.2.0 // indirect github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect @@ -25,7 +20,6 @@ require ( github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect github.com/nlopes/slack v0.5.0 github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 - github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237 // indirect github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d // indirect github.com/rs/zerolog v1.15.0 github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -33,14 +27,10 @@ require ( github.com/stretchr/testify v1.3.0 github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89 github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 - golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect - golang.org/x/mobile v0.0.0-20190806162312-597adff16ade // indirect + golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect - golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect - golang.org/x/tools v0.0.0-20190813142322-97f12d73768f // indirect gonum.org/v1/gonum v0.0.0-20190808205415-ced62fe5104b // indirect gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e // indirect - gonum.org/v1/plot v0.0.0-20190615073203-9aa86143727f // indirect google.golang.org/appengine v1.6.1 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect ) diff --git a/go.sum b/go.sum index fe11ac3..8ebbfb2 100644 --- a/go.sum +++ b/go.sum @@ -6,58 +6,44 @@ github.com/PaulRosset/go-hacknews v0.0.0-20170815075127-4aad99273a3c/go.mod h1:8 github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20181006003313-6ce6a3bcf6cd/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff h1:+TEqaP0eO1unI7XHHFeMDhsxhLDIb0x8KYuZbqbAmxA= github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff/go.mod h1:QCRjR0b4qiJiNjuP7RFM89bh4UExGJalcWmYeSvlnRc= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18= github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M= github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/james-bowman/nlp v0.0.0-20190301165020-c5645f996605 h1:MjLvsJmW4uoTjleqqiL0wKRTjxUakKUhDNoSsSlS2hk= -github.com/james-bowman/nlp v0.0.0-20190301165020-c5645f996605/go.mod h1:kixuaexEqWB+mHZNysgnb6mqgGIT25WvD1/tFRRt0J0= github.com/james-bowman/nlp v0.0.0-20190408090549-143ee6f41889 h1:VYwE/yKDYXpd5hno5fCCWv2wPcM37DYAX4r3Re1pLz8= github.com/james-bowman/nlp v0.0.0-20190408090549-143ee6f41889/go.mod h1:kixuaexEqWB+mHZNysgnb6mqgGIT25WvD1/tFRRt0J0= -github.com/james-bowman/sparse v0.0.0-20190309194602-7d83420cfcbe h1:UFAsFuH6cu/0Lx+qBWfxiO69jrPkvdbG3qwSWI/7yF0= -github.com/james-bowman/sparse v0.0.0-20190309194602-7d83420cfcbe/go.mod h1:G6EcQnwZKsWtItoaQHd+FHPPk6bDeYVJSeeSP9Sge+I= github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7 h1:ph/BDQQDL41apnHSN48I5GyNOQXXAlc79HwGqDSXCss= github.com/james-bowman/sparse v0.0.0-20190423065201-80c6877364c7/go.mod h1:G6EcQnwZKsWtItoaQHd+FHPPk6bDeYVJSeeSP9Sge+I= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jung-kurt/gofpdf v1.7.0/go.mod h1:s/VXv+TdctEOx2wCEguezYaR7f0OwUAd6H9VGfRkcSs= github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU= github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0= -github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 h1:iOAVXzZyXtW408TMYejlUPo6BIn92HmOacWtIfNyYns= -github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= +github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mmcdole/gofeed v1.0.0-beta2 h1:CjQ0ADhAwNSb08zknAkGOEYqr8zfZKfrzgk9BxpWP2E= @@ -66,33 +52,23 @@ github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/ github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8= github.com/nlopes/slack v0.5.0 h1:NbIae8Kd0NpqaEI3iUrsuS0KbcEDhzhc939jLW5fNm0= github.com/nlopes/slack v0.5.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM= -github.com/olebedev/when v0.0.0-20190131080308-164b69386514 h1:xpZutaUgtGPKT2JFaH72/yby908QS9ORlnrAkkdJ4m0= -github.com/olebedev/when v0.0.0-20190131080308-164b69386514/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0= github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 h1:JYoQR67E1vv1WGoeW8DkdFs7vrIEe/5wP+qJItd5tUE= github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0= -github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4= github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.12.0 h1:aqZ1XRadoS8IBknR5IDFvGzbHly1X9ApIqOroooQF/c= -github.com/rs/zerolog v1.12.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89 h1:3D3M900hEBJJAqyKl70QuRHi5weX9+ptlQI1v+FNcQ8= @@ -103,31 +79,21 @@ github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxt golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190321205749-f0864edee7f3 h1:Ep4L2ibjtJcW6IP73KbcJAU0cpNKsLNSSP2jE1xlCys= -golang.org/x/exp v0.0.0-20190321205749-f0864edee7f3/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190806162312-597adff16ade/go.mod h1:AlhUtkH4DA4asiFC5RgK7ZKmauvtkAVcy9L0epCzlWo= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190606173856-1492cefac77f h1:IWHgpgFqnL5AhBUBZSgBdjl2vkQUEzcY+JNKWfcgAU0= -golang.org/x/net v0.0.0-20190606173856-1492cefac77f/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -135,7 +101,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -146,21 +111,16 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190813142322-97f12d73768f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20190325211145-e42c1265cdd5 h1:tyvqqvbB9Sn6UPjokEzsK6cCE9k4Tx/AHGGaJiLIk7g= -gonum.org/v1/gonum v0.0.0-20190325211145-e42c1265cdd5/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.0.0-20190808205415-ced62fe5104b h1:wlZ2AJblZitrh7dfm5OX2WenXLBZCuWqUeNczop2lPA= gonum.org/v1/gonum v0.0.0-20190808205415-ced62fe5104b/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -gonum.org/v1/plot v0.0.0-20190615073203-9aa86143727f/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=