Skip to content

Commit

Permalink
throwaway socketmode test
Browse files Browse the repository at this point in the history
  • Loading branch information
wass3r committed Mar 15, 2021
1 parent e61f5a8 commit 67b09e7
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 57 deletions.
7 changes: 7 additions & 0 deletions core/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ func configureSlackBot(bot *models.Bot) {

bot.SlackToken = token

aToken, err := utils.Substitute(bot.SlackAppToken, map[string]string{})
if err != nil {
bot.Log.Info("Slack App token not found")
}

bot.SlackAppToken = aToken

// Slack verification token
vToken, err := utils.Substitute(bot.SlackVerificationToken, map[string]string{})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions core/remotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func Remotes(inputMsgs chan<- models.Message, rules map[string]models.Rule, bot
Token: bot.SlackToken,
VerificationToken: bot.SlackVerificationToken,
WorkspaceToken: bot.SlackWorkspaceToken,
AppToken: bot.SlackAppToken,
}
// Read messages from Slack
go remoteSlack.Read(inputMsgs, rules, bot)
Expand Down
1 change: 1 addition & 0 deletions models/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Bot struct {
SlackWorkspaceToken string `mapstructure:"slack_workspace_token"`
SlackEventsCallbackPath string `mapstructure:"slack_events_callback_path"`
SlackInteractionsCallbackPath string `mapstructure:"slack_interactions_callback_path"`
SlackAppToken string `mapstructure:"slack_app_token"`
SlackListenerPort string `mapstructure:"slack_listener_port"`
DiscordToken string `mapstructure:"discord_token"`
DiscordServerID string `mapstructure:"discord_server_id"`
Expand Down
149 changes: 95 additions & 54 deletions remote/slack/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/gorilla/mux"
"github.com/slack-go/slack"
"github.com/slack-go/slack/slackevents"
"github.com/slack-go/slack/socketmode"
"github.com/target/flottbot/models"
"github.com/target/flottbot/utils"
)
Expand Down Expand Up @@ -546,66 +547,106 @@ func readFromEventsAPI(api *slack.Client, vToken string, inputMsgs chan<- models
// readFromRTM utilizes the Slack API client to read messages via RTM.
// This method of reading is not preferred and the event-based read should instead be used.
// nolint:gocyclo // needs refactor
func readFromRTM(rtm *slack.RTM, inputMsgs chan<- models.Message, bot *models.Bot) {
go rtm.ManageConnection()
for {
msg := <-rtm.IncomingEvents
switch ev := msg.Data.(type) {
case *slack.MessageEvent:
senderID := ev.User
// Sometimes message events in RTM don't have a User ID?
// Also, only process messages that aren't from the bot itself
if senderID != "" && bot.ID != senderID {
channel := ev.Channel
msgType, err := getMessageType(channel)
if err != nil {
bot.Log.Debug(err.Error())
}
text, mentioned := removeBotMention(ev.Text, bot.ID)
user, err := rtm.GetUserInfo(senderID)
if err != nil && senderID != "" { // we only care if senderID is not empty and there's an error (senderID == "" could be a thread from a message)
bot.Log.Errorf("Did not get Slack user info: %s", err.Error())
func readFromRTM(sm *slack.Client, inputMsgs chan<- models.Message, bot *models.Bot) {
client := socketmode.New(
sm,
socketmode.OptionDebug(true),
)

go func() {
for evt := range client.Events {
switch evt.Type {
case socketmode.EventTypeEventsAPI:
eventsAPIEvent, ok := evt.Data.(slackevents.EventsAPIEvent)
if !ok {
bot.Log.Warnf("Ignored: %+v", evt)

continue
}
timestamp := ev.Timestamp
threadTimestamp := ev.ThreadTimestamp

link, err := rtm.GetPermalink(&slack.PermalinkParameters{Channel: channel, Ts: timestamp})
bot.Log.Debugf("Event received: %+v", eventsAPIEvent)

client.Ack(*evt.Request)

switch eventsAPIEvent.Type {
case slackevents.CallbackEvent:
innerEvent := eventsAPIEvent.InnerEvent
switch ev := innerEvent.Data.(type) {
case *slackevents.MessageEvent:
senderID := ev.User
// Sometimes message events in RTM don't have a User ID?
// Also, only process messages that aren't from the bot itself
if senderID != "" && bot.ID != senderID {
channel := ev.Channel
msgType, err := getMessageType(channel)
if err != nil {
bot.Log.Debug(err.Error())
}
text, mentioned := removeBotMention(ev.Text, bot.ID)
user, err := sm.GetUserInfo(senderID)
if err != nil && senderID != "" { // we only care if senderID is not empty and there's an error (senderID == "" could be a thread from a message)
bot.Log.Errorf("Did not get Slack user info: %s", err.Error())
}
timestamp := ev.TimeStamp
threadTimestamp := ev.ThreadTimeStamp

link, err := sm.GetPermalink(&slack.PermalinkParameters{Channel: channel, Ts: timestamp})
if err != nil {
link = ""
}

inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, link, mentioned, user, bot)
}
// case *slackevents.AppMentionEvent:
// senderID := ev.User

// if senderID != "" && bot.ID != senderID {
// channel := ev.Channel
// msgType, err := getMessageType(channel)
// if err != nil {
// bot.Log.Debug(err.Error())
// }
// text, mentioned := removeBotMention(ev.Text, bot.ID)
// user, err := sm.GetUserInfo(ev.User)
// if err != nil && user != nil { // we only care if senderID is not empty and there's an error (senderID == "" could be a thread from a message)
// bot.Log.Errorf("Did not get Slack user info: %s", err.Error())
// }
// timestamp := ev.TimeStamp
// threadTimestamp := ev.ThreadTimeStamp

// link, err := sm.GetPermalink(&slack.PermalinkParameters{Channel: channel, Ts: timestamp})
// if err != nil {
// link = ""
// }

// inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, link, mentioned, user, bot)

// }
}
default:
bot.Log.Warn("Unsupported Events API event received")
}
case socketmode.EventTypeConnecting:
bot.Log.Info("Connecting to Slack with Socket Mode...")
case socketmode.EventTypeConnectionError:
bot.Log.Error("Connection failed. Retrying later...")
case socketmode.EventTypeConnected:
// populate users
users, err := sm.GetUsers()
if err != nil {
link = ""
bot.Log.Errorf("Unable to get users: %v", err)
}

inputMsgs <- populateMessage(models.NewMessage(), msgType, channel, text, timestamp, threadTimestamp, link, mentioned, user, bot)
populateBotUsers(users, bot)
// populate user groups
populateUserGroups(bot)
bot.Log.Info("Connected to Slack with Socket Mode.")
default:
bot.Log.Errorf("Unexpected event type received: %s", evt.Type)
}
case *slack.ConnectedEvent:
// populate users
users, err := rtm.GetUsers()
if err != nil {
bot.Log.Errorf("Unable to get users: %v", err)
}
populateBotUsers(users, bot)
// populate user groups
populateUserGroups(bot)
bot.Log.Debugf("RTM connection established!")
case *slack.ChannelJoinedEvent:
// when the bot joins a channel add it to the internal lookup
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)
}
case *slack.HelloEvent:
// ignore - this is the very first initial event sent when connecting to Slack
case *slack.RTMError:
bot.Log.Error(ev.Error())
case *slack.ConnectionErrorEvent:
bot.Log.Errorf("RTM connection error: %+v", ev)
case *slack.InvalidAuthEvent:
if !bot.CLI {
bot.Log.Debug("Invalid Authorization. Please double check your Slack token.")
}
default:
bot.Log.Debugf("readFromRTM: Unrecognized event type: %v", ev)
}
}
}()

client.Run()
}

// send - handles the sending logic of a message going to Slack
Expand Down
11 changes: 8 additions & 3 deletions remote/slack/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Client struct {
Token string
VerificationToken string
WorkspaceToken string
AppToken string
}

// validate that Client adheres to remote interface
Expand Down Expand Up @@ -91,10 +92,14 @@ func (c *Client) Read(inputMsgs chan<- models.Message, rules map[string]models.R
}
bot.ID = rat.UserID
readFromEventsAPI(api, c.VerificationToken, inputMsgs, bot)
} else if c.Token != "" {
} else if c.AppToken != "" {
bot.ID = rat.UserID
rtm := api.NewRTM()
readFromRTM(rtm, inputMsgs, bot)
sm := slack.New(
bot.SlackToken,
slack.OptionDebug(true),
slack.OptionAppLevelToken(bot.SlackAppToken),
)
readFromRTM(sm, inputMsgs, bot)
} else {
if !bot.CLI {
bot.Log.Fatal("Did not find either Slack Token or Slack Verification Token. Unable to read from Slack")
Expand Down

0 comments on commit 67b09e7

Please sign in to comment.