NukaNewsBot/main.go

207 lines
6.0 KiB
Go
Raw Normal View History

2024-04-27 01:20:47 +00:00
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
}
2024-04-27 01:59:05 +00:00
// 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
}
// Define a map to associate each desired tag with its corresponding Discord channel ID
var tagChannelMap = map[string]string{
"Patch Notes": "patch-notes-channel-id",
"Atomic Shop": "atomic-shop-channel-id",
"News": "news-channel-id",
// Add more tags and corresponding channel IDs as needed
}
2024-04-27 01:20:47 +00:00
// Function to scrape the webpage and send a message if the date matches
func sendNotifications(session *discordgo.Session, channelID string, html string) {
2024-04-27 01:59:05 +00:00
// Extract tags from the HTML content
tags := extractTags(html)
// Define the desired tags to filter for
desiredTags := []string{"Patch Notes", "Atomic Shop", "News"}
// Check if any of the desired tags are present in the extracted tags
for _, tag := range tags {
for _, desiredTag := range desiredTags {
if tag == desiredTag {
// If the desired tag is found, send a message to the Discord channel
_, err := session.ChannelMessageSend(channelID, fmt.Sprintf("Found tag: %s", tag))
if err != nil {
fmt.Println("Error sending message to Discord:", err)
return
}
fmt.Println("Message sent to Discord channel")
}
}
}
2024-04-27 01:20:47 +00:00
2024-04-27 01:59:05 +00:00
// Parse the HTML content
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
fmt.Println("Error parsing HTML:", err)
return
}
2024-04-27 01:20:47 +00:00
2024-04-27 01:59:05 +00:00
// 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")
}
2024-04-27 01:20:47 +00:00
}
2024-04-27 01:59:05 +00:00
2024-04-27 01:20:47 +00:00
// 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!")
}
}