package models import ( "bufio" "fmt" "os" "strings" "time" "github.com/slack-go/slack" "github.com/spf13/viper" ) const ( keyPluginDir = "plugin_dir" keySlackToken = "slack.token" keySlackAdminDmId = "slack.admin_dm_id" ) func (m *BotModel) GetPluginDir() string { return viper.GetString(keyPluginDir) } /* Slack Config Functions */ func (m *BotModel) getSlackToken() string { return viper.GetString(keySlackToken) } func (m *BotModel) setSlackToken(token string) error { viper.Set(keySlackToken, token) return viper.WriteConfig() } func (m *BotModel) GetSlackAdminDMId() string { return viper.GetString(keySlackAdminDmId) } func (m *BotModel) setSlackAdminDMId(adminId string) error { viper.Set(keySlackAdminDmId, adminId) return viper.WriteConfig() } func (m *BotModel) requestSlackToken() { reader := bufio.NewReader(os.Stdin) fmt.Print("Slack Token: ") token, _ := reader.ReadString('\n') m.slackApiToken = strings.TrimSpace(token) m.setSlackToken(m.slackApiToken) } func (m *BotModel) requestAdminDMId() { reader := bufio.NewReader(os.Stdin) fmt.Print("Slack Admin DM ID: ") dmId, _ := reader.ReadString('\n') m.setSlackAdminDMId(strings.TrimSpace(dmId)) } /* End Slack Config Functions */ func (m *BotModel) NewSlack() error { var err error m.slackApiToken = m.getSlackToken() if m.slackApiToken == "" { m.requestSlackToken() } slackDmId := m.GetSlackAdminDMId() if slackDmId == "" { m.requestAdminDMId() } m.incomingSlackMessages = make(chan *slack.MessageEvent, 50) m.otherRTMEvents = make(chan *slack.RTMEvent, 50) m.slackApi = slack.New(m.slackApiToken) m.slackRTM = m.slackApi.NewRTM() m.slackRTMLatency = time.Duration(0) go m.slackRTM.ManageConnection() go m.HandleRTMEvents() return err } func (m *BotModel) GetChannelInfo(id string) (*slack.Channel, error) { convInfo := &slack.GetConversationInfoInput{ ChannelID: id, IncludeLocale: false, IncludeNumMembers: false, } return m.slackApi.GetConversationInfo(convInfo) } func (m *BotModel) HandleRTMEvents() { for msg := range m.slackRTM.IncomingEvents { fmt.Printf("RTM Message: %v\n", msg) switch ev := msg.Data.(type) { case *slack.MessageEvent: fmt.Println("RTM Message: Processing Message Event") m.processMessageEvent(ev) case *slack.LatencyReport: fmt.Println("RTM Message: Latency Report") m.otherRTMEvents <- &msg case *slack.RTMError: fmt.Printf("RTM ERROR: (%d) %s\n", ev.Code, ev.Msg) m.otherRTMEvents <- &msg default: // Ignore other events } } } func (m *BotModel) SendSlackAdminMessage(msg string) error { // Send message to slack admin dmId := m.GetSlackAdminDMId() _, _, err := m.slackApi.PostMessage( dmId, slack.MsgOptionText(msg, false), slack.MsgOptionAsUser(true), ) return err } func (m *BotModel) SendSlackChannelMessage(msg string, cid string) error { if m.debug { return m.SendSlackAdminMessage(msg) } _, _, err := m.slackApi.PostMessage( cid, slack.MsgOptionText(msg, false), slack.MsgOptionAsUser(true), ) return err } func (m *BotModel) processMessageEvent(ev *slack.MessageEvent) { m.getSlackUserName(ev.User) m.getSlackChannelName(ev.Channel) m.incomingSlackMessages <- ev } func (m *BotModel) getSlackUserName(id string) (string, error) { user, err := m.slackApi.GetUserInfo(id) if err != nil { return "", err } return user.Profile.DisplayName, nil } func (m *BotModel) getSlackChannelName(id string) (string, error) { c, err := m.GetChannelInfo(id) if err != nil { return "", err } return c.Name, nil } func (m *BotModel) GetSlackLatency() time.Duration { return m.slackRTMLatency } func (m *BotModel) monitorSlackMessages() { for msg := range m.incomingSlackMessages { m.SendMessage(BotMessageFromSlack(slack.Message(*msg))) } }