NukaNewsBot/main.go

221 lines
5.8 KiB
Go
Raw Normal View History

2024-04-27 01:20:47 +00:00
package main
import (
2024-04-28 02:30:53 +00:00
"NukaNewsBot/commands"
2024-04-28 03:05:54 +00:00
"NukaNewsBot/utils"
2024-04-27 01:20:47 +00:00
"encoding/json"
"fmt"
"log"
"os"
"strings"
"time"
"github.com/PuerkitoBio/goquery"
"github.com/bwmarrin/discordgo"
)
type Config struct {
2024-04-27 16:34:35 +00:00
DiscordBotToken string `json:"discord_bot_token"`
2024-04-27 21:05:14 +00:00
ChannelMap map[string]string `json:"channel_map"`
RoleMap map[string]string `json:"role_map"`
URL string `json:"url"`
2024-04-27 01:20:47 +00:00
}
func main() {
//Initialize Time
2024-04-27 21:05:14 +00:00
//date := "April 16, 2024"
date := time.Now().Format("January 2, 2006")
2024-04-27 16:34:35 +00:00
// At the beginning of the main function
log.Println("Starting the bot...")
2024-04-27 02:30:28 +00:00
// 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
}
2024-04-27 16:34:35 +00:00
// After loading the configuration
log.Println("Loaded configuration from config.json")
// Access the Discord bot token and channel ID from the configuration
2024-04-27 02:30:28 +00:00
token := config.DiscordBotToken
if token == "" {
fmt.Println("Discord bot token is not set in config file")
return
}
2024-04-27 21:05:14 +00:00
channelMap := config.ChannelMap
if len(channelMap) == 0 {
fmt.Println("Channel map is not set in config file")
return
}
roleMap := config.RoleMap
if len(roleMap) == 0 {
fmt.Println("Role map is not set in config file")
return
}
2024-04-27 02:30:28 +00:00
url := config.URL
if url == "" {
fmt.Println("URL is not set in config file")
return
}
2024-04-27 02:30:28 +00:00
// 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
}
2024-04-27 16:34:35 +00:00
// After creating the Discord session
log.Println("Created Discord session")
2024-04-28 02:30:53 +00:00
// Register commandHandler as a callback for message creation events
dg.AddHandler(commands.CommandHandler)
// After creating the Discord session
log.Println("Listening for Commands")
2024-04-27 02:30:28 +00:00
// Open a websocket connection to Discord and begin listening
err = dg.Open()
if err != nil {
fmt.Println("Error opening Discord connection:", err)
return
}
2024-04-27 16:34:35 +00:00
// After opening the Discord connection
log.Println("Opened Discord connection")
2024-04-27 02:30:28 +00:00
// Run the scraping and message sending function at start up
2024-04-28 03:05:54 +00:00
sendNotifications(dg, utils.FetchUrl(url), channelMap, roleMap, date)
2024-04-27 01:20:47 +00:00
2024-04-27 02:30:28 +00:00
// 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:
2024-04-28 03:05:54 +00:00
sendNotifications(dg, utils.FetchUrl(url), channelMap, roleMap, date)
2024-04-27 02:30:28 +00:00
}
}
}()
// 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{})
2024-04-27 01:20:47 +00:00
}
2024-04-27 01:59:05 +00:00
// Add a function to extract relevant tags from the HTML content
func extractNewsArticles(html string) []map[string]string {
var articles []map[string]string
2024-04-27 02:30:28 +00:00
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
fmt.Println("Error parsing HTML:", err)
return articles
2024-04-27 02:30:28 +00:00
}
// Find and extract each article
doc.Find("article.news-module-feed-item").Each(func(i int, s *goquery.Selection) {
article := make(map[string]string)
// Extract link
link, exists := s.Find("a.news-module-feed-item-image").Attr("href")
if exists {
article["link"] = "https://fallout.bethesda.net" + link
}
// Extract title
title := strings.TrimSpace(s.Find("h3.news-module-feed-item-title").Text())
article["title"] = title
// Extract tag
tag := strings.TrimSpace(s.Find("span.news-module-feed-item-details-tag").Text())
article["tag"] = tag
// Extract date
date := strings.TrimSpace(s.Find("span.news-module-feed-item-details-date").Text())
article["date"] = date
// Extract game
game := strings.TrimSpace(s.Find("span.news-module-feed-item-details-game").Text())
article["game"] = game
// Extract blurb
blurb := strings.TrimSpace(s.Find("p.news-module-feed-item-blurb").Text())
article["blurb"] = blurb
// Extract image URL
imageURL, exists := s.Find("img.news-module-feed-item-image-tag").Attr("src")
if exists {
article["imageURL"] = "https:" + imageURL
}
articles = append(articles, article)
2024-04-27 02:30:28 +00:00
})
return articles
2024-04-27 01:59:05 +00:00
}
2024-04-27 21:05:14 +00:00
func sendNotifications(session *discordgo.Session, html string, channelMap, roleMap map[string]string, specifiedDate string) {
// Extract articles from the HTML content
articles := extractNewsArticles(html)
2024-04-27 02:30:28 +00:00
// Iterate over extracted articles
for _, article := range articles {
tag := article["tag"]
date := article["date"]
link := article["link"]
blurb := article["blurb"]
title := article["title"]
imageURL := article["imageURL"]
2024-04-27 02:30:28 +00:00
// Check if the tag is in the desired tags list
2024-04-27 21:05:14 +00:00
if channelID, ok := channelMap[tag]; ok {
// Check if the article's date matches the specified date
if date == specifiedDate {
// Create a rich embed
embed := &discordgo.MessageEmbed{
Title: title,
Description: blurb,
URL: link,
Image: &discordgo.MessageEmbedImage{
URL: imageURL,
},
Color: 0x00ff00, // Green color for the embed
2024-04-27 02:30:28 +00:00
}
// Send a message to the corresponding Discord channel
2024-04-27 21:05:14 +00:00
message := fmt.Sprintf("New <@&%s> have been released!", roleMap[tag])
_, err := session.ChannelMessageSendComplex(channelID, &discordgo.MessageSend{
Content: message,
Embed: embed,
2024-04-27 21:05:14 +00:00
AllowedMentions: &discordgo.MessageAllowedMentions{}, // Allow mentions
})
2024-04-27 02:30:28 +00:00
if err != nil {
2024-04-27 21:05:14 +00:00
fmt.Printf("Error sending message to Discord channel %s: %s\n", channelID, err)
2024-04-27 02:30:28 +00:00
continue
}
2024-04-27 21:05:14 +00:00
fmt.Println("Message sent to Discord channel:", channelID)
2024-04-27 02:30:28 +00:00
}
}
}
}