From 7b322ed116cea51cb399f154b8746f52167f6796 Mon Sep 17 00:00:00 2001 From: sirrow Date: Wed, 28 May 2025 02:10:12 +0900 Subject: [PATCH] init --- go.mod | 11 +++ main.go | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 go.mod create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9ca0144 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module splaschedbot + +go 1.24.1 + +require github.com/bwmarrin/discordgo v0.29.0 + +require ( + github.com/gorilla/websocket v1.4.2 // indirect + golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..9b57dd8 --- /dev/null +++ b/main.go @@ -0,0 +1,231 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "time" + "unicode/utf8" + + "github.com/bwmarrin/discordgo" +) + +type AutoGenerated struct { + Result struct { + Regular []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule struct { + Key string `json:"key"` + Name string `json:"name"` + } `json:"rule"` + Stages []struct { + ID int `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + } `json:"stages"` + IsFest bool `json:"is_fest"` + } `json:"regular"` + BankaraChallenge []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule struct { + Key string `json:"key"` + Name string `json:"name"` + } `json:"rule"` + Stages []struct { + ID int `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + } `json:"stages"` + IsFest bool `json:"is_fest"` + } `json:"bankara_challenge"` + BankaraOpen []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule struct { + Key string `json:"key"` + Name string `json:"name"` + } `json:"rule"` + Stages []struct { + ID int `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + } `json:"stages"` + IsFest bool `json:"is_fest"` + } `json:"bankara_open"` + X []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule struct { + Key string `json:"key"` + Name string `json:"name"` + } `json:"rule"` + Stages []struct { + ID int `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + } `json:"stages"` + IsFest bool `json:"is_fest"` + } `json:"x"` + Event []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule struct { + Key string `json:"key"` + Name string `json:"name"` + } `json:"rule"` + Stages []struct { + ID int `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + } `json:"stages"` + Event struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + } `json:"event"` + IsFest bool `json:"is_fest"` + } `json:"event"` + Fest []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule any `json:"rule"` + Stages any `json:"stages"` + IsFest bool `json:"is_fest"` + IsTricolor bool `json:"is_tricolor"` + TricolorStages any `json:"tricolor_stages"` + } `json:"fest"` + FestChallenge []struct { + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Rule any `json:"rule"` + Stages any `json:"stages"` + IsFest bool `json:"is_fest"` + IsTricolor bool `json:"is_tricolor"` + TricolorStages any `json:"tricolor_stages"` + } `json:"fest_challenge"` + } `json:"result"` +} + +type msgidstore struct { + filepath string +} + +func NewMsgIDStore() *msgidstore { + return &msgidstore{filepath: os.Getenv("MSGIDSTORE_FILEPATH")} +} + +func (s *msgidstore) Set(id string) error { + // Open file for writing + file, err := os.OpenFile(s.filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + defer file.Close() + // Write the message ID to the file + _, err = file.WriteString(id) + if err != nil { + return err + } + return nil +} + +func (s *msgidstore) Exist() bool { + // Check if the file exists + _, err := os.Stat(s.filepath) + if os.IsNotExist(err) { + return false + } + return err == nil +} + +func (s *msgidstore) Get() (string, error) { + // Open file for reading + file, err := os.Open(s.filepath) + if err != nil { + return "", err + } + defer file.Close() + // Read the message ID from the file + var id string + _, err = fmt.Fscanf(file, "%s", &id) + if err != nil { + return "", err + } + return id, nil +} + +func main() { + discordChannelId := os.Getenv("DISCORD_CHANNEL_ID") + discordToken := os.Getenv("DISCORD_TOKEN") + + discord, err := discordgo.New("Bot " + discordToken) + if err != nil { + panic(err) + } + + url := "https://spla3.yuu26.com/api/schedule" + + resp, err := http.Get(url) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + byteArray, _ := io.ReadAll(resp.Body) + var data AutoGenerated + err = json.Unmarshal(byteArray, &data) + if err != nil { + panic(err) + } + + output := "バンカラオープン スケジュール\n" + output += "```\n" + for _, v := range data.Result.BankaraChallenge { + output += fmt.Sprintf("%d/%d %2d:%02d- ", v.StartTime.Month(), v.StartTime.Day(), v.StartTime.Hour(), v.StartTime.Minute()) + output += v.Rule.Name + length := utf8.RuneCountInString(v.Rule.Name) + fill := (13 - length) + for range fill { + output += " " + } + for _, stage := range v.Stages { + output += fmt.Sprintf("%s ", stage.Name) + length := utf8.RuneCountInString(stage.Name) + fill := (11 - length) + for range fill { + output += " " + } + } + output += fmt.Sprintln() + } + output += "```\n" + output += "updated at " + time.Now().Format("1/2 15:04") + "\n" + print(output) + + msgidstore := NewMsgIDStore() + if msgidstore.Exist() { + id, err := msgidstore.Get() + if err != nil { + panic(err) + } + // If the message ID exists, edit the message + _, err = discord.ChannelMessageEdit(discordChannelId, id, output) + if err != nil { + panic(err) + } + } else { + msg, err := discord.ChannelMessageSend(discordChannelId, output) + if err != nil { + panic(err) + } + // Store msg ID + err = msgidstore.Set(msg.ID) + if err != nil { + panic(err) + } + } +}