229 lines
5.1 KiB
Go
229 lines
5.1 KiB
Go
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
|
|
}
|