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"` ChannelMap map[string]string `json:"channel_map"` // Add the channel map to the config } func main() { // At the beginning of the main function log.Println("Starting the bot...") // 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 } // After loading the configuration log.Println("Loaded configuration from config.json") // Access the Discord bot token and channel ID from the configuration token := config.DiscordBotToken if token == "" { fmt.Println("Discord bot token is not set in config file") return } // Access the channel map from the configuration tagChannelMap := config.ChannelMap // 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 } // After creating the Discord session log.Println("Created Discord session") // 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 } // After opening the Discord connection log.Println("Opened Discord connection") // Run the scraping and message sending function once at the specified time sendNotifications(dg, scrapeNews(), tagChannelMap) // 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, scrapeNews(), tagChannelMap) } } }() // 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 } // Add a function to extract relevant tags from the HTML content func extractTags(html string) []string { var tags []string doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) if err != nil { fmt.Println("Error parsing HTML:", err) return tags } // Find and extract tags with class name "news-module-feed-item-details-tag" doc.Find("span.news-module-feed-item-details-tag").Each(func(i int, s *goquery.Selection) { tag := strings.TrimSpace(s.Text()) tags = append(tags, tag) }) return tags } func sendNotifications(session *discordgo.Session, html string, tagChannelMap map[string]string) { // Extract tags from the HTML content tags := extractTags(html) // Define today's date string today := time.Now().Format("January 2, 2006") // Iterate over extracted tags for _, tag := range tags { // Check if the tag is in the desired tags list if tagChannelID, ok := tagChannelMap[tag]; ok { // Check if today's date matches the tag if tag == today { // Send a message to the corresponding Discord channel message := fmt.Sprintf("Today's date matches the tag '%s' on the Fallout news page!", tag) _, err := session.ChannelMessageSend(tagChannelID, message) if err != nil { fmt.Printf("Error sending message to Discord channel %s: %s\n", tagChannelID, err) continue } fmt.Println("Message sent to Discord channel:", tagChannelID) } else { // Send a different message indicating the tag was found message := fmt.Sprintf("Tag '%s' found on the Fallout news page, but it's not today's date.", tag) _, err := session.ChannelMessageSend(tagChannelID, message) if err != nil { fmt.Printf("Error sending message to Discord channel %s: %s\n", tagChannelID, err) continue } fmt.Println("Message sent to Discord channel:", tagChannelID) } } } // Inside the sendNotifications function, after extracting tags //log.Println("Extracted tags:", tags) // Inside the sendNotifications function, after checking tag-channel mappings //log.Println("Tag-channel mappings:", tagChannelMap) } // 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!") } }