mirror of
https://github.com/idanoo/NZCovidBot
synced 2025-07-02 19:52:14 +00:00
Rework to use API instead of CSVs
This commit is contained in:
parent
b73a6b7cae
commit
4937ec7253
13 changed files with 290 additions and 675 deletions
151
internal/nzcovidbot/api.go
Normal file
151
internal/nzcovidbot/api.go
Normal file
|
@ -0,0 +1,151 @@
|
|||
package nzcovidbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
const API_ENDPOINT = "https://api.integration.covid19.health.nz/locations/v1/current-locations-of-interest"
|
||||
|
||||
var newLocations ApiResponse
|
||||
|
||||
type ApiResponse struct {
|
||||
Items []ApiItem `json:"items"`
|
||||
}
|
||||
|
||||
type ApiItem struct {
|
||||
EventID string `json:"eventId"`
|
||||
EventName string `json:"eventName"`
|
||||
StartDateTime time.Time `json:"startDateTime"`
|
||||
EndDateTime time.Time `json:"endDateTime"`
|
||||
PublicAdvice string `json:"publicAdvice"`
|
||||
VisibleInWebform bool `json:"visibleInWebform"`
|
||||
PublishedAt time.Time `json:"publishedAt"`
|
||||
// UpdatedAt time.Time `json:"updatedAt"` // Nullable
|
||||
ExposureType string `json:"exposureType"`
|
||||
Location struct {
|
||||
Latitude string `json:"latitude"`
|
||||
Longitude string `json:"longitude"`
|
||||
Suburb string `json:"suburb"`
|
||||
City string `json:"city"`
|
||||
Address string `json:"address"`
|
||||
} `json:"location"`
|
||||
}
|
||||
|
||||
// fetchAPILocations - Return struct of API response
|
||||
func fetchAPILocations() (ApiResponse, error) {
|
||||
var apiResponse ApiResponse
|
||||
|
||||
// Build HTTP Client and create request
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", API_ENDPOINT, nil)
|
||||
if err != nil {
|
||||
return apiResponse, err
|
||||
}
|
||||
|
||||
// Set user-agent info
|
||||
req.Header.Set("User-Agent", "NZCovidBot/1.0 (https://m2.nz)")
|
||||
|
||||
// Fire off the request
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return apiResponse, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read body response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return apiResponse, err
|
||||
}
|
||||
|
||||
// Unmarshal JSON into Go struct
|
||||
err = json.Unmarshal(body, &apiResponse)
|
||||
|
||||
return apiResponse, err
|
||||
}
|
||||
|
||||
// getNewAPILocations - Gets all locations and triggers posts
|
||||
func getNewAPILocations() {
|
||||
// Set lastUpdate time at the start of the request so we don't miss any locations
|
||||
// posted right after we poll
|
||||
newPollTime := time.Now()
|
||||
|
||||
// Pull latest data
|
||||
locations, err := fetchAPILocations()
|
||||
if err != nil {
|
||||
log.Printf("Error fetching API Locations %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Re-init our apiRepsonse so we don't hold onto old locations!
|
||||
newItems := make([]ApiItem, 0)
|
||||
|
||||
// Iterate over the data and only find new locations
|
||||
for _, item := range locations.Items {
|
||||
if item.PublishedAt.Unix() > lastUpdated.Unix() {
|
||||
// Clone the item to put in our own lil slice
|
||||
copy := item
|
||||
newItems = append(newItems, copy)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure to clear out the previous list and append new data
|
||||
newLocations = ApiResponse{}
|
||||
newLocations.Items = newItems
|
||||
|
||||
// Order by StartDate
|
||||
sort.Slice(newLocations.Items, func(i, j int) bool {
|
||||
return newLocations.Items[i].StartDateTime.Before(newLocations.Items[j].StartDateTime)
|
||||
})
|
||||
|
||||
// If new items, post it!
|
||||
if len(newLocations.Items) > 0 {
|
||||
postTheUpdates()
|
||||
}
|
||||
|
||||
updateLastUpdated(newPollTime)
|
||||
}
|
||||
|
||||
// updateLastUpdated - Creates/Updates lastUpdated.txt
|
||||
func updateLastUpdated(newUpdated time.Time) {
|
||||
// Make sure to update the global var for next poll
|
||||
lastUpdated = newUpdated
|
||||
|
||||
// Open file in truncate/append mode
|
||||
f, err := os.OpenFile("lastUpdated.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Write data
|
||||
data := []byte(fmt.Sprintf("%d", lastUpdated.Unix()))
|
||||
_, err = f.Write(data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Close file so we can reopen next time
|
||||
if err := f.Close(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// getDateString - Returns Date + StartTime + EndTime
|
||||
func (item ApiItem) getDateString() string {
|
||||
st := item.StartDateTime
|
||||
et := item.EndDateTime
|
||||
|
||||
dateFormat := "Mon 2 Jan, 03:04PM"
|
||||
timeFormat := "03:04PM"
|
||||
|
||||
return st.Format(dateFormat) + " - " + et.Format(timeFormat)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue