From 8b2f6a7b8a76644fca90903959abef6f5ba4ffc5 Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski <janne@kuschku.de> Date: Fri, 28 Feb 2025 18:03:30 +0100 Subject: [PATCH] feat: split framework from prototype --- .gitlab-ci.yml | 9 -- Dockerfile | 12 -- api/joinroom.go => api_joinroom.go | 4 +- api/login.go => api_login.go | 2 +- api/markread.go => api_markread.go | 4 +- api/refresh.go => api_refresh.go | 2 +- api/sendmessage.go => api_sendmessage.go | 4 +- api/setpusher.go => api_setpusher.go | 4 +- go.mod | 14 +-- go.sum | 14 --- main.go | 126 ------------------- matrixbot.go | 25 ++-- api/token.go => model_matrixtoken.go | 4 +- api/notification.go => model_notification.go | 2 +- 14 files changed, 27 insertions(+), 199 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 Dockerfile rename api/joinroom.go => api_joinroom.go (82%) rename api/login.go => api_login.go (98%) rename api/markread.go => api_markread.go (90%) rename api/refresh.go => api_refresh.go (98%) rename api/sendmessage.go => api_sendmessage.go (89%) rename api/setpusher.go => api_setpusher.go (95%) delete mode 100644 main.go rename api/token.go => model_matrixtoken.go (65%) rename api/notification.go => model_notification.go (98%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 167716e..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,9 +0,0 @@ -container: - stage: build - image: - name: gcr.io/kaniko-project/executor:debug - entrypoint: [ "" ] - script: - - mkdir -p /kaniko/.docker - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA} --destination $CI_REGISTRY_IMAGE:latest diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index ea5101d..0000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM golang:1.24-alpine AS go_builder - -WORKDIR /src -COPY go.* ./ -RUN go mod download -COPY . ./ -RUN CGO_ENABLED=0 GOOS=linux go build -o app - -FROM scratch -COPY --from=go_builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -COPY --from=go_builder /src/app /app -ENTRYPOINT ["/app"] diff --git a/api/joinroom.go b/api_joinroom.go similarity index 82% rename from api/joinroom.go rename to api_joinroom.go index 5826d78..32477d3 100644 --- a/api/joinroom.go +++ b/api_joinroom.go @@ -1,11 +1,11 @@ -package api +package matrixbot import ( "fmt" "net/http" ) -func JoinRoom(token Token, roomId string) error { +func JoinRoom(token MatrixToken, roomId string) error { request, err := http.NewRequest( http.MethodPost, fmt.Sprintf("https://matrix-client.matrix.org/_matrix/client/v3/rooms/%s/join", roomId), diff --git a/api/login.go b/api_login.go similarity index 98% rename from api/login.go rename to api_login.go index 3cb9aff..afc9e6f 100644 --- a/api/login.go +++ b/api_login.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "bytes" diff --git a/api/markread.go b/api_markread.go similarity index 90% rename from api/markread.go rename to api_markread.go index 7bbdaa7..b14aeb0 100644 --- a/api/markread.go +++ b/api_markread.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "bytes" @@ -15,7 +15,7 @@ type ReadReceiptRequest struct { ReadPrivate string `json:"m.read.private"` } -func SetReadReceipt(token Token, roomId string, messageId string) error { +func SetReadReceipt(token MatrixToken, roomId string, messageId string) error { body, err := json.Marshal(ReadReceiptRequest{ FullyRead: messageId, Read: messageId, diff --git a/api/refresh.go b/api_refresh.go similarity index 98% rename from api/refresh.go rename to api_refresh.go index 1dcc5b7..ebefbe5 100644 --- a/api/refresh.go +++ b/api_refresh.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "bytes" diff --git a/api/sendmessage.go b/api_sendmessage.go similarity index 89% rename from api/sendmessage.go rename to api_sendmessage.go index 70e480d..a7faa3d 100644 --- a/api/sendmessage.go +++ b/api_sendmessage.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "bytes" @@ -8,7 +8,7 @@ import ( "net/http" ) -func SendMessage(token Token, roomId string, content interface{}) error { +func SendMessage(token MatrixToken, roomId string, content interface{}) error { transactionId, err := uuid.NewRandom() if err != nil { return err diff --git a/api/setpusher.go b/api_setpusher.go similarity index 95% rename from api/setpusher.go rename to api_setpusher.go index c223f86..e1ed92e 100644 --- a/api/setpusher.go +++ b/api_setpusher.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "bytes" @@ -26,7 +26,7 @@ type PusherData struct { Url string `json:"url"` } -func SetPusher(token Token, url string) error { +func SetPusher(token MatrixToken, url string) error { body, err := json.Marshal(PusherRequest{ AppDisplayName: "webhook", AppId: "de.justjanne.webhook", diff --git a/go.mod b/go.mod index 44a23d6..b784d8d 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,5 @@ -module git.kuschku.de/justjanne/stateless-matrix-bot +module git.kuschku.de/justJanne/stateless-matrix-bot-framework go 1.22.2 -require ( - git.kuschku.de/justJanne/bahn-api v0.0.0-20210606022125-173e9216d8a8 - github.com/google/uuid v1.6.0 -) - -require ( - github.com/andybalholm/cascadia v1.0.0 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01 // indirect - golang.org/x/text v0.3.2 // indirect -) +require github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 0425cac..7790d7c 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,2 @@ -git.kuschku.de/justJanne/bahn-api v0.0.0-20210606022125-173e9216d8a8 h1:5VmfteMrWeABylH1lP46QLBEx8YWawIfw2WdfGWSv/I= -git.kuschku.de/justJanne/bahn-api v0.0.0-20210606022125-173e9216d8a8/go.mod h1:9d+hDIsjtAxjb0FPo6DLNqf9Co7CX35IHScmo9wQGlo= -github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= -github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01 h1:po1f06KS05FvIQQA2pMuOWZAUXiy1KYdIf0ElUU2Hhc= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go deleted file mode 100644 index 218ce4d..0000000 --- a/main.go +++ /dev/null @@ -1,126 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "git.kuschku.de/justJanne/bahn-api" - "git.kuschku.de/justjanne/stateless-matrix-bot/api" - "html/template" - "math/rand/v2" - "net/http" - "net/url" - "os" - "strings" -) - -func main() { - var err error - - pushUrl, err := url.Parse(os.Getenv("BOT_PUSHURL")) - if err != nil { - panic(err) - } - bot := NewMatrixBot(pushUrl) - - // !8ball handler - bot.HandleFunc("!8ball", func(bot *MatrixBot, notification api.Notification) error { - positive := []string{ - "It is certain", - "It is decidedly so", - "Without a doubt", - "Yes – definitely", - "You may rely on it", - "As I see it, yes", - "Most Likely", - "Outlook good", - "Yes", - "Signs point to yes.", - } - negative := []string{ - "Don’t count on it", - "My reply is no", - "My sources say no", - "Outlook not so good", - "very doubtful", - } - neutral := []string{ - "Reply hazy", - "try again", - "Ask again later", - "Better not tell you now", - "Cannot predict now", - "Concentrate and ask again", - } - var answers []string - switch rand.IntN(3) { - case 0: - answers = positive - break - case 1: - answers = negative - break - case 2: - answers = neutral - break - } - answer := answers[rand.IntN(len(answers))] - - err = api.SendMessage(*bot.token, notification.RoomId, api.MessageContent{ - Body: answer, - MsgType: "m.text", - }) - return nil - }) - - // !trains handler - bahnTpl, err := template.New("bahn").Parse(`{{- /*gotype: bahn.Timetable*/ -}} -<b>{{.Station}}</b> Abfahrten -{{- range .Stops -}} - {{- if .Departure -}} - {{- if .Departure.Line -}} - <li>{{- if .Departure.ChangedTime -}}{{.Departure.ChangedTime}}{{- else if .Departure.PlannedTime -}}{{.Departure.PlannedTime}}{{- end -}} - · <b>{{ .Departure.Line }}</b></li> - {{- else if .TripLabel.TripCategory -}} - {{- if .TripLabel.TripNumber -}} - <li>{{- if .Departure.ChangedTime -}}{{.Departure.ChangedTime}}{{- else if .Departure.PlannedTime -}}{{.Departure.PlannedTime}}{{- end -}} - · <b>{{ .TripLabel.TripCategory }} {{ .TripLabel.TripNumber }}</b></li> - {{- end -}} - {{- end -}} - {{- end -}} -{{- end -}}`) - if err != nil { - panic(err) - } - bot.HandleFunc("!trains", func(bot *MatrixBot, notification api.Notification) error { - elements := strings.SplitN(strings.TrimSpace(notification.Content.Body), " ", 3) - response, err := http.Get(fmt.Sprintf("https://iris.noncd.db.de/iris-tts/timetable/fchg/%s", elements[1])) - if err != nil { - return err - } - timetable, err := bahn.TimetableFromReader(response.Body) - if err != nil { - return err - } - buf := new(bytes.Buffer) - err = bahnTpl.Execute(buf, timetable) - if err != nil { - return err - } - err = api.SendMessage(*bot.token, notification.RoomId, api.MessageContent{ - FormattedBody: buf.String(), - Format: "org.matrix.custom.html", - MsgType: "m.text", - }) - return nil - }) - err = bot.Login(os.Getenv("BOT_USERNAME"), os.Getenv("BOT_PASSWORD"), os.Getenv("BOT_DEVICEID")) - if err != nil { - panic(err) - } - err = bot.RegisterPusher() - if err != nil { - panic(err) - } - go bot.RefreshTask() - bot.Serve(":8080") -} diff --git a/matrixbot.go b/matrixbot.go index 2604f8f..3c6237c 100644 --- a/matrixbot.go +++ b/matrixbot.go @@ -1,8 +1,7 @@ -package main +package matrixbot import ( "fmt" - "git.kuschku.de/justjanne/stateless-matrix-bot/api" "io" "log" "net/http" @@ -12,16 +11,16 @@ import ( ) type MatrixBot struct { - token *api.Token + token *MatrixToken pushUrl *url.URL - handlers map[string]func(bot *MatrixBot, notification api.Notification) error + handlers map[string]func(bot *MatrixBot, notification Notification) error } func NewMatrixBot(pushUrl *url.URL) *MatrixBot { return &MatrixBot{ token: nil, pushUrl: pushUrl, - handlers: make(map[string]func(bot *MatrixBot, notification api.Notification) error), + handlers: make(map[string]func(bot *MatrixBot, notification Notification) error), } } @@ -29,11 +28,11 @@ func (bot *MatrixBot) RefreshToken() error { if bot.token == nil { return fmt.Errorf("no refresh token available") } - userData, err := api.Refresh(bot.token.RefreshToken) + userData, err := Refresh(bot.token.RefreshToken) if err != nil { return err } - bot.token = &api.Token{ + bot.token = &MatrixToken{ AccessToken: userData.AccessToken, Expires: time.Now().Add(time.Duration(userData.ExpiresInMs) / 2 * time.Millisecond), RefreshToken: userData.RefreshToken, @@ -42,11 +41,11 @@ func (bot *MatrixBot) RefreshToken() error { } func (bot *MatrixBot) Login(username string, password string, deviceId string) error { - userData, err := api.Login(username, password, deviceId) + userData, err := Login(username, password, deviceId) if err != nil { return err } - bot.token = &api.Token{ + bot.token = &MatrixToken{ AccessToken: userData.AccessToken, Expires: time.Now().Add(time.Duration(userData.ExpiresInMs) / 2 * time.Millisecond), RefreshToken: userData.RefreshToken, @@ -66,10 +65,10 @@ func (bot *MatrixBot) RefreshTask() { } func (bot *MatrixBot) RegisterPusher() error { - return api.SetPusher(*bot.token, bot.pushUrl.String()) + return SetPusher(*bot.token, bot.pushUrl.String()) } -func (bot *MatrixBot) HandleFunc(command string, handler func(bot *MatrixBot, notification api.Notification) error) { +func (bot *MatrixBot) HandleFunc(command string, handler func(bot *MatrixBot, notification Notification) error) { bot.handlers[command] = handler } @@ -80,7 +79,7 @@ func (bot *MatrixBot) Serve(endpoint string) { log.Printf("listening for push notifications on %s\n", bot.pushUrl.Path) http.HandleFunc(bot.pushUrl.Path, func(writer http.ResponseWriter, request *http.Request) { log.Println("Received push notification") - notification, err := api.ParseNotification(request.Body) + notification, err := ParseNotification(request.Body) if err != nil { log.Println(err.Error()) return @@ -88,7 +87,7 @@ func (bot *MatrixBot) Serve(endpoint string) { if notification.EventId == "" { return } - err = api.SetReadReceipt(*bot.token, notification.RoomId, notification.EventId) + err = SetReadReceipt(*bot.token, notification.RoomId, notification.EventId) if err != nil { log.Println(err.Error()) return diff --git a/api/token.go b/model_matrixtoken.go similarity index 65% rename from api/token.go rename to model_matrixtoken.go index fa9c559..7a8221a 100644 --- a/api/token.go +++ b/model_matrixtoken.go @@ -1,8 +1,8 @@ -package api +package matrixbot import "time" -type Token struct { +type MatrixToken struct { AccessToken string Expires time.Time RefreshToken string diff --git a/api/notification.go b/model_notification.go similarity index 98% rename from api/notification.go rename to model_notification.go index 8f7dd65..933a424 100644 --- a/api/notification.go +++ b/model_notification.go @@ -1,4 +1,4 @@ -package api +package matrixbot import ( "encoding/json" -- GitLab