mirror of
https://github.com/jesperbakhandskemager/OpenBibleDiscord.git
synced 2024-07-22 12:42:20 +01:00
274 lines
6.3 KiB
Go
274 lines
6.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"log"
|
||
|
"os"
|
||
|
"os/signal"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/bwmarrin/discordgo"
|
||
|
"github.com/gocolly/colly"
|
||
|
)
|
||
|
|
||
|
type BibleStructure struct {
|
||
|
bibleref string
|
||
|
verse string
|
||
|
}
|
||
|
|
||
|
func TopicScraper(keyword string) []BibleStructure {
|
||
|
|
||
|
c := colly.NewCollector()
|
||
|
c.SetRequestTimeout(120 * time.Second)
|
||
|
verses := make([]BibleStructure, 0)
|
||
|
|
||
|
c.OnHTML("div.verse", func(h *colly.HTMLElement) {
|
||
|
v := BibleStructure{}
|
||
|
|
||
|
v.bibleref = h.ChildText("a")
|
||
|
v.verse = h.ChildText("p")
|
||
|
|
||
|
verses = append(verses, v)
|
||
|
})
|
||
|
|
||
|
c.Visit("https://www.openbible.info/topics/" + keyword)
|
||
|
|
||
|
return verses
|
||
|
}
|
||
|
|
||
|
func VerseBuilder(search string, n int) string {
|
||
|
// If user enters negative number
|
||
|
if n < 1 {
|
||
|
return "Invalid"
|
||
|
}
|
||
|
// Set max ammount of verses to 5
|
||
|
if n > 5 {
|
||
|
n = 5
|
||
|
}
|
||
|
|
||
|
topic := TopicScraper(search)
|
||
|
|
||
|
topicLen := len(topic)
|
||
|
// If site can't find any topics
|
||
|
if topicLen == 0 {
|
||
|
return "No results"
|
||
|
}
|
||
|
|
||
|
var returnString strings.Builder
|
||
|
|
||
|
// String to be returned
|
||
|
returnString.WriteString("Topic: " + search + "\n")
|
||
|
|
||
|
// Populate return string
|
||
|
for i := 0; i < n; i++ {
|
||
|
if i < topicLen {
|
||
|
returnString.WriteString(topic[i].bibleref + "\n" + "> " + topic[i].verse + "\n\n")
|
||
|
} else {
|
||
|
return returnString.String()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return returnString.String()
|
||
|
}
|
||
|
|
||
|
// Bot parameters
|
||
|
var (
|
||
|
GuildID = flag.String("guild", "", "Test guild ID. If not passed - bot registers commands globally")
|
||
|
BotToken = flag.String("token", "[YOUR-DISCORD-TOKEN]", "Bot access token")
|
||
|
RemoveCommands = flag.Bool("rmcmd", true, "Remove all commands after shutdowning or not")
|
||
|
)
|
||
|
|
||
|
var s *discordgo.Session
|
||
|
|
||
|
func init() { flag.Parse() }
|
||
|
|
||
|
func init() {
|
||
|
var err error
|
||
|
s, err = discordgo.New("Bot " + *BotToken)
|
||
|
if err != nil {
|
||
|
log.Fatalf("Invalid bot parameters: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
commands = []*discordgo.ApplicationCommand{
|
||
|
{
|
||
|
Name: "bible-topic",
|
||
|
Description: "What does the bible say about a topic?",
|
||
|
Type: discordgo.ChatApplicationCommand,
|
||
|
Options: []*discordgo.ApplicationCommandOption{
|
||
|
{
|
||
|
Name: "topic",
|
||
|
Description: "A topic in the bible",
|
||
|
Type: discordgo.ApplicationCommandOptionString,
|
||
|
Required: true,
|
||
|
Autocomplete: true,
|
||
|
},
|
||
|
{
|
||
|
Name: "amount",
|
||
|
Description: "Amount of verses to see (max 5)",
|
||
|
Type: discordgo.ApplicationCommandOptionInteger,
|
||
|
Required: false,
|
||
|
Autocomplete: false,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
||
|
"bible-topic": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||
|
switch i.Type {
|
||
|
case discordgo.InteractionApplicationCommand:
|
||
|
data := i.ApplicationCommandData()
|
||
|
amountOfVerses := 1
|
||
|
if len(data.Options) > 1 {
|
||
|
amountOfVerses = int(data.Options[1].IntValue())
|
||
|
}
|
||
|
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||
|
Data: &discordgo.InteractionResponseData{
|
||
|
Content: VerseBuilder(data.Options[0].StringValue(), amountOfVerses),
|
||
|
},
|
||
|
})
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
// Autocomplete options introduce a new interaction type (8) for returning custom autocomplete results.
|
||
|
case discordgo.InteractionApplicationCommandAutocomplete:
|
||
|
data := i.ApplicationCommandData()
|
||
|
choices := []*discordgo.ApplicationCommandOptionChoice{
|
||
|
{
|
||
|
Name: "10 commandments",
|
||
|
Value: "10 commandments",
|
||
|
},
|
||
|
{
|
||
|
Name: "homosexaulity",
|
||
|
Value: "homosexaulity",
|
||
|
},
|
||
|
{
|
||
|
Name: "forgiveness",
|
||
|
Value: "forgiveness",
|
||
|
},
|
||
|
{
|
||
|
Name: "sodom",
|
||
|
Value: "sodom",
|
||
|
},
|
||
|
{
|
||
|
Name: "signs of the end times",
|
||
|
Value: "signs of the end times",
|
||
|
},
|
||
|
{
|
||
|
Name: "bitter woman",
|
||
|
Value: "bitter woman",
|
||
|
},
|
||
|
{
|
||
|
Name: "the purpose of the woman",
|
||
|
Value: "the purpose of the woman",
|
||
|
},
|
||
|
{
|
||
|
Name: "woman",
|
||
|
Value: "woman",
|
||
|
},
|
||
|
{
|
||
|
Name: "abortion",
|
||
|
Value: "abortion",
|
||
|
},
|
||
|
{
|
||
|
Name: "harming your body",
|
||
|
Value: "harming your body",
|
||
|
},
|
||
|
{
|
||
|
Name: "healthy eating",
|
||
|
Value: "healthy eating",
|
||
|
},
|
||
|
{
|
||
|
Name: "confrontation",
|
||
|
Value: "confrontation",
|
||
|
},
|
||
|
{
|
||
|
Name: "confusion",
|
||
|
Value: "confusion",
|
||
|
},
|
||
|
{
|
||
|
Name: "non believers",
|
||
|
Value: "non believers",
|
||
|
},
|
||
|
{
|
||
|
Name: "not giving up",
|
||
|
Value: "not giving up",
|
||
|
},
|
||
|
{
|
||
|
Name: "truth",
|
||
|
Value: "truth",
|
||
|
},
|
||
|
{
|
||
|
Name: "transvestites",
|
||
|
Value: "transvestites",
|
||
|
},
|
||
|
{
|
||
|
Name: "telling the truth",
|
||
|
Value: "telling the truth",
|
||
|
},
|
||
|
{
|
||
|
Name: "not telling the truth",
|
||
|
Value: "not telling the truth",
|
||
|
},
|
||
|
// And so on, up to 25 choices
|
||
|
}
|
||
|
|
||
|
if data.Options[0].StringValue() != "" {
|
||
|
choices = append(choices, &discordgo.ApplicationCommandOptionChoice{
|
||
|
Name: data.Options[0].StringValue(), // To get user input you just get value of the autocomplete option.
|
||
|
Value: data.Options[0].StringValue(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||
|
Type: discordgo.InteractionApplicationCommandAutocompleteResult,
|
||
|
Data: &discordgo.InteractionResponseData{
|
||
|
Choices: choices, // This is basically the whole purpose of autocomplete interaction - return custom options to the user.
|
||
|
},
|
||
|
})
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { log.Println("Bot is up!") })
|
||
|
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||
|
if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok {
|
||
|
h(s, i)
|
||
|
}
|
||
|
})
|
||
|
err := s.Open()
|
||
|
if err != nil {
|
||
|
log.Fatalf("Cannot open the session: %v", err)
|
||
|
}
|
||
|
defer s.Close()
|
||
|
|
||
|
createdCommands, err := s.ApplicationCommandBulkOverwrite(s.State.User.ID, *GuildID, commands)
|
||
|
|
||
|
if err != nil {
|
||
|
log.Fatalf("Cannot register commands: %v", err)
|
||
|
}
|
||
|
|
||
|
stop := make(chan os.Signal, 1)
|
||
|
signal.Notify(stop, os.Interrupt)
|
||
|
<-stop
|
||
|
log.Println("Gracefully shutting down")
|
||
|
|
||
|
if *RemoveCommands {
|
||
|
for _, cmd := range createdCommands {
|
||
|
err := s.ApplicationCommandDelete(s.State.User.ID, *GuildID, cmd.ID)
|
||
|
if err != nil {
|
||
|
log.Fatalf("Cannot delete %q command: %v", cmd.Name, err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|