package pagecomment import ( "fmt" "github.com/PuerkitoBio/goquery" "github.com/bwmarrin/discordgo" "github.com/rs/zerolog/log" "github.com/velour/catbase/bot" "github.com/velour/catbase/config" "github.com/velour/catbase/connectors/discord" "net/http" "regexp" "strings" ) type PageComment struct { b bot.Bot c *config.Config } func New(b bot.Bot) bot.Plugin { p := &PageComment{ b: b, c: b.Config(), } p.register() return p } func (p *PageComment) register() { p.b.RegisterTable(p, bot.HandlerTable{ { Kind: bot.Startup, IsCmd: false, Regex: regexp.MustCompile(`.*`), Handler: func(r bot.Request) bool { switch conn := r.Conn.(type) { case *discord.Discord: p.registerCmds(conn) } return false }, }, {Kind: bot.Message, IsCmd: true, Regex: regexp.MustCompile(`(?i)^url (?P\S+) (?P.+)`), HelpText: "Comment on a URL", Handler: p.handleURLReq}, }) } func (p *PageComment) handleURLReq(r bot.Request) bool { fullText := r.Msg.Body fullComment := fullText[strings.Index(fullText, r.Values["comment"]):] u := r.Values["url"] if strings.HasPrefix(u, "<") && strings.HasSuffix(u, ">") { u = u[1 : len(u)-1] } ua := p.c.Get("url.useragent", "catbase/1.0") msg := handleURL(u, fullComment, r.Msg.User.Name, ua) p.b.Send(r.Conn, bot.Delete, r.Msg.Channel, r.Msg.ID) p.b.Send(r.Conn, bot.Message, r.Msg.Channel, msg) return true } func (p *PageComment) handleURLCmd(conn bot.Connector) func(*discordgo.Session, *discordgo.InteractionCreate) { return func(s *discordgo.Session, i *discordgo.InteractionCreate) { u := i.ApplicationCommandData().Options[0].StringValue() cmt := i.ApplicationCommandData().Options[1].StringValue() ua := p.c.Get("url.useragent", "catbase/1.0") msg := handleURL(u, cmt, "", ua) err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: msg, }, }) if err != nil { log.Error().Err(err).Msg("") return } } } func handleURL(u, cmt, who, ua string) string { if who != "" { who = who + ": " } client := http.Client{} req, err := http.NewRequest(http.MethodGet, u, nil) if err != nil { return "Couldn't parse that URL" } req.Header.Set("User-Agent", ua) resp, err := client.Do(req) if err != nil || resp.StatusCode > 299 { log.Error().Err(err).Int("status", resp.StatusCode).Msgf("error with request") return "Couldn't get that URL" } doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { return "Couldn't parse that URL" } wait := make(chan string, 1) sel := doc.Find("title") if sel.Length() == 0 { return fmt.Sprintf("%s%s\n(<%s>)", who, cmt, u) } sel.First().Each(func(i int, s *goquery.Selection) { wait <- fmt.Sprintf("> %s\n%s%s\n(<%s>)", s.Text(), who, cmt, u) }) return <-wait } func (p *PageComment) registerCmds(d *discord.Discord) { cmd := discordgo.ApplicationCommand{ Name: "url", Description: "comment on a URL with its title", Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionString, Name: "url", Description: "What URL would you like", Required: true, }, { Type: discordgo.ApplicationCommandOptionString, Name: "comment", Description: "Your comment", Required: true, }, }, } if err := d.RegisterSlashCmd(cmd, p.handleURLCmd(d)); err != nil { log.Error().Err(err).Msg("could not register emojy command") } }