vyvanse/cmd/vyvanse/main.go

128 lines
3.3 KiB
Go

package main
import (
"context"
"fmt"
"log"
"net/http"
"git.xeserv.us/xena/vyvanse/bot"
"github.com/Xe/ln"
"github.com/bwmarrin/discordgo"
_ "github.com/joho/godotenv/autoload"
"github.com/namsral/flag"
xkcd "github.com/nishanths/go-xkcd"
opentracing "github.com/opentracing/opentracing-go"
otlog "github.com/opentracing/opentracing-go/log"
zipkin "github.com/openzipkin/zipkin-go-opentracing"
"github.com/robfig/cron"
)
var lastXKCD int
var (
pesterChannel = flag.String("upload-channel", "", "Discord channel ID to upload and announce new XKCD items to")
token = flag.String("token", "", "discord bot token")
zipkinURL = flag.String("zipkin-url", "", "URL for Zipkin traces")
)
func main() {
flag.Parse()
xk := xkcd.NewClient()
dg, err := discordgo.New("Bot " + *token)
if err != nil {
log.Fatal(err)
}
c := cron.New()
comic, err := xk.Latest()
if err != nil {
log.Fatal(err)
}
lastXKCD = comic.Number
c.AddFunc("@daily", func() {
sp, ctx := opentracing.StartSpanFromContext(context.Background(), "daily.xkcd.fetch")
comic, err := xk.Latest()
if err != nil {
log.Println(err)
return
}
if comic.Number > lastXKCD {
sp.LogFields(otlog.String("image.url", comic.ImageURL), otlog.String("target", *pesterChannel))
req, err := http.NewRequest(http.MethodGet, comic.ImageURL, nil)
if err != nil {
ln.Error(ctx, err, ln.F{"action": "make request"})
sp.LogFields(otlog.Error(err))
return
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
ln.Error(ctx, err, ln.F{"action": "http get", "url": comic.ImageURL})
sp.LogFields(otlog.Error(err))
return
}
fname := fmt.Sprintf("%d - %s.png", comic.Number, comic.Title)
msg := fmt.Sprintf("New XKCD comic uploaded: %d - %s\n\n*%s*", comic.Number, comic.Title, comic.Alt)
_, err = dg.ChannelFileSendWithMessage(*pesterChannel, msg, fname, resp.Body)
if err != nil {
ln.Error(ctx, err, ln.F{"action": "send xkcd upload", "to": *pesterChannel})
sp.LogFields(otlog.Error(err))
return
}
lastXKCD = comic.Number
}
})
c.Start()
if *zipkinURL != "" {
collector, err := zipkin.NewHTTPCollector(*zipkinURL)
if err != nil {
ln.FatalErr(context.Background(), err)
}
tracer, err := zipkin.NewTracer(
zipkin.NewRecorder(collector, false, "vyvanse:5000", "vyvanse"))
if err != nil {
ln.FatalErr(context.Background(), err)
}
opentracing.SetGlobalTracer(tracer)
}
cs := bot.NewCommandSet()
cs.Prefix = ">"
cs.AddCmd("hipster", "generates hipster-sounding text", bot.NoPermissions, hipster)
cs.AddCmd("printerfact", "facts about printers", bot.NoPermissions, printerFact)
cs.AddCmd("dice", "roll the dice", bot.NoPermissions, roll)
cs.AddCmd("splattus", "splatoon 2 map rotation status", bot.NoPermissions, spla2nMaps)
dg.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
err := cs.Run(s, m.Message)
if err != nil {
ln.Error(context.Background(), err, ln.F{"action": "run commandSet on message"})
}
})
// Open the websocket and begin listening.
err = dg.Open()
if err != nil {
fmt.Println("error opening connection,", err)
return
}
fmt.Println("Bot is now running. Press CTRL-C to exit.")
// Simple way to keep program running until CTRL-C is pressed.
<-make(chan struct{})
return
}