From 188fb60704b3ac609d7e454a3b2b29a084cc17b7 Mon Sep 17 00:00:00 2001 From: idanoo Date: Tue, 13 Sep 2022 23:25:11 +1200 Subject: [PATCH] Get address distance working --- .env.example | 1 + cmd/flatfinder/main.go | 1 + flatfinder.service | 4 +- internal/flatfinder/discord.go | 14 +++++- internal/flatfinder/google.go | 88 ++++++++++++++++++++++++++++++++-- internal/flatfinder/main.go | 1 + internal/flatfinder/trademe.go | 4 +- 7 files changed, 104 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index e5d7ca1..8fab136 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ DISCORD_WEBHOOK="" +DISCORD_TAG="" GOOGLE_API_KEY="" GOOGLE_LOCATION_1="42 Wallaby Way, Sydney" GOOGLE_LOCATION_2="43 Wallaby Way, Sydney" diff --git a/cmd/flatfinder/main.go b/cmd/flatfinder/main.go index 8652524..3e11177 100755 --- a/cmd/flatfinder/main.go +++ b/cmd/flatfinder/main.go @@ -25,6 +25,7 @@ func main() { if flatfinder.Conf.DiscordWebhook == "" { log.Fatal("DISCORD_WEBHOOK not set") } + flatfinder.Conf.DiscordTag = os.Getenv("DISCORD_TAG") // Load Google stuff flatfinder.Conf.GoogleApiToken = os.Getenv("GOOGLE_API_KEY") diff --git a/flatfinder.service b/flatfinder.service index cfd6cdc..7784ec6 100644 --- a/flatfinder.service +++ b/flatfinder.service @@ -3,8 +3,8 @@ Description=FlatFinder After=network.target [Service] -ExecStart=/root/flatfinder -WorkingDirectory=/root +ExecStart=/root/flat-finder/flatfinder +WorkingDirectory=/root/flat-finder Type=simple Restart=always RestartSec=5 diff --git a/internal/flatfinder/discord.go b/internal/flatfinder/discord.go index bb3cf79..d1a193e 100644 --- a/internal/flatfinder/discord.go +++ b/internal/flatfinder/discord.go @@ -65,10 +65,20 @@ func (c *LocalConfig) sendEmbeddedMessage(listing TradeMeListing) { AddField("Fibre Avail", hasFibre, false). AddField("Current Connection", currentConn, false) + // Tag if required + if c.DiscordTag != "" { + embed.SetDescription(c.DiscordTag) + } + // Only add address if token set if c.GoogleApiToken != "" && c.GoogleLocation1 != "" { - distance := getDistanceFromAddress(listing.Address, c.GoogleLocation1) - embed = embed.AddField(fmt.Sprintf("Distance to %s", c.GoogleLocation1), distance, false) + distance := c.getDistanceFromAddress(c.GoogleLocation1, listing.GeographicLocation.Latitude, listing.GeographicLocation.Longitude) + embed = embed.AddField(fmt.Sprintf("Walking distance to %s", c.GoogleLocation1), distance, false) + } + + if c.GoogleApiToken != "" && c.GoogleLocation2 != "" { + distance := c.getDistanceFromAddress(c.GoogleLocation2, listing.GeographicLocation.Latitude, listing.GeographicLocation.Longitude) + embed = embed.AddField(fmt.Sprintf("Walking distance to %s", c.GoogleLocation2), distance, false) } embeds := []discord.Embed{} diff --git a/internal/flatfinder/google.go b/internal/flatfinder/google.go index 67ce5dd..03a459c 100644 --- a/internal/flatfinder/google.go +++ b/internal/flatfinder/google.go @@ -1,6 +1,88 @@ package flatfinder -// getDistanceFromAddress - Return distance from 2 points -func getDistanceFromAddress(from string, to string) string { - return "N/A" +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "net/url" +) + +type GoogleMapsDistanceMatrixResponse struct { + DestinationAddresses []string `json:"destination_addresses"` + OriginAddresses []string `json:"origin_addresses"` + Rows []struct { + Elements []struct { + Distance struct { + Text string `json:"text"` + Value int `json:"value"` + } `json:"distance"` + Duration struct { + Text string `json:"text"` + Value int `json:"value"` + } `json:"duration"` + Status string `json:"status"` + } `json:"elements"` + } `json:"rows"` + Status string `json:"status"` +} + +// getDistanceFromAddress - Return distance between 2 points +func (c *LocalConfig) getDistanceFromAddress(address string, toLat float64, toLong float64) string { + + mapsURL := fmt.Sprintf( + "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&mode=%s&origins=%f,%f&destinations=%s&key=%s", + "walking", + toLat, + toLong, + url.QueryEscape(address), + c.GoogleApiToken, + ) + + client := http.Client{} + req, err := http.NewRequest("GET", mapsURL, nil) + if err != nil { + log.Print(err) + return "UNKNOWN" + } + + // Do the request + resp, err := client.Do(req) + if err != nil { + log.Print(err) + return "UNKNOWN" + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusOK { + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + log.Print(err) + return "UNKNOWN" + } + + // Decode JSON + var mapsResult GoogleMapsDistanceMatrixResponse + err = json.Unmarshal(bodyBytes, &mapsResult) + if err != nil { + log.Print(err) + return "UNKNOWN" + } + + dist := "N/A" + time := "N/A" + for _, rows := range mapsResult.Rows { + for _, element := range rows.Elements { + dist = element.Distance.Text + time = element.Duration.Text + } + } + + return fmt.Sprintf("%s (%s)", dist, time) + } else { + log.Printf("Maps API error: %s", resp.Status) + } + + return "UNKNOWN" } diff --git a/internal/flatfinder/main.go b/internal/flatfinder/main.go index 5fa455d..ccff801 100644 --- a/internal/flatfinder/main.go +++ b/internal/flatfinder/main.go @@ -10,6 +10,7 @@ import ( // Our local struct we will store data during runtime type LocalConfig struct { DiscordWebhook string `json:"-"` + DiscordTag string `json:"-"` DiscordClient webhook.Client `json:"-"` GoogleApiToken string `json:"-"` diff --git a/internal/flatfinder/trademe.go b/internal/flatfinder/trademe.go index 1e31b89..8e254e1 100644 --- a/internal/flatfinder/trademe.go +++ b/internal/flatfinder/trademe.go @@ -105,8 +105,8 @@ type TradeMeListing struct { } func (c *LocalConfig) searchTrademe() error { - // Only show last 2 hours of posts - dateFrom := time.Now().Add(-time.Hour * 6) + // Only pull last 2 hours by default + dateFrom := time.Now().Add(-time.Hour * 8) // Set filters queryParams := url.Values{}