diff options
author | Dmitry Ilvokhin <d@ilvokhin.com> | 2025-03-08 22:26:47 +0000 |
---|---|---|
committer | Dmitry Ilvokhin <d@ilvokhin.com> | 2025-03-08 22:26:47 +0000 |
commit | 5c2b8ff9b7a6c239424f54f3a818b1916253955d (patch) | |
tree | fa1fa63a0e2c3757d6290c45821952f8a894eebd /flatbot.go | |
parent | 5688f1493026eb4cf96f1abd6d961a5801f1dd26 (diff) | |
download | flatbot-5c2b8ff9b7a6c239424f54f3a818b1916253955d.tar.gz flatbot-5c2b8ff9b7a6c239424f54f3a818b1916253955d.tar.bz2 flatbot-5c2b8ff9b7a6c239424f54f3a818b1916253955d.zip |
Manage options with CLI flags
Diffstat (limited to 'flatbot.go')
-rw-r--r-- | flatbot.go | 103 |
1 files changed, 88 insertions, 15 deletions
@@ -1,46 +1,119 @@ package main import ( + "flag" "fmt" "io" "log" "net/http" "os" + "time" ) +var ( + apiToken = flag.String("api-token", + os.Getenv("FLATBOT_TELEGRAM_BOT_API_TOKEN"), + "Telegram Bot API token") + chatID = flag.String("chat-id", + os.Getenv("FLATBOT_TELEGRAM_CHAT_ID"), + "Telegram chat id where to send notification messages") + state = flag.String("state", "/tmp/flatbot-sent.json", + "Filename to save and load already sent flats") + interval = flag.Duration("frequency", 5*time.Minute, + "Frequency interval to fetch new data") + once = flag.Bool("once", false, "Run fetch and message loop only once") + dryRun = flag.Bool("dry-run", false, + "Run entire flow, but print new flats to stdout instead of "+ + "sending them to Telegram") +) + +func usage() { + fmt.Fprintf(os.Stderr, + "usage: flatbot [-api-token token] [-chat-id id] "+ + "[-state file] [-interval duration] [-once] [-send] "+ + "URL...\n") + flag.PrintDefaults() + os.Exit(2) +} + func main() { - url := "http://localhost:8000/2025-02-19-isle-of-dogs.html" - body, err := fetch(url) + flag.Usage = usage + flag.Parse() + if !*dryRun { + if len(*apiToken) == 0 { + fmt.Fprintf(os.Stderr, + "Going to send messages to Telegram, "+ + "but no API token was provided\n") + os.Exit(1) + } + if len(*chatID) == 0 { + fmt.Fprintf(os.Stderr, + "Going to send messages to Telegram, "+ + "but no chat id was provided\n") + os.Exit(1) + } + } + if flag.NArg() == 0 { + usage() + os.Exit(1) + } + + for { + err := loopOnce() + if err != nil { + log.Fatal(err) + } + if *once { + break + } + log.Printf("Going to sleep for %v", *interval) + time.Sleep(*interval) + } +} + +func loopOnce() error { + sent, err := readSent(*state) if err != nil { - log.Fatal(err) + return err } - fetched, err := parse(body) + for _, url := range flag.Args() { + sent, err = doOneURL(url, sent) + if err != nil { + log.Print(err) + continue + } + } + // TODO: trim sent file here? + return writeSent(sent, *state) +} + +func doOneURL(url string, sent []flat) ([]flat, error) { + body, err := fetch(url) if err != nil { - log.Fatal(err) + return sent, err } - sent, err := readSent("sent/sent.json") + fetched, err := parse(body) if err != nil { - log.Fatal(err) + return sent, err } newFlats := removeAlreadySent(fetched, sent) m := messenger{ - Token: os.Getenv("FLATBOT_TELEGRAM_BOT_API_TOKEN"), - ChatID: os.Getenv("FLATBOT_TELEGRAM_CHANNEL_ID"), + Token: *apiToken, + ChatID: *chatID, } for _, f := range newFlats { - if false { + if !*dryRun { err = m.Send(f) if err != nil { - // TODO: what to do with it? log.Print(err) + continue } } + log.Printf("Should have been sent to chat: %v, %v", + f.Price, f.URL()) sent = append(sent, f) } - // Remove flats from sent that are no longer in the search response to - // prevent indefinite grow of sent file. - sent = removeDelisted(sent, fetched) - writeSent(sent, "/tmp/sent.json") + return sent, nil } func fetch(url string) ([]byte, error) { |