package main import ( "context" "encoding/json" "fmt" "log" "os" "strings" "time" "github.com/PuerkitoBio/goquery" "github.com/bwmarrin/discordgo" "github.com/chromedp/chromedp" ) type Config struct { DiscordBotToken string `json:"discord_bot_token"` DiscordChannelID string `json:"discord_channel_id"` // Add more configuration fields here } func main() { // Open and read the configuration file configFile, err := os.Open("config.json") if err != nil { fmt.Println("Error opening config file:", err) return } defer configFile.Close() // Parse the configuration from JSON var config Config err = json.NewDecoder(configFile).Decode(&config) if err != nil { fmt.Println("Error decoding config JSON:", err) return } // Access the Discord bot token from the configuration token := config.DiscordBotToken if token == "" { fmt.Println("Discord bot token is not set in config file") return } // channelID := config.DiscordChannelID if channelID == "" { fmt.Println("Discord channel ID is not set in config file") } // Create a new Discord session using the provided bot token dg, err := discordgo.New("Bot " + token) if err != nil { fmt.Println("Error creating Discord session:", err) return } // Register messageCreate as a callback for the messageCreate events dg.AddHandler(messageCreate) // Open a websocket connection to Discord and begin listening err = dg.Open() if err != nil { fmt.Println("Error opening Discord connection:", err) return } // Run the scraping and message sending function once at the specified time sendNotifications(dg, channelID, scrapeNews()) // Schedule the scraping and message sending function to run once a day ticker := time.NewTicker(24 * time.Hour) defer ticker.Stop() // Run the scraping and message sending function when the ticker ticks go func() { for { select { case <-ticker.C: sendNotifications(dg, channelID, scrapeNews()) } } }() //test() // Wait here until CTRL-C or other term signal is received fmt.Println("Bot is now running. Press CTRL-C to exit.") <-make(chan struct{}) } func scrapeNews() string { // Create a new context ctx := context.Background() ctx, cancel := chromedp.NewContext( ctx, chromedp.WithLogf(log.Printf), ) defer cancel() // Navigate to the Fallout news page var html string err := chromedp.Run(ctx, chromedp.Tasks{ chromedp.Navigate("https://fallout.bethesda.net/en/news"), chromedp.OuterHTML("html", &html), }) if err != nil { log.Fatal(err) } // Return the HTML content return html } // Function to scrape the webpage and send a message if the date matches func sendNotifications(session *discordgo.Session, channelID string, html string) { // Parse the HTML content doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) if err != nil { fmt.Println("Error parsing HTML:", err) return } // Find and extract the date from the webpage var foundDate bool doc.Find("span.news-module-feed-item-details-date").Each(func(i int, s *goquery.Selection) { dateString := strings.TrimSpace(s.Text()) fmt.Println("Found date:", dateString) if dateString == time.Now().Format("January 2, 2006") { foundDate = true } }) // If today's date was found on the webpage, send a message to the Discord channel if foundDate { _, err := session.ChannelMessageSend(channelID, "Today's date was found on the Fallout news page!") if err != nil { fmt.Println("Error sending message to Discord:", err) return } fmt.Println("Message sent to Discord channel") } else { fmt.Println("Today's date not found on the Fallout news page") } } // This function will be called whenever a new message is created func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { // Ignore messages created by the bot itself if m.Author.ID == s.State.User.ID { return } // If the message content is "!hello", respond with "Hello!" if m.Content == "!hello" { _, _ = s.ChannelMessageSend(m.ChannelID, "Hello!") } }