lints, dunno about build yet
This commit is contained in:
247
bot/bot.go
Normal file
247
bot/bot.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package sco
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
|
||||
type Bot struct {
|
||||
botName string
|
||||
apiURL string
|
||||
websocketURL string
|
||||
accountEmail string
|
||||
accountPassword string
|
||||
accountFirstname string
|
||||
accountLastname string
|
||||
teamName string
|
||||
logChannelName string
|
||||
client *model.Client4
|
||||
webSocketClient *model.WebSocketClient
|
||||
botUser *model.User
|
||||
botTeam *model.Team
|
||||
debuggingChannel *model.Channel
|
||||
}
|
||||
|
||||
func New(options ...func(s *Bot)) *Bot {
|
||||
b := new(Bot)
|
||||
for _, opt := range options {
|
||||
opt(b)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Bot) Main() {
|
||||
println(b.BotName)
|
||||
|
||||
b.SetupGracefulShutdown()
|
||||
|
||||
b.client = model.NewAPIv4Client(b.apiURL)
|
||||
|
||||
// Lets test to see if the mattermost server is up and running
|
||||
b.MakeSureServerIsRunning()
|
||||
|
||||
// lets attempt to login to the Mattermost server as the bot user
|
||||
// This will set the token required for all future calls
|
||||
// You can get this token with client.AuthToken
|
||||
b.LoginAsTheBotUser()
|
||||
|
||||
// If the bot user doesn't have the correct information lets update his profile
|
||||
b.UpdateTheBotUserIfNeeded()
|
||||
|
||||
// Lets find our bot team
|
||||
b.FindBotTeam()
|
||||
|
||||
// This is an important step. Lets make sure we use the botTeam
|
||||
// for all future web service requests that require a team.
|
||||
//client.SetTeamId(botTeam.Id)
|
||||
|
||||
// Lets create a bot channel for logging debug messages into
|
||||
b.CreateBotDebuggingChannelIfNeeded()
|
||||
b.SendMsgToDebuggingChannel("_"+SAMPLE_NAME+" has **started** running_", "")
|
||||
|
||||
// Lets start listening to some channels via the websocket!
|
||||
b.webSocketClient, err = model.NewWebSocketClient4(b.websocketURL, b.client.AuthToken)
|
||||
if err != nil {
|
||||
println("We failed to connect to the web socket")
|
||||
PrintError(err)
|
||||
}
|
||||
|
||||
b.webSocketClient.Listen()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case resp := <-b.webSocketClient.EventChannel:
|
||||
b.HandleWebSocketResponse(resp)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// You can block forever with
|
||||
select {}
|
||||
}
|
||||
|
||||
func (b *Bot) MakeSureServerIsRunning() {
|
||||
if props, resp := client.GetOldClientConfig(""); resp.Error != nil {
|
||||
println("There was a problem pinging the Mattermost server. Are you sure it's running?")
|
||||
PrintError(resp.Error)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
println("Server detected and is running version " + props["Version"])
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) LoginAsTheBotUser() {
|
||||
if user, resp := client.Login(USER_EMAIL, USER_PASSWORD); resp.Error != nil {
|
||||
println("There was a problem logging into the Mattermost server. Are you sure ran the setup steps from the README.md?")
|
||||
PrintError(resp.Error)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
botUser = user
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) UpdateTheBotUserIfNeeded() {
|
||||
if botUser.FirstName != USER_FIRST || botUser.LastName != USER_LAST || botUser.Username != USER_NAME {
|
||||
botUser.FirstName = USER_FIRST
|
||||
botUser.LastName = USER_LAST
|
||||
botUser.Username = USER_NAME
|
||||
|
||||
if user, resp := client.UpdateUser(botUser); resp.Error != nil {
|
||||
println("We failed to update the Sample Bot user")
|
||||
PrintError(resp.Error)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
botUser = user
|
||||
println("Looks like this might be the first run so we've updated the bots account settings")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) FindBotTeam() {
|
||||
if team, resp := client.GetTeamByName(TEAM_NAME, ""); resp.Error != nil {
|
||||
println("We failed to get the initial load")
|
||||
println("or we do not appear to be a member of the team '" + TEAM_NAME + "'")
|
||||
PrintError(resp.Error)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
botTeam = team
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) CreateBotDebuggingChannelIfNeeded() {
|
||||
if rchannel, resp := client.GetChannelByName(CHANNEL_LOG_NAME, botTeam.Id, ""); resp.Error != nil {
|
||||
println("We failed to get the channels")
|
||||
PrintError(resp.Error)
|
||||
} else {
|
||||
debuggingChannel = rchannel
|
||||
return
|
||||
}
|
||||
|
||||
// Looks like we need to create the logging channel
|
||||
channel := &model.Channel{}
|
||||
channel.Name = CHANNEL_LOG_NAME
|
||||
channel.DisplayName = "Debugging For Sample Bot"
|
||||
channel.Purpose = "This is used as a test channel for logging bot debug messages"
|
||||
channel.Type = model.CHANNEL_OPEN
|
||||
channel.TeamId = botTeam.Id
|
||||
if rchannel, resp := client.CreateChannel(channel); resp.Error != nil {
|
||||
println("We failed to create the channel " + CHANNEL_LOG_NAME)
|
||||
PrintError(resp.Error)
|
||||
} else {
|
||||
debuggingChannel = rchannel
|
||||
println("Looks like this might be the first run so we've created the channel " + CHANNEL_LOG_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) SendMsgToDebuggingChannel(msg string, replyToId string) {
|
||||
post := &model.Post{}
|
||||
post.ChannelId = debuggingChannel.Id
|
||||
post.Message = msg
|
||||
|
||||
post.RootId = replyToId
|
||||
|
||||
if _, resp := client.CreatePost(post); resp.Error != nil {
|
||||
println("We failed to send a message to the logging channel")
|
||||
PrintError(resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) HandleWebSocketResponse(event *model.WebSocketEvent) {
|
||||
HandleMsgFromDebuggingChannel(event)
|
||||
}
|
||||
|
||||
func (b *Bot) HandleMsgFromDebuggingChannel(event *model.WebSocketEvent) {
|
||||
// If this isn't the debugging channel then lets ingore it
|
||||
if event.Broadcast.ChannelId != debuggingChannel.Id {
|
||||
return
|
||||
}
|
||||
|
||||
// Lets only reponded to messaged posted events
|
||||
if event.Event != model.WEBSOCKET_EVENT_POSTED {
|
||||
return
|
||||
}
|
||||
|
||||
println("responding to debugging channel msg")
|
||||
|
||||
post := model.PostFromJson(strings.NewReader(event.Data["post"].(string)))
|
||||
if post != nil {
|
||||
|
||||
// ignore my events
|
||||
if post.UserId == botUser.Id {
|
||||
return
|
||||
}
|
||||
|
||||
// if you see any word matching 'alive' then respond
|
||||
if matched, _ := regexp.MatchString(`(?:^|\W)alive(?:$|\W)`, post.Message); matched {
|
||||
SendMsgToDebuggingChannel("Yes I'm running", post.Id)
|
||||
return
|
||||
}
|
||||
|
||||
// if you see any word matching 'up' then respond
|
||||
if matched, _ := regexp.MatchString(`(?:^|\W)up(?:$|\W)`, post.Message); matched {
|
||||
SendMsgToDebuggingChannel("Yes I'm running", post.Id)
|
||||
return
|
||||
}
|
||||
|
||||
// if you see any word matching 'running' then respond
|
||||
if matched, _ := regexp.MatchString(`(?:^|\W)running(?:$|\W)`, post.Message); matched {
|
||||
SendMsgToDebuggingChannel("Yes I'm running", post.Id)
|
||||
return
|
||||
}
|
||||
|
||||
// if you see any word matching 'hello' then respond
|
||||
if matched, _ := regexp.MatchString(`(?:^|\W)hello(?:$|\W)`, post.Message); matched {
|
||||
SendMsgToDebuggingChannel("Yes I'm running", post.Id)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
SendMsgToDebuggingChannel("I did not understand you!", post.Id)
|
||||
}
|
||||
|
||||
func PrintError(err *model.AppError) {
|
||||
println("\tError Details:")
|
||||
println("\t\t" + err.Message)
|
||||
println("\t\t" + err.Id)
|
||||
println("\t\t" + err.DetailedError)
|
||||
}
|
||||
|
||||
func (b *Bot) SetupGracefulShutdown() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for _ = range c {
|
||||
if webSocketClient != nil {
|
||||
webSocketClient.Close()
|
||||
}
|
||||
|
||||
SendMsgToDebuggingChannel("_"+SAMPLE_NAME+" has **stopped** running_", "")
|
||||
os.Exit(0)
|
||||
}
|
||||
}()
|
||||
}
|
||||
Reference in New Issue
Block a user