-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.go
135 lines (119 loc) · 3.42 KB
/
bot.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
package gokord
import (
"errors"
"fmt"
"github.com/anhgelus/gokord/utils"
"github.com/bwmarrin/discordgo"
"math/rand/v2"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
var (
Debug = true
ErrBadStatusType = errors.New("bad status type, please use the constant")
ErrStatusUrlNotFound = errors.New("status url not found")
)
const (
GameStatus = 0
WatchStatus = 1
StreamingStatus = 2
ListeningStatus = 3
AdminPermission int64 = discordgo.PermissionManageServer // AdminPermission of the command
)
// Bot is the representation of a discord bot
type Bot struct {
Token string // Token of the Bot
Status []*Status // Status of the Bot
Commands []*GeneralCommand // Commands of the Bot, use NewCommand to create easily a new command
//Handlers []interface{} // Handlers of the Bot
AfterInit func(s *discordgo.Session) // AfterInit is called after the initialization process of the Bot
Version *Version
Innovations []*Innovation
Name string
}
// Status contains all required information for updating the status
type Status struct {
Type int // Type of the Status (use GameStatus or WatchStatus or StreamingStatus or ListeningStatus)
Content string // Content of the Status
Url string // Url of the StreamingStatus
}
// Start the Bot (blocking instruction)
func (b *Bot) Start() {
dg, err := discordgo.New("Bot " + b.Token) // New connection to the discord API with bot token
if err != nil {
utils.SendAlert("bot.go - Token", err.Error())
return
}
err = dg.Open() // Starts the bot
if err != nil {
utils.SendAlert("bot.go - Start", err.Error())
}
dg.Identify.Intents = discordgo.IntentsAll
var wg sync.WaitGroup
st1 := time.Now()
// register commands
wg.Add(1)
go func() {
b.updateCommands(dg)
utils.SendSuccess("Commands updated")
wg.Done()
}()
b.setupCommandsHandlers(dg)
//for h := range b.Handlers {
// dg.AddHandler(h)
//}
// do after init (mainly used to register handlers)
b.AfterInit(dg)
// wait until all setup goroutines are finished
wg.Wait()
st2 := time.Now()
delta := float64(st2.Unix() - st1.Unix())
to := dg.Client.Timeout.Seconds()
// if the setup was faster than the http client timeout, wait
if delta < dg.Client.Timeout.Seconds() {
time.Sleep(time.Duration(to-delta) * time.Second)
}
utils.SendSuccess(fmt.Sprintf("Bot started as %s", dg.State.User.Username))
utils.NewTimer(30*time.Second, func(stop chan struct{}) {
if b.Status == nil {
stop <- struct{}{}
return
}
l := len(b.Status)
r := rand.New(rand.NewPCG(uint64(time.Now().Unix()), uint64(l))).UintN(uint(l))
s := b.Status[r]
if s.Type == GameStatus {
err = dg.UpdateGameStatus(0, s.Content)
} else if s.Type == WatchStatus {
err = dg.UpdateWatchStatus(0, s.Content)
} else if s.Type == StreamingStatus {
if s.Url == "" {
err = ErrStatusUrlNotFound
} else {
err = dg.UpdateStreamingStatus(0, s.Content, s.Url)
}
} else if s.Type == ListeningStatus {
err = dg.UpdateListeningStatus(s.Content)
} else {
err = ErrBadStatusType
}
if err != nil {
utils.SendAlert("bot.go - Update status", err.Error())
err = nil
}
})
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc
if Debug {
utils.SendDebug("Unregistering local commands")
b.unregisterGuildCommands(dg)
}
err = dg.Close() // Bot Shutdown
if err != nil {
utils.SendAlert("bot.go - Shutdown", err.Error())
}
}