commit
8aaae1aa9c
@ -0,0 +1,23 @@ |
||||
FROM golang:1.15 |
||||
|
||||
WORKDIR /go/src/app |
||||
copy . . |
||||
|
||||
RUN go get -d -v ./... |
||||
RUN go install -v ./... |
||||
|
||||
CMD ["sco"] |
||||
|
||||
|
||||
|
||||
|
||||
FROM golang:1.15 as builder |
||||
RUN mkdir /build |
||||
ADD . /build/ |
||||
WORKDIR /build |
||||
RUN make |
||||
|
||||
FROM scratch |
||||
COPY --from=builder /build/main /app/ |
||||
WORKDIR /app |
||||
CMD ["./main"] |
@ -0,0 +1,32 @@ |
||||
VERSION := $(shell git rev-parse --short HEAD)
|
||||
BUILDTIME := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
|
||||
BUILDTIMEFILENAME := $(shell date -u '+%Y%m%d-%H%M%SZ')
|
||||
BUILDTIMETAG := $(shell date -u '+%Y%m%d%H%M%S')
|
||||
BUILDUSER := $(shell whoami)
|
||||
BUILDHOST := $(shell hostname -s)
|
||||
BUILDARCH := $(shell uname -m)
|
||||
|
||||
FN := sco
|
||||
IMAGENAME := sneak/$(FN)
|
||||
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
GOLDFLAGS += -X main.Version=$(VERSION)
|
||||
GOLDFLAGS += -X main.Buildarch=$(BUILDARCH)
|
||||
|
||||
# osx can't statically link apparently?!
|
||||
ifeq ($(UNAME_S),Darwin) |
||||
GOFLAGS := -ldflags "$(GOLDFLAGS)"
|
||||
endif |
||||
|
||||
ifneq ($(UNAME_S),Darwin) |
||||
GOFLAGS = -ldflags "-linkmode external -extldflags -static $(GOLDFLAGS)"
|
||||
endif |
||||
|
||||
default: ./$(FN) |
||||
|
||||
go-get: |
||||
cd cmd/$(FN) && go get -v
|
||||
|
||||
./$(FN): */*.go cmd/*/*.go go-get |
||||
cd cmd/$(FN) && go build -o ../../$(FN) $(GOFLAGS) .
|
@ -0,0 +1,247 @@ |
||||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"os" |
||||
"os/signal" |
||||
"regexp" |
||||
"strings" |
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model" |
||||
) |
||||
|
||||
const ( |
||||
SAMPLE_NAME = "Mattermost Bot Sample" |
||||
|
||||
USER_EMAIL = "bot@example.com" |
||||
USER_PASSWORD = "password1" |
||||
USER_NAME = "samplebot" |
||||
USER_FIRST = "Sample" |
||||
USER_LAST = "Bot" |
||||
|
||||
TEAM_NAME = "botsample" |
||||
CHANNEL_LOG_NAME = "debugging-for-sample-bot" |
||||
) |
||||
|
||||
var client *model.Client4 |
||||
var webSocketClient *model.WebSocketClient |
||||
|
||||
var botUser *model.User |
||||
var botTeam *model.Team |
||||
var debuggingChannel *model.Channel |
||||
|
||||
// Documentation for the Go driver can be found
|
||||
// at https://godoc.org/github.com/mattermost/platform/model#Client
|
||||
func main() { |
||||
println(SAMPLE_NAME) |
||||
|
||||
SetupGracefulShutdown() |
||||
|
||||
client = model.NewAPIv4Client("http://localhost:8065") |
||||
|
||||
// Lets test to see if the mattermost server is up and running
|
||||
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
|
||||
LoginAsTheBotUser() |
||||
|
||||
// If the bot user doesn't have the correct information lets update his profile
|
||||
UpdateTheBotUserIfNeeded() |
||||
|
||||
// Lets find our bot team
|
||||
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
|
||||
CreateBotDebuggingChannelIfNeeded() |
||||
SendMsgToDebuggingChannel("_"+SAMPLE_NAME+" has **started** running_", "") |
||||
|
||||
// Lets start listening to some channels via the websocket!
|
||||
webSocketClient, err := model.NewWebSocketClient4("ws://localhost:8065", client.AuthToken) |
||||
if err != nil { |
||||
println("We failed to connect to the web socket") |
||||
PrintError(err) |
||||
} |
||||
|
||||
webSocketClient.Listen() |
||||
|
||||
go func() { |
||||
for { |
||||
select { |
||||
case resp := <-webSocketClient.EventChannel: |
||||
HandleWebSocketResponse(resp) |
||||
} |
||||
} |
||||
}() |
||||
|
||||
// You can block forever with
|
||||
select {} |
||||
} |
||||
|
||||
func 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 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 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 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 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 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 HandleWebSocketResponse(event *model.WebSocketEvent) { |
||||
HandleMsgFromDebuggingChannel(event) |
||||
} |
||||
|
||||
func 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 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) |
||||
} |
||||
}() |
||||
} |
Loading…
Reference in new issue