diff --git a/go.mod b/go.mod index 584efe4a..590b8222 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/golang/protobuf v1.4.0 // indirect github.com/google/uuid v1.1.1 // indirect github.com/gorilla/mux v1.7.4 - github.com/gorilla/websocket v1.4.2 // indirect github.com/huandu/xstrings v1.3.1 // indirect github.com/imdario/mergo v0.3.9 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect @@ -27,7 +26,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/rs/xid v1.2.1 github.com/sirupsen/logrus v1.5.0 - github.com/slack-go/slack v0.6.4 + github.com/slack-go/slack v0.7.2 github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/go.sum b/go.sum index aa59beef..5744192e 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -74,7 +76,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -169,8 +170,8 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= -github.com/slack-go/slack v0.6.4 h1:cxOqFgM5RW6mdEyDqAJutFk3qiORK9oHRKi5bPqkY9o= -github.com/slack-go/slack v0.6.4/go.mod h1:sGRjv3w+ERAUMMMbldHObQPBcNSyVB7KLKYfnwUFBfw= +github.com/slack-go/slack v0.7.2 h1:oLy2a2YqrtoHSSxbjRhrtLDGbCKcZJwgbuQ826BWxaI= +github.com/slack-go/slack v0.7.2/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -203,6 +204,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= +github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= diff --git a/remote/slack/helper.go b/remote/slack/helper.go index a99f69b0..fbf1c352 100644 --- a/remote/slack/helper.go +++ b/remote/slack/helper.go @@ -149,16 +149,23 @@ func handleCallBack(api *slack.Client, event slackevents.EventsAPIInnerEvent, bo inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, link, mentioned, user, bot) } // This is an Event shared between RTM and the Events API - case *slack.MemberJoinedChannelEvent: - // get bot rooms - bot.Rooms = getRooms(api) - bot.Log.Debugf("%s has joined the channel %s", bot.Name, bot.Rooms[ev.Channel]) - case *slack.MemberLeftChannelEvent: - // remove room - delete(bot.Rooms, ev.Channel) - bot.Log.Debugf("%s has left the channel %s", bot.Name, bot.Rooms[ev.Channel]) + case *slackevents.MemberJoinedChannelEvent: + // limit to our bot + if ev.User == bot.ID { + // look up channel info, since 'ev' only gives us ID + channel, err := api.GetChannelInfo(ev.Channel) + if err != nil { + bot.Log.Debugf("unable to fetch channel info for channel joined event: %v", err) + } else { + // add the room to the lookup + if bot.Rooms[channel.Name] == "" { + bot.Rooms[channel.Name] = channel.ID + bot.Log.Debugf("Joined new channel. %s(%s) added to lookup", channel.Name, channel.ID) + } + } + } default: - bot.Log.Errorf("getEventsAPIEventHandler: Unrecognized event type: %v", ev) + bot.Log.Debugf("getEventsAPIEventHandler: Unrecognized event type: %v", ev) } } @@ -265,16 +272,39 @@ func getInteractiveComponentRuleHandler(verificationToken string, inputMsgs chan // getRooms - return a map of rooms func getRooms(api *slack.Client) map[string]string { rooms := make(map[string]string) - // get public channels - channels, _ := api.GetChannels(true) - for _, channel := range channels { - rooms[channel.Name] = channel.ID + + // we're getting all channel types by default + // this can be controlled with permission scopes in Slack: + // channels:read, groups:read, im:read, mpim:read + cp := slack.GetConversationsParameters{ + Cursor: "", + ExcludeArchived: "true", + Limit: 1000, // this is the maximum value allowed + Types: []string{"public_channel", "private_channel", "mpim", "im"}, } - // get private channels - groups, _ := api.GetGroups(true) - for _, group := range groups { - rooms[group.Name] = group.ID + + // there's a possibility we need to page through results + // the results, so we're looping until there are no more pages + for { + channels, nc, err := api.GetConversations(&cp) + if err != nil { + break + } + + // populate our channel map + for _, channel := range channels { + rooms[channel.Name] = channel.ID + } + + // no more pages to process? quit the loop + if len(nc) == 0 { + break + } + + // override the cursor + cp.Cursor = nc } + return rooms } @@ -555,11 +585,8 @@ func readFromRTM(rtm *slack.RTM, inputMsgs chan<- models.Message, bot *models.Bo // populate user groups populateUserGroups(bot) bot.Log.Debugf("RTM connection established!") - case *slack.GroupJoinedEvent: + case *slack.ChannelJoinedEvent: // when the bot joins a channel add it to the internal lookup - // NOTE: looks like there is another unsupported event we could use - // Received unmapped event \"member_joined_channel\" - // Maybe watch for an update to slack package for future support if bot.Rooms[ev.Channel.Name] == "" { bot.Rooms[ev.Channel.Name] = ev.Channel.ID bot.Log.Debugf("Joined new channel. %s(%s) added to lookup", ev.Channel.Name, ev.Channel.ID) @@ -574,6 +601,8 @@ func readFromRTM(rtm *slack.RTM, inputMsgs chan<- models.Message, bot *models.Bo if !bot.CLI { bot.Log.Debug("Invalid Authorization. Please double check your Slack token.") } + default: + bot.Log.Debugf("readFromRTM: Unrecognized event type: %v", ev) } } } @@ -609,11 +638,16 @@ func sendChannelMessage(api *slack.Client, channel string, message models.Messag // sendDirectMessage - sends a message back to the user who dm'ed your bot func sendDirectMessage(api *slack.Client, userID string, message models.Message) error { - _, _, imChannelID, err := api.OpenIMChannel(userID) + params := &slack.OpenConversationParameters{ + Users: []string{userID}, + } + + imChannelID, _, _, err := api.OpenConversation(params) if err != nil { return err } - return sendMessage(api, message.IsEphemeral, imChannelID, message.Vars["_user.id"], message.Output, message.ThreadTimestamp, message.Attributes["ws_token"], message.Remotes.Slack.Attachments) + + return sendMessage(api, message.IsEphemeral, imChannelID.ID, message.Vars["_user.id"], message.Output, message.ThreadTimestamp, message.Attributes["ws_token"], message.Remotes.Slack.Attachments) } // sendMessage - does the final send to Slack; adds any Slack-specific message parameters to the message to be sent out