145 lines
4.1 KiB
Go
145 lines
4.1 KiB
Go
package bot
|
|
|
|
//import "github.com/kr/pretty"
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type MetarResponse struct {
|
|
Meta struct {
|
|
Timestamp time.Time `json:"timestamp"`
|
|
StationsUpdated string `json:"stations_updated"`
|
|
} `json:"meta"`
|
|
Altimeter struct {
|
|
Repr string `json:"repr"`
|
|
Value float64 `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"altimeter"`
|
|
Clouds []interface{} `json:"clouds"`
|
|
FlightRules string `json:"flight_rules"`
|
|
Other []interface{} `json:"other"`
|
|
Sanitized string `json:"sanitized"`
|
|
Visibility struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"visibility"`
|
|
WindDirection struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"wind_direction"`
|
|
WindGust struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"wind_gust"`
|
|
WindSpeed struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"wind_speed"`
|
|
WxCodes []interface{} `json:"wx_codes"`
|
|
Raw string `json:"raw"`
|
|
Station string `json:"station"`
|
|
Time struct {
|
|
Repr string `json:"repr"`
|
|
Dt time.Time `json:"dt"`
|
|
} `json:"time"`
|
|
Remarks string `json:"remarks"`
|
|
Dewpoint struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"dewpoint"`
|
|
RemarksInfo struct {
|
|
DewpointDecimal struct {
|
|
Repr string `json:"repr"`
|
|
Value float64 `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"dewpoint_decimal"`
|
|
TemperatureDecimal struct {
|
|
Repr string `json:"repr"`
|
|
Value float64 `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"temperature_decimal"`
|
|
} `json:"remarks_info"`
|
|
RunwayVisibility []interface{} `json:"runway_visibility"`
|
|
Temperature struct {
|
|
Repr string `json:"repr"`
|
|
Value int `json:"value"`
|
|
Spoken string `json:"spoken"`
|
|
} `json:"temperature"`
|
|
WindVariableDirection []interface{} `json:"wind_variable_direction"`
|
|
Units struct {
|
|
Altimeter string `json:"altimeter"`
|
|
Altitude string `json:"altitude"`
|
|
Temperature string `json:"temperature"`
|
|
Visibility string `json:"visibility"`
|
|
WindSpeed string `json:"wind_speed"`
|
|
} `json:"units"`
|
|
}
|
|
|
|
func (b *Bot) HandleWeatherRequest(channelid string, postid string, message string) {
|
|
|
|
// we are using a very bare image with no CA cert bundle
|
|
// actually if you docker bind mount the ca cert bundle in the right
|
|
// place, golang will find it and use it.
|
|
//http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
|
|
log.Info().Msgf("weather request received: `%s`", message)
|
|
|
|
r := regexp.MustCompile(`metar\s+([A-Za-z]{4})`)
|
|
matches := r.FindStringSubmatch(message)
|
|
if len(matches) < 2 {
|
|
b.SendMsgToChannel("error, sorry", postid, channelid)
|
|
}
|
|
|
|
loc := matches[1]
|
|
|
|
token := os.Getenv("METAR_API_TOKEN")
|
|
url := fmt.Sprintf("https://avwx.rest/api/metar/%s?options=&airport=true&reporting=true&format=json&onfail=cache", loc)
|
|
|
|
log.Info().Msgf("calculated url: `%s`", url)
|
|
|
|
client := http.Client{
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
req.Header.Add("Authorization", `Token `+token)
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
b.SendMsgToChannel(fmt.Sprintf("weather fetch error: %s", err), postid, channelid)
|
|
return
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
b.SendMsgToChannel(fmt.Sprintf("weather fetch error: http status %d", resp.StatusCode), postid, channelid)
|
|
return
|
|
}
|
|
|
|
data, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
var parsedMetarResponse MetarResponse
|
|
|
|
log.Info().Msgf("weather %s: %s", loc, data)
|
|
|
|
err = nil
|
|
err = json.Unmarshal([]byte(data), &parsedMetarResponse)
|
|
|
|
if err != nil {
|
|
b.SendMsgToChannel("error deserializing metar data", postid, channelid)
|
|
return
|
|
}
|
|
b.SendMsgToChannel(fmt.Sprintf("weather for `%s`: \n```\n%+v\n```\n", loc, parsedMetarResponse), postid, channelid)
|
|
}
|