-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsevcord.go
143 lines (119 loc) · 3.52 KB
/
sevcord.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
137
138
139
140
141
142
143
package sevcord
import (
"fmt"
"log"
"os"
"os/signal"
"strings"
"sync"
"github.com/bwmarrin/discordgo"
)
var Logger = log.Default()
// MiddlewareFunc accepts context and returns whether or not to continue
type MiddlewareFunc func(ctx Ctx, command string) (ok bool)
type MessageHandler func(ctx Ctx, content string)
type Sevcord struct {
lock *sync.RWMutex
dg *discordgo.Session // Note: only use this to create cmds, give one provided with handlers for user
middleware []MiddlewareFunc
messageHandler MessageHandler
commands map[string]SlashCommandObject
buttonHandlers map[string]ButtonHandler
selectHandlers map[string]SelectHandler
modalHandlers map[string]ModalHandler
}
func (s *Sevcord) RegisterSlashCommand(cmd SlashCommandObject) {
s.lock.Lock()
defer s.lock.Unlock()
s.commands[cmd.name()] = cmd
}
func (s *Sevcord) SetMessageHandler(handler MessageHandler) {
s.messageHandler = handler
}
func New(token string) (*Sevcord, error) {
dg, err := discordgo.New("Bot " + strings.TrimSpace(token))
if err != nil {
return nil, err
}
dg.Identify.Intents = discordgo.IntentsNone
return &Sevcord{
lock: &sync.RWMutex{},
dg: dg,
middleware: make([]MiddlewareFunc, 0),
commands: make(map[string]SlashCommandObject),
buttonHandlers: make(map[string]ButtonHandler),
selectHandlers: make(map[string]SelectHandler),
modalHandlers: make(map[string]ModalHandler),
}, nil
}
// AddMiddleware adds middleware, a function that is run before every command handler is called. Middleware is run in the order it is added. Note that middleware is not run for message handlers
func (s *Sevcord) AddMiddleware(m MiddlewareFunc) {
s.lock.Lock()
defer s.lock.Unlock()
s.middleware = append(s.middleware, m)
}
func (s *Sevcord) AddButtonHandler(id string, handler ButtonHandler) {
s.lock.Lock()
defer s.lock.Unlock()
s.buttonHandlers[id] = handler
}
func (s *Sevcord) AddSelectHandler(id string, handler SelectHandler) {
s.lock.Lock()
defer s.lock.Unlock()
s.selectHandlers[id] = handler
}
// Dg gets the global discordgo session. NOTE: Only use this to add handlers/intents, use the one provided with Ctx for anything else
func (s *Sevcord) Dg() *discordgo.Session {
return s.dg
}
func (s *Sevcord) Listen() {
s.lock.RLock()
// Build commands
cmds := make([]*discordgo.ApplicationCommand, 0, len(s.commands))
for _, cmd := range s.commands {
v := cmd.dg()
dmPermission := false
cmds = append(cmds, &discordgo.ApplicationCommand{
Name: v.Name,
Description: v.Description,
Options: v.Options,
Type: discordgo.ChatApplicationCommand,
DefaultMemberPermissions: cmd.permissions(),
DMPermission: &dmPermission,
})
}
s.lock.RUnlock()
// Handlers
s.dg.AddHandler(s.interactionHandler)
s.dg.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
_, err := s.ApplicationCommandBulkOverwrite(s.State.User.ID, "", cmds)
if err != nil {
Logger.Println("Error updating commands", err)
}
Logger.Println("Bot Ready")
})
if s.messageHandler != nil {
s.dg.AddHandler(func(d *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.Bot {
return
}
ctx := &MessageCtx{
m: m.Message,
d: d,
}
s.messageHandler(ctx, m.Content)
})
}
// Open
if s.messageHandler != nil {
s.dg.Identify.Intents |= discordgo.IntentsGuildMessages
}
s.dg.Open()
// Wait
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
fmt.Println("Gracefully shutting down...")
// Close
s.dg.Close()
}