package main import ( "bufio" "errors" "fmt" "os" "strings" "time" "github.com/nlopes/slack" ) /* DB Functions */ func (m *BotModel) setSlackToken(token string) error { return m.SetBytes([]string{"slack", "config", "token"}, []byte(token)) } func (m *BotModel) getSlackToken() (string, error) { return m.GetString([]string{"slack", "config", "token"}) } func (m *BotModel) setSlackAdminDMId(adminId string) error { return m.SetString([]string{"slack", "config", "admin_dm_id"}, adminId) } func (m *BotModel) GetSlackAdminDMId() (string, error) { return m.GetString([]string{"slack", "config", "admin_dm_id"}) } /* End DB Functions */ func (m *BotModel) NewSlack() error { var err error m.slackApiToken, err = m.getSlackToken() if err != nil { if strings.HasPrefix(err.Error(), "Couldn't find") { m.RequestSlackToken() } else { return err } } var slackDMid string slackDMid, err = m.GetSlackAdminDMId() if err != nil || slackDMid == "" { m.RequestAdminDMId() } m.IncomingSlackMessages = make(chan *slack.MessageEvent, 50) m.OtherRTMEvents = make(chan *slack.RTMEvent, 50) m.slackApi = slack.New(m.slackApiToken) m.slackIdToFriendly = make(map[string]string) m.slackRTM = m.slackApi.NewRTM() m.slackRTMLatency = time.Duration(0) go m.slackRTM.ManageConnection() go m.HandleRTMEvents() return nil } func (m *BotModel) RequestAdminDMId() { reader := bufio.NewReader(os.Stdin) fmt.Print("Slack Admin DM ID: ") dmId, _ := reader.ReadString('\n') m.setSlackAdminDMId(strings.TrimSpace(dmId)) } 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) HandleRTMEvents() { for msg := range m.slackRTM.IncomingEvents { switch ev := msg.Data.(type) { case *slack.MessageEvent: m.processMessageEvent(ev) case *slack.LatencyReport: m.OtherRTMEvents <- &msg case *slack.RTMError: fmt.Printf("RTM ERROR: (%d) %s", ev.Code, ev.Msg) m.OtherRTMEvents <- &msg default: // Ignore other events } } } func (m *BotModel) SendSlackChannelMessage(msg *slack.Message) error { if DebugMode { return m.SendSlackAdminMessage(msg) } // Send message to slack channel m.PostSlackMessage(msg) return nil } func (m *BotModel) SendSlackAdminMessage(msg *slack.Message) error { // Send message to slack admin var err error msg.Channel, err = m.GetSlackAdminDMId() if err != nil { return err } m.PostSlackMessage(msg) return nil } func (m *BotModel) LoadDirectMessages() { cs, err := m.slackApi.GetIMChannels() if err != nil { return } for _, v := range cs { uname, err := m.GetSlackUserName(v.User) if err != nil { uname = v.User } m.slackIdToFriendly[v.ID] = uname } } func (m *BotModel) processMessageEvent(ev *slack.MessageEvent) { m.GetSlackUserName(ev.User) m.GetSlackIdName(ev.Channel) m.IncomingSlackMessages <- ev } func (m *BotModel) GetSlackIdName(id string) (string, error) { switch id[0] { case 'U': return m.GetSlackUserName(id) case 'G': return m.GetSlackGroupName(id) case 'C': return m.GetSlackChannelName(id) case 'D': return m.GetSlackIMName(id) } return "", errors.New("Unknown ID Type") } func (m *BotModel) GetSlackUserName(id string) (string, error) { if v, ok := m.slackIdToFriendly[id]; ok { return v, nil } user, err := m.slackApi.GetUserInfo(id) if err != nil { return "", err } m.slackIdToFriendly[id] = user.Profile.DisplayName return user.Profile.DisplayName, nil } func (m *BotModel) GetSlackIMName(id string) (string, error) { if v, ok := m.slackIdToFriendly[id]; ok { return v, nil } c, err := m.slackApi.GetChannelInfo(id) if err != nil { return "", err } m.slackIdToFriendly[id] = c.Name return c.Name, nil } func (m *BotModel) GetSlackChannelName(id string) (string, error) { if v, ok := m.slackIdToFriendly[id]; ok { return v, nil } c, err := m.slackApi.GetChannelInfo(id) if err != nil { return "", err } m.slackIdToFriendly[id] = c.Name return c.Name, nil } func (m *BotModel) GetSlackUserIM(id string) (string, error) { for k, v := range m.slackIdToFriendly { if v == id { return k, nil } } _, _, newId, err := m.slackApi.OpenIMChannel(id) if err != nil { return "", err } m.slackIdToFriendly[id] = newId return newId, nil } func (m *BotModel) GetSlackGroupName(id string) (string, error) { if v, ok := m.slackIdToFriendly[id]; ok { return v, nil } g, err := m.slackApi.GetGroupInfo(id) if err != nil { return "", err } m.slackIdToFriendly[id] = g.Name return g.Name, nil } func (m *BotModel) PostSlackMessage(msg *slack.Message) { m.slackRTM.SendMessage(m.slackRTM.NewOutgoingMessage(msg.Text, msg.Channel)) } func (m *BotModel) SendMessageToUser(msg *slack.Message, uid string) error { dmId, err := m.GetSlackUserIM(uid) if err != nil { return err } msg.Channel = dmId m.PostSlackMessage(msg) return nil } func (m *BotModel) GetSlackUserInfo(uid string) (*slack.User, error) { return m.slackApi.GetUserInfo(uid) } func (m *BotModel) GetSlackLatency() time.Duration { return m.slackRTMLatency }