BibleBot/main.go

247 lines
5.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"bufio"
"database/sql"
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/xconstruct/go-pushbullet"
)
const NAME string = "Tʜᴇ Lʀᴅ"
var BibleDB *sql.DB
var BibleQuery *sql.Stmt
var Client *RDramaClient
var WAIT_TIME time.Duration
var ONE_SEC time.Duration
var BibleBotID int
func main() {
ERRCOUNT := 0
WAIT_TIME, err := time.ParseDuration("1m")
if err != nil {
log.Fatal("Error parsing time")
}
time.Sleep(WAIT_TIME)
ONE_SEC, err = time.ParseDuration("1s")
if err != nil {
log.Fatal("Error parsing time 2")
}
fmt.Printf("Running...\n")
siteURL := os.Getenv("RDRAMA_URL")
if siteURL == "" {
log.Fatal("RDRAMA_URL environment variable not set")
}
siteToken := os.Getenv("RDRAMA_API_TOKEN")
if siteToken == "" {
log.Fatal("RDRAMA_API_TOKEN environment variable not set")
}
botId := os.Getenv("BIBLEBOT_ID")
if botId == "" {
log.Fatal("BIBLEBOT_ID environment variable not set")
}
BibleBotID, err = strconv.Atoi(botId)
if err != nil {
log.Fatal("Error loading BIBLEBOT_ID: ", botId)
}
Client = NewRDramaClient(siteURL, siteToken)
username := os.Getenv("MARIADB_USER")
password := os.Getenv("MARIADB_PASSWORD")
host := os.Getenv("BIBLEDB_HOST")
database := os.Getenv("MARIADB_DATABASE")
for ERRCOUNT < 5 {
BibleDB, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", username, password, host, database))
if err != nil {
fmt.Println("ERROR connecting: ", err)
fmt.Println("DB string: ", fmt.Sprintf("%s:%s@tcp(%s)/%s", username, password, host, database))
ERRCOUNT = ERRCOUNT + 1
time.Sleep(WAIT_TIME)
} else {
ERRCOUNT = 0
break
}
}
defer BibleDB.Close()
BibleQuery, err = BibleDB.Prepare("SELECT t FROM t_web WHERE id BETWEEN ? AND ?")
if err != nil {
fmt.Println(err)
log.Fatal("Unable to prepare query")
}
defer BibleQuery.Close()
now := time.Now()
lastrun := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()-1, 0, 0, 0, time.UTC)
file, err := os.Open("lastrun.txt")
if err == nil {
// Create a new scanner to read the file
scanner := bufio.NewScanner(file)
// Read the first line of the file
scanner.Scan()
line := scanner.Text()
// Convert the line to an integer
num, err := strconv.ParseInt(line, 10, 64)
if err == nil {
newTime := time.Unix(num, 0)
// fmt.Println("New time: ", newTime)
if newTime != time.Unix(0, 0) {
lastrun = newTime
}
} else {
fmt.Println("error parsing time", err)
}
file.Close()
} else {
fmt.Println("Err opening lastrun: ", err)
}
for ERRCOUNT < 5 {
fmt.Println("\n\n-------------------------------------------------------")
fmt.Printf("Posts between %v - %v\n", lastrun, now)
posts, err := Client.GetPosts(SearchParams{
Hole: "dankchristianmemes",
After: lastrun,
Before: now,
})
if err == nil {
fmt.Printf("Found posts: %d\n", len(posts))
for _, post := range posts {
// fmt.Printf("%s: %s\n", comment.AuthorName, comment.Text)
if post.Author.ID != BibleBotID { // originally forgot this lol
handleAndReply(fmt.Sprintf("%s\n%s", post.Title, post.Text), fmt.Sprintf("p_%v", post.ID))
} else {
fmt.Println("Skipping own post")
}
}
} else {
ERRCOUNT = ERRCOUNT + 1
time.Sleep(WAIT_TIME)
now = time.Now()
continue
}
fmt.Printf("Comments between %v - %v\n", lastrun, now)
comments, err := Client.GetComments(SearchParams{
Hole: "dankchristianmemes",
After: lastrun,
Before: now,
})
if err == nil {
fmt.Printf("Found comments: %d\n", len(comments))
for _, comment := range comments {
// fmt.Printf("%s: %s\n", comment.AuthorName, comment.Text)
if comment.Author.ID != BibleBotID {
handleAndReply(comment.Text, fmt.Sprintf("c_%v", comment.ID))
} else {
fmt.Println("Skipping own comment")
}
// Client.UpvoteComment(comment.ID) // not allowed for bots
}
lastrun = now.Add(ONE_SEC)
file, err = os.Create("lastrun.txt")
if err == nil {
_, err = file.WriteString(strconv.FormatInt(lastrun.Unix(), 10))
if err != nil {
fmt.Println("FILE ERROR: ", err)
}
err = file.Sync()
if err != nil {
fmt.Println("FILE ERROR: ", err)
}
file.Close()
}
if err != nil {
fmt.Println("FILE ERROR: ", err)
}
} else {
fmt.Println(err)
ERRCOUNT = ERRCOUNT + 1
}
time.Sleep(WAIT_TIME)
now = time.Now()
}
// tell pushbullet that Biblebot failed
pushbullet_key := os.Getenv("PUSHBULLET_KEY")
pushbullet_device := os.Getenv("PUSHBULLET_DEVICE_ID")
if pushbullet_key != "" && pushbullet_device != "" {
pb := pushbullet.New(pushbullet_key)
err = pb.PushNote(pushbullet_device, "Biblebot shut down due to error", err.Error())
if err != nil {
fmt.Println("Pushbullet error reporting failed")
}
}
}
func handleAndReply(text string, parent_fullname string) {
refs := GetReferences(strings.ToUpper(text))
if len(refs) == 0 {
return
}
var post strings.Builder
for _, ref := range refs {
rows, err := BibleQuery.Query(ref.StartKey, ref.EndKey)
if err != nil {
fmt.Println(err)
continue
}
canName, err := ref.CanonicalName()
post.WriteString("**")
if err != nil {
post.WriteString(ref.RegexMatch)
} else {
post.WriteString(canName)
}
post.WriteString("**\n> ")
for rows.Next() {
var verse string
err = rows.Scan(&verse)
if err != nil {
fmt.Println(err)
continue
}
verse = strings.ReplaceAll(verse, "Yahweh", NAME)
verse = strings.ReplaceAll(verse, "\n", "\n> ")
post.WriteString(verse)
post.WriteString(" ")
}
rows.Close()
post.WriteString("\n\n")
}
fmt.Println(post.String())
err := Client.PostComment(post.String(), parent_fullname)
if err != nil {
fmt.Println(err)
} else {
time.Sleep(ONE_SEC)
}
}