dota_patch_bot/main.go

138 lines
3.3 KiB
Go

package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
)
type patchList struct {
Patches []patch `json:"patches"`
Success bool `json:"success"`
}
type patch struct {
PatchNumber string `json:"patch_number"`
PatchName string `json:"patch_name"`
PatchTimestamp int `json:"patch_timestamp"`
PatchWebsite string `json:"patch_website,omitempty"`
PatchWebsiteAnchor string `json:"patch_website_anchor,omitempty"`
}
func loadPatches(pl *patchList, url string) {
res, err := http.Get(url)
if err != nil {
log.Printf("Got %v, retrying in 5s", err)
time.Sleep(5 * time.Second)
res, err = http.Get(url)
if err != nil {
log.Printf("Got %v, not trying again", err)
return
}
}
defer res.Body.Close()
body, readErr := io.ReadAll(res.Body)
if readErr != nil {
log.Fatal(readErr)
}
err = json.Unmarshal(body, pl)
if err != nil {
log.Fatal("error: ", err)
}
}
func notify(ptch patch, url string) {
type Payload struct {
Text string `json:"text"`
DisplayName string `json:"displayName"`
AvatarURL string `json:"avatar_url"`
}
var msg string
if ptch.PatchNumber == "" {
msg = "DotaPatchBot online"
} else {
log.Printf("Patch %v found, notifying\n", ptch.PatchNumber)
if ptch.PatchWebsite != "" {
msg = fmt.Sprintf("Patch %v released, see website:\nhttps://www.dota2.com/%v", ptch.PatchNumber, ptch.PatchWebsite)
} else {
msg = fmt.Sprintf("Patch %v Released", ptch.PatchNumber)
}
}
if url != "" {
data := Payload{
msg,
"DotaPatchBot",
"https://i.pinimg.com/originals/8a/8b/50/8a8b50da2bc4afa933718061fe291520.jpg",
}
payloadBytes, err := json.Marshal(data)
if err != nil {
log.Fatalf("Can't create webhook notice; failing since that means drastic data format change")
}
body := bytes.NewReader(payloadBytes)
resp, err := http.Post(url, "application/json", body)
if err != nil {
log.Println("error posting to webhook")
return
}
defer resp.Body.Close()
}
}
func main() {
hookPtr := flag.String("hook", "", "the webhook to notify")
sourcePtr := flag.String("url", "https://www.dota2.com/datafeed/patchnoteslist", "url to fetch patchnotes from")
patchlist := patchList{}
var currentPatch patch
flag.Parse()
if *hookPtr == "" {
if val, ok := os.LookupEnv("DOTA_WEBHOOK"); ok {
*hookPtr = val
}
}
if *sourcePtr == "" {
if val, ok := os.LookupEnv("DOTA_PATCH_SOURCE"); ok {
*sourcePtr = val
}
}
loadPatches(&patchlist, *sourcePtr)
if len(patchlist.Patches) <= 0 {
log.Fatal("error getting initial patch list")
}
currentPatch = patchlist.Patches[len(patchlist.Patches)-1]
log.Println("Started bot, loaded patch list")
log.Printf("Starting on patch %v", currentPatch.PatchNumber)
if *hookPtr == "" {
log.Println("No webhook set, not notifying")
} else {
log.Printf("Notifying %v", *hookPtr)
}
notify(patch{}, *hookPtr)
for {
time.Sleep(30 * time.Second)
loadPatches(&patchlist, *sourcePtr)
if len(patchlist.Patches) > 0 {
newestPatch := patchlist.Patches[len(patchlist.Patches)-1]
if newestPatch.PatchNumber != currentPatch.PatchNumber {
currentPatch = newestPatch
if *hookPtr != "" {
notify(currentPatch, *hookPtr)
} else {
log.Printf("Patch %v found, no webhook\n", currentPatch.PatchNumber)
}
}
}
}
}