From 96de26a544ec50fd02ac954756bde61238c92517 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Thu, 11 Jan 2024 02:08:42 +0100 Subject: [PATCH] add weather command --- Makefile | 6 +++-- cmd/bot/commands.go | 10 +++++++++ go.mod | 5 +++-- go.sum | 4 ++++ pkg/owm/weather.go | 53 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 pkg/owm/weather.go diff --git a/Makefile b/Makefile index 28d6148..1359228 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,13 @@ BINARY_NAME=Nourybot-Matrix.out -dev: +xd: go build -o ${BINARY_NAME} cmd/bot/* ./${BINARY_NAME} --env="dev" +dev: + ./${BINARY_NAME} --env="dev" + prod: - go build -o ${BINARY_NAME} cmd/bot/* ./${BINARY_NAME} --env="prod" build: diff --git a/cmd/bot/commands.go b/cmd/bot/commands.go index 7df5d1d..bfd002d 100644 --- a/cmd/bot/commands.go +++ b/cmd/bot/commands.go @@ -3,10 +3,12 @@ package main import ( "strings" + "github.com/lyx0/nourybot-matrix/pkg/owm" "maunium.net/go/mautrix/event" ) func (app *application) ParseCommand(evt *event.Event) { + var reply string // commandName is the actual name of the command without the prefix. // e.g. `!ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(evt.Content.AsMessage().Body, " ", 2)[0][1:]) @@ -31,8 +33,16 @@ func (app *application) ParseCommand(evt *event.Event) { case "gofile": app.NewDownload("gofile", evt, cmdParams[1]) return + + case "weather": + reply, _ = owm.Weather(evt.Content.AsMessage().Body[9:len(evt.Content.AsMessage().Body)]) + case "yaf": app.NewDownload("yaf", evt, cmdParams[1]) return + + } + if reply != "" { + app.SendText(evt, reply) } } diff --git a/go.mod b/go.mod index f28b663..c0362a6 100644 --- a/go.mod +++ b/go.mod @@ -11,14 +11,15 @@ require ( ) require ( - github.com/google/uuid v1.5.0 // indirect + github.com/briandowns/openweathermap v0.19.0 + github.com/google/uuid v1.5.0 github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/tidwall/gjson v1.17.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/wader/goutubedl v0.0.0-20240110164636-adddb11ead1b // indirect + github.com/wader/goutubedl v0.0.0-20240110164636-adddb11ead1b go.mau.fi/util v0.2.1 // indirect golang.org/x/crypto v0.15.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect diff --git a/go.sum b/go.sum index 7426b3e..1dad0cf 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/briandowns/openweathermap v0.19.0 h1:nkopLMEtZLxbZI1th6dOG6xkajpszofqf53r5K8mT9k= +github.com/briandowns/openweathermap v0.19.0/go.mod h1:0GLnknqicWxXnGi1IqoOaZIw+kIe5hkt+YM5WY3j8+0= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= @@ -7,6 +9,7 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= @@ -37,6 +40,7 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/wader/goutubedl v0.0.0-20240110164636-adddb11ead1b h1:xSddyANsGzMEoClwwZzuesuWPnwkmmtSsERFrOodMT8= github.com/wader/goutubedl v0.0.0-20240110164636-adddb11ead1b/go.mod h1:5KXd5tImdbmz4JoVhePtbIokCwAfEhUVVx3WLHmjYuw= +github.com/wader/osleaktest v0.0.0-20191111175233-f643b0fed071 h1:QkrG4Zr5OVFuC9aaMPmFI0ibfhBZlAgtzDYWfu7tqQk= github.com/wader/osleaktest v0.0.0-20191111175233-f643b0fed071/go.mod h1:XD6emOFPHVzb0+qQpiNOdPL2XZ0SRUM0N5JHuq6OmXo= go.mau.fi/util v0.2.1 h1:eazulhFE/UmjOFtPrGg6zkF5YfAyiDzQb8ihLMbsPWw= go.mau.fi/util v0.2.1/go.mod h1:MjlzCQEMzJ+G8RsPawHzpLB8rwTo3aPIjG5FzBvQT/c= diff --git a/pkg/owm/weather.go b/pkg/owm/weather.go new file mode 100644 index 0000000..f241936 --- /dev/null +++ b/pkg/owm/weather.go @@ -0,0 +1,53 @@ +package owm + +import ( + "errors" + "fmt" + "os" + + owm "github.com/briandowns/openweathermap" + "github.com/joho/godotenv" +) + +var ( + ErrInternalServerError = errors.New("internal server error") + ErrWeatherLocationNotFound = errors.New("location not found") +) + +// Weather queries the OpenWeatherMap Api for the given location and sends the +// current weather response to the target twitch chat. +func Weather(location string) (string, error) { + err := godotenv.Load() + if err != nil { + return "", ErrInternalServerError + } + owmKey := os.Getenv("OWM_KEY") + + w, err := owm.NewCurrent("C", "en", owmKey) + if err != nil { + return "", ErrInternalServerError + } + + if err := w.CurrentByName(location); err != nil { + return "", ErrInternalServerError + } + + // Longitude and Latitude are returned as 0 when the supplied location couldn't be + // assigned to a OpenWeatherMap location. + if w.GeoPos.Longitude == 0 && w.GeoPos.Latitude == 0 { + return "", ErrWeatherLocationNotFound + } else { + // Weather for Vilnius, LT: Feels like: 29.67°C. Currently 29.49°C with a high of 29.84°C and a low of 29.49°C, humidity: 45%, wind: 6.17m/s. + reply := fmt.Sprintf("Weather for %s, %s: Feels like: %v°C. Currently %v°C with a high of %v°C and a low of %v°C, humidity: %v%%, wind: %vm/s.", + w.Name, + w.Sys.Country, + w.Main.FeelsLike, + w.Main.Temp, + w.Main.TempMax, + w.Main.TempMin, + w.Main.Humidity, + w.Wind.Speed, + ) + return reply, nil + } +}