-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
136 lines (114 loc) · 3.15 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"context"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/bwmarrin/discordgo"
"github.com/otiai10/openaigo"
)
var gptClient *openaigo.Client
var gptContext context.Context
func main() {
// Get Tokens
gptToken := os.Getenv("GPT_TOKEN")
if gptToken == "" {
panic("GPT_TOKEN env variable must be set")
}
discordToken := os.Getenv("DISCORD_CLIENT_TOKEN")
if discordToken == "" {
panic("DISCORD_CLIENT_TOKEN env variable must be set")
}
// Init clients
gptClient = openaigo.NewClient(gptToken)
gptContext = context.Background()
dg, err := discordgo.New("Bot " + discordToken)
if err != nil {
panic(err)
}
// Handle discord messages
dg.AddHandler(SearchHandler)
dg.Identify.Intents = discordgo.IntentGuildMessages
// Open Bot
err = dg.Open()
if err != nil {
panic(err)
}
defer dg.Close()
// Wait close
fmt.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
}
func SearchHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore all messages created by the bot itself
if m.Author.ID == s.State.User.ID {
return
}
// Split message in string array
splittedContent := strings.Split(m.Content, " ")
// If there is not arguments, return
if len(splittedContent) <= 1 {
return
}
// If the message is the GPT command
if splittedContent[0] == "!gpt" {
// Response text message
response := make(chan string)
// Get command arguments string
args := strings.Join(splittedContent[1:], " ")
// Send message before processing GPT search
message, _ := s.ChannelMessageSendReply(m.ChannelID, "Processing...", m.Reference())
// Handle timeouts
go IsContentFlagged(args, response)
select {
case text := <-response:
// Edit sent message with GPT response or GPT error response
s.ChannelMessageEdit(m.ChannelID, message.ID, text)
case <-time.After(1 * time.Minute):
// Edit send message with timeout error
s.ChannelMessageEdit(m.ChannelID, message.ID, "Désolé chakal chu ko là mon reuf")
}
}
}
func IsContentFlagged(args string, response chan string) {
// Request to ChatGPT
gstResp, err := gptClient.CreateModeration(gptContext, openaigo.ModerationCreateRequestBody{
Input: args,
Model: "text-moderation-stable",
})
// Get categories
cat := gstResp.Results[0].Categories
// Check if the content was flagged
if err != nil ||
cat.Hate ||
cat.HateThreatening ||
cat.SelfHarm ||
cat.Sexual ||
cat.SexualMinors ||
cat.Violence ||
cat.ViolenceGraphic {
response <- "Oups! The content is not allowed by OpenAI!"
return
}
// The content is legit, now compute the response
GetGptResponse(args, response)
}
func GetGptResponse(args string, response chan string) {
// Request to ChatGPT
gptResp, err := gptClient.Completion(gptContext, openaigo.CompletionRequestBody{
Model: "text-davinci-003",
Prompt: []string{args},
MaxTokens: 2048, // Max for this model
})
if err != nil || len(gptResp.Choices) < 1 {
response <- "Oups! An error occured..."
return
}
// Set default response message by an error
response <- gptResp.Choices[0].Text
}