diff --git a/main.go b/main.go
index b99c64a..29535da 100644
--- a/main.go
+++ b/main.go
@@ -1,59 +1,88 @@
package main
import (
+ "context"
"fmt"
- "context"
"github.com/bwmarrin/discordgo"
- "os"
- "log"
+ "github.com/conneroisu/groq-go"
+ "github.com/joho/godotenv"
+ "log"
+ "math/rand"
+ "os"
"os/signal"
"syscall"
- "math/rand"
- "github.com/conneroisu/groq-go"
- "github.com/joho/godotenv"
)
var (
- Token string
- GroqKey string
+ Token string
+ GroqKey string
+ defaultThreshold = 0.1
+ defaultMaxTokens = 100
+ defaultTemperature float32 = 0.5
+ defaultMessagesCount = 100
+
+ commands = []*discordgo.ApplicationCommand{
+ {
+ Name: "ping",
+ Description: "Replies with Pong!",
+ },
+ }
+
+ commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
+ "ping": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
+ log.Println("ping command")
+ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
+ Data: &discordgo.InteractionResponseData{
+ Content: "Pong!",
+ },
+ })
+ },
+ }
)
func init() {
- err := godotenv.Load()
- if err != nil {
- log.Fatal("Error loading .env file")
- }
+ err := godotenv.Load()
+ if err != nil {
+ log.Fatal("Error loading .env file")
+ }
- Token = os.Getenv("DISCORD_TOKEN")
- GroqKey = os.Getenv("GROQ_API_KEY")
+ Token = os.Getenv("DISCORD_TOKEN")
+ GroqKey = os.Getenv("GROQ_API_KEY")
- if Token == "" {
- log.Fatal("No discord token found in .env file")
- }
+ if Token == "" {
+ log.Fatal("No discord token found in .env file")
+ }
- if GroqKey == "" {
- log.Fatal("No Groq key found in .env file")
- }
+ if GroqKey == "" {
+ log.Fatal("No Groq key found in .env file")
+ }
}
func main() {
dg, err := discordgo.New("Bot " + Token)
if err != nil {
- log.Fatal("Error creating Discord session,", err)
+ log.Fatal("Error creating Discord session,", err)
return
}
- dg.AddHandler(messageCreate)
+ dg.AddHandler(messageCreate)
+ dg.AddHandler(joiningGuild)
+ dg.AddHandler(leavingGuild)
- dg.Identify.Intents = discordgo.IntentsGuildMessages
+ dg.AddHandler(userCommand)
+
+ dg.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds
err = dg.Open()
if err != nil {
- log.Fatal("Error opening connection,", err)
+ log.Fatal("Error opening connection,", err)
return
}
- log.Println("Bot is now running. Press CTRL-C to exit.")
+ checkRegisteredCommands(dg)
+
+ log.Println("Bot is now running. Press CTRL-C to exit.")
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc
@@ -61,104 +90,146 @@ func main() {
dg.Close()
}
-func getMessages(s *discordgo.Session, channelID string, num int) ([]*discordgo.Message, error) {
- if (num <= 100) {
- messages, err := s.ChannelMessages(channelID, num, "", "", "")
- if err != nil {
- log.Println("error getting messages,", err)
- return nil, err
- }
- return messages, nil
- }
+func checkRegisteredCommands(s *discordgo.Session) {
+ for _, v := range s.State.Guilds {
+ registerCommands(s, v.ID)
+ }
+}
- messages := []*discordgo.Message{}
- for num > 0 {
- var toGet int
- if num > 100 {
- toGet = 100
- } else {
- toGet = num
- }
- lastMessage := ""
- if len(messages) > 0 {
- lastMessage = messages[len(messages)-1].ID
- }
- newMessages, err := s.ChannelMessages(channelID, toGet, lastMessage, "", "")
- if err != nil {
- fmt.Println("error getting messages,", err)
- return nil, err
- }
- messages = append(messages, newMessages...)
- num -= toGet
- }
- return messages, nil
+func registerCommands(s *discordgo.Session, guildID string) {
+ registeredCommands := make([]*discordgo.ApplicationCommand, len(commands))
+ for i, v := range commands {
+ cmd, err := s.ApplicationCommandCreate(s.State.User.ID, guildID, v)
+ if err != nil {
+ log.Panicf("Cannot create '%v' command: %v", v.Name, err)
+ }
+ registeredCommands[i] = cmd
+ }
+}
+
+func userCommand(s *discordgo.Session, i *discordgo.InteractionCreate) {
+ handler, ok := commandHandlers[i.ApplicationCommandData().Name]
+ if !ok {
+ return
+ }
+ handler(s, i)
+}
+
+func joiningGuild(s *discordgo.Session, m *discordgo.GuildCreate) {
+ registerCommands(s, m.ID)
+}
+
+func leavingGuild(s *discordgo.Session, m *discordgo.GuildDelete) {
+ for _, v := range commands {
+ err := s.ApplicationCommandDelete(s.State.User.ID, m.ID, v.ID)
+ if err != nil {
+ log.Panicf("Cannot delete '%v' command: %v", v.Name, err)
+ }
+ }
+}
+
+func getMessages(s *discordgo.Session, channelID string, num int) ([]*discordgo.Message, error) {
+ if num <= 100 {
+ messages, err := s.ChannelMessages(channelID, num, "", "", "")
+ if err != nil {
+ log.Println("error getting messages,", err)
+ return nil, err
+ }
+ return messages, nil
+ }
+
+ messages := []*discordgo.Message{}
+ for num > 0 {
+ var toGet int
+ if num > 100 {
+ toGet = 100
+ } else {
+ toGet = num
+ }
+ lastMessage := ""
+ if len(messages) > 0 {
+ lastMessage = messages[len(messages)-1].ID
+ }
+ newMessages, err := s.ChannelMessages(channelID, toGet, lastMessage, "", "")
+ if err != nil {
+ fmt.Println("error getting messages,", err)
+ return nil, err
+ }
+ messages = append(messages, newMessages...)
+ num -= toGet
+ }
+ return messages, nil
}
func botMentioned(s *discordgo.Session, m *discordgo.MessageCreate) bool {
- for i := range m.Mentions {
- if m.Mentions[i].ID == s.State.User.ID {
- return true
- }
- }
- return false
+ for i := range m.Mentions {
+ if m.Mentions[i].ID == s.State.User.ID {
+ return true
+ }
+ }
+ return false
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
- if m.Author.ID == s.State.User.ID {
- return
- }
+ if m.Author.ID == s.State.User.ID {
+ return
+ }
- rand := rand.Intn(100)
+ rand := rand.Float32()
- if rand > 10 && !botMentioned(s, m){
- return
- }
+ if rand > float32(defaultThreshold) && !botMentioned(s, m) {
+ return
+ }
- messages, err := getMessages(s, m.ChannelID, 100)
- if err != nil {
- fmt.Println("error getting messages,", err)
- return
- }
- messagesFormatted := ""
- for i := range messages {
- if messages[i].Author.ID == s.State.User.ID {
- continue
- }
- messagesFormatted = messagesFormatted + "<" + messages[i].Author.ID + "> " + messages[i].Content + "\n"
- }
+ messages, err := getMessages(s, m.ChannelID, 100)
+ if err != nil {
+ fmt.Println("error getting messages,", err)
+ return
+ }
+ messagesFormatted := ""
+ for i := range messages {
+ if messages[i].Author.ID == s.State.User.ID {
+ continue
+ }
+ messagesFormatted = messagesFormatted + "<" + messages[i].Author.ID + "> " + messages[i].Content + "\n"
+ }
- question := "Tu fais partie d'une conversation. Tu n'as pas conscience d'etre un bot. Reponds de maniere goofy. Ta reponse doit etre tres courte, une phrase ou deux.\n"
- question += "\n" + messagesFormatted + "\n"
- response, err := askGroq(context.Background(), question)
- if err != nil {
- s.ChannelMessageSend(m.ChannelID, "There was an error getting the response.")
- return
- }
- s.ChannelMessageSend(m.ChannelID, response)
+ question := "Tu fais partie d'une conversation. Tu n'as pas conscience d'etre un bot. Reponds de maniere goofy. Ta reponse doit etre tres courte, une phrase ou deux.\n"
+ question += "\n" + messagesFormatted + "\n"
+ response, err := askGroq(context.Background(), question)
+ if err != nil {
+ if botMentioned(s, m) {
+ s.ChannelMessageSendReply(m.ChannelID, "There was an error getting the response.", m.Reference())
+ } else {
+ s.ChannelMessageSend(m.ChannelID, "There was an error getting the response.")
+ }
+ return
+ }
+ s.ChannelMessageSendReply(m.ChannelID, response, m.Reference())
}
-func askGroq(ctx context.Context, message string) (string,error) {
- client, err := groq.NewClient(GroqKey)
- if err != nil {
- fmt.Println("error creating Groq client,", err)
- return "", err
- }
+func askGroq(ctx context.Context, message string) (string, error) {
+ client, err := groq.NewClient(GroqKey)
+ if err != nil {
+ fmt.Println("error creating Groq client,", err)
+ return "", err
+ }
- resp, err := client.CreateChatCompletion(ctx, groq.ChatCompletionRequest{
- Model: groq.Llama318BInstant,
- Messages: []groq.ChatCompletionMessage{
- {
- Role: groq.ChatMessageRoleUser,
- Content: message,
- },
- },
- MaxTokens: 100,
- })
- if err != nil {
- fmt.Println("error creating Groq completion,", err)
- return "", err
- }
+ resp, err := client.CreateChatCompletion(ctx, groq.ChatCompletionRequest{
+ Model: groq.Llama318BInstant,
+ Messages: []groq.ChatCompletionMessage{
+ {
+ Role: groq.ChatMessageRoleUser,
+ Content: message,
+ },
+ },
+ MaxTokens: defaultMaxTokens,
+ Temperature: defaultTemperature,
+ })
+ if err != nil {
+ fmt.Println("error creating Groq completion,", err)
+ return "", err
+ }
-
- return string(resp.Choices[0].Message.Content), nil
+ return string(resp.Choices[0].Message.Content), nil
}