feature/improvements #8
@@ -73,7 +73,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
b, err := bolt.New(bolt.WithLogLevel(bolt.LogLevelAll),
|
b, err := bolt.New(bolt.WithLogLevel(bolt.LogLevelAll),
|
||||||
bolt.WithMaxGoroutines(50),
|
bolt.WithMaxGoroutines(150),
|
||||||
bolt.WithPermissions(bolt.MessagePermissions, bolt.AdminPermissions))
|
bolt.WithPermissions(bolt.MessagePermissions, bolt.AdminPermissions))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
19
bolt.go
19
bolt.go
@@ -33,8 +33,7 @@ type bolt struct {
|
|||||||
pool chan struct{}
|
pool chan struct{}
|
||||||
maxRoutines int
|
maxRoutines int
|
||||||
msgHandlerf Payload
|
msgHandlerf Payload
|
||||||
admin bool
|
// admin bool
|
||||||
tools AdminToolBox
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bolt interface {
|
type Bolt interface {
|
||||||
@@ -69,7 +68,7 @@ func New(opts ...Option) (Bolt, error) {
|
|||||||
logLvl: LogLevelAll,
|
logLvl: LogLevelAll,
|
||||||
indicator: DEFAULT_INDICATOR,
|
indicator: DEFAULT_INDICATOR,
|
||||||
wg: sync.WaitGroup{},
|
wg: sync.WaitGroup{},
|
||||||
admin: false,
|
// admin: false,
|
||||||
maxRoutines: DEFAULT_MAX_GOROUTINES,
|
maxRoutines: DEFAULT_MAX_GOROUTINES,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ func New(opts ...Option) (Bolt, error) {
|
|||||||
|
|
||||||
//options can change these fields so we must create post-opts
|
//options can change these fields so we must create post-opts
|
||||||
b.pool = make(chan struct{}, b.maxRoutines)
|
b.pool = make(chan struct{}, b.maxRoutines)
|
||||||
b.tools = NewToolbox(b)
|
// b.tools = NewToolbox(b)
|
||||||
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
@@ -173,7 +172,7 @@ func (b *bolt) msgEventHandler(s *dg.Session, msg *dg.MessageCreate) {
|
|||||||
ChannelID: channel.ID,
|
ChannelID: channel.ID,
|
||||||
Server: server.Name,
|
Server: server.Name,
|
||||||
ServerID: server.ID,
|
ServerID: server.ID,
|
||||||
sesh: b,
|
// sesh: b,
|
||||||
}
|
}
|
||||||
|
|
||||||
w := strings.Fields(msg.Content)
|
w := strings.Fields(msg.Content)
|
||||||
@@ -240,7 +239,10 @@ func (b *bolt) msgEventHandler(s *dg.Session, msg *dg.MessageCreate) {
|
|||||||
|
|
||||||
func (b *bolt) handleMessage(event *Message) error {
|
func (b *bolt) handleMessage(event *Message) error {
|
||||||
if b.msgHandlerf != nil {
|
if b.msgHandlerf != nil {
|
||||||
return b.msgHandlerf(event, b.tools)
|
return b.msgHandlerf(&Context{
|
||||||
|
Message: event,
|
||||||
|
bolt: b,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -277,7 +279,10 @@ func (b *bolt) handleCommand(msg *Message, lg int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = run.Payload(msg, b.tools)
|
err = run.Payload(&Context{
|
||||||
|
Message: msg,
|
||||||
|
bolt: b,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("encountered an error while handling command (%s): %e", msg.Words[0], err)
|
return fmt.Errorf("encountered an error while handling command (%s): %e", msg.Words[0], err)
|
||||||
}
|
}
|
||||||
|
|||||||
55
command.go
55
command.go
@@ -13,37 +13,34 @@ type Command struct {
|
|||||||
Roles []string //roles that can use command, if none are set anyone can run the command
|
Roles []string //roles that can use command, if none are set anyone can run the command
|
||||||
}
|
}
|
||||||
|
|
||||||
// command payload functions, any strings returned are sent as a response to the command
|
// type adminToolbox struct {
|
||||||
type Payload func(msg *Message, admin AdminToolBox) error
|
// *bolt
|
||||||
|
// }
|
||||||
|
// type AdminToolBox interface {
|
||||||
|
// Timeout(userId, serverId string, duration time.Time) error
|
||||||
|
// ClearTimeout(userId, serverId string) error
|
||||||
|
// Mute(userId, serverId string) error
|
||||||
|
// Unmute(userId, serverId string) error
|
||||||
|
// }
|
||||||
|
|
||||||
type adminToolbox struct {
|
// func NewToolbox(b *bolt) AdminToolBox {
|
||||||
*bolt
|
// return &adminToolbox{
|
||||||
}
|
// bolt: b,
|
||||||
type AdminToolBox interface {
|
// }
|
||||||
Timeout(userId, serverId string, duration time.Time) error
|
// }
|
||||||
ClearTimeout(userId, serverId string) error
|
|
||||||
Mute(userId, serverId string) error
|
|
||||||
Unmute(userId, serverId string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewToolbox(b *bolt) AdminToolBox {
|
// func (a *adminToolbox) Timeout(userId, serverId string, duration time.Time) error {
|
||||||
return &adminToolbox{
|
// return a.GuildMemberTimeout(serverId, userId, &duration)
|
||||||
bolt: b,
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *adminToolbox) Timeout(userId, serverId string, duration time.Time) error {
|
// func (a *adminToolbox) ClearTimeout(userId, serverId string) error {
|
||||||
return a.GuildMemberTimeout(serverId, userId, &duration)
|
// return a.GuildMemberTimeout(serverId, userId, nil)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (a *adminToolbox) ClearTimeout(userId, serverId string) error {
|
// func (a *adminToolbox) Mute(userId, serverId string) error {
|
||||||
return a.GuildMemberTimeout(serverId, userId, nil)
|
// return a.GuildMemberMute(serverId, userId, true)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (a *adminToolbox) Mute(userId, serverId string) error {
|
// func (a *adminToolbox) Unmute(userId, serverId string) error {
|
||||||
return a.GuildMemberMute(serverId, userId, true)
|
// return a.GuildMemberMute(serverId, userId, false)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (a *adminToolbox) Unmute(userId, serverId string) error {
|
|
||||||
return a.GuildMemberMute(serverId, userId, false)
|
|
||||||
}
|
|
||||||
|
|||||||
170
message.go
170
message.go
@@ -2,6 +2,7 @@ package bolt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
dg "github.com/bwmarrin/discordgo"
|
dg "github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
@@ -11,89 +12,8 @@ const (
|
|||||||
MSG_MAX_LENGTH = 2000
|
MSG_MAX_LENGTH = 2000
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message contains basic information about the messages received and provides a few methods
|
// command payload functions, any strings returned are sent as a response to the command
|
||||||
// for handling replies, bans, timeouts, reaction, and deletion. All Discord utilities will use
|
type Payload func(c *Context) error
|
||||||
// a timeout to prevent hanging for too long, this timeout can be customized with the WithTimeout
|
|
||||||
// option.
|
|
||||||
type Message struct {
|
|
||||||
Author Author
|
|
||||||
ID string //message ID
|
|
||||||
Words []string //message data split on whitespaces
|
|
||||||
Content string //entire message data string
|
|
||||||
Channel string //name of channel message was sent in
|
|
||||||
ChannelID string //ID of channel message was sent in
|
|
||||||
Server string //name of guild message was sent in
|
|
||||||
ServerID string //ID of guild message was sent in
|
|
||||||
Attachments []MessageAttachment //any attachments bound to the message
|
|
||||||
Mentions []*dg.User
|
|
||||||
sesh *bolt
|
|
||||||
}
|
|
||||||
|
|
||||||
type Author struct {
|
|
||||||
Name string
|
|
||||||
ID string
|
|
||||||
Roles []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// React applies reaction to the message
|
|
||||||
func (m *Message) React(emoji Reaction) error {
|
|
||||||
return m.sesh.MessageReactionAdd(m.ChannelID, m.ID, fmt.Sprint(emoji))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Respond sends a response to the message, handling chunking if the message exceeds max length
|
|
||||||
func (m *Message) Respond(res string) error {
|
|
||||||
if len(res) > MSG_MAX_LENGTH {
|
|
||||||
for len(res) > 0 {
|
|
||||||
//send full chunk size allowed by discord
|
|
||||||
sc := res[:MSG_MAX_LENGTH]
|
|
||||||
rep := m.sesh.createReply(sc, m.ID, m.ChannelID, m.ServerID)
|
|
||||||
_, err := m.sesh.ChannelMessageSendComplex(m.ChannelID, rep)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
res = res[MSG_MAX_LENGTH:]
|
|
||||||
|
|
||||||
//if we have left than a full chunk send the rest and break the loop
|
|
||||||
if len(res) < MSG_MAX_LENGTH {
|
|
||||||
final := m.sesh.createReply(res, m.ID, m.ChannelID, m.ServerID)
|
|
||||||
_, err := m.sesh.ChannelMessageSendComplex(m.ChannelID, final)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//short enough message to send in one go
|
|
||||||
rep := m.sesh.createReply(res, m.ID, m.ChannelID, m.ServerID)
|
|
||||||
_, err := m.sesh.ChannelMessageSendComplex(m.ChannelID, rep)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete removes the message from the current channel
|
|
||||||
func (m *Message) Delete() error {
|
|
||||||
return m.sesh.ChannelMessageDelete(m.ChannelID, m.ID, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (m *Message) Timeout(userID string, duration time.Time) error {
|
|
||||||
// return m.sesh.GuildMemberTimeout(m.serverID, userID, &duration)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (m *Message) ClearTimeout(userID string) error {
|
|
||||||
// return m.sesh.GuildMemberTimeout(m.serverID, userID, nil)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (m *Message) Mute(userID string) error {
|
|
||||||
// return m.sesh.GuildMemberMute(m.serverID, userID, true)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (m *Author) Unmute(userID string) error {
|
|
||||||
// return m.sesh.GuildMemberMute(m.serverID, userID, false)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// message attachment details
|
// message attachment details
|
||||||
type MessageAttachment struct {
|
type MessageAttachment struct {
|
||||||
@@ -107,3 +27,87 @@ type MessageAttachment struct {
|
|||||||
Size int
|
Size int
|
||||||
DurationSecs float64
|
DurationSecs float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Author struct {
|
||||||
|
Name string
|
||||||
|
ID string
|
||||||
|
Roles []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Author Author
|
||||||
|
ID string //message ID
|
||||||
|
Words []string //message data split on whitespaces
|
||||||
|
Content string //entire message data string
|
||||||
|
Channel string //name of channel message was sent in
|
||||||
|
ChannelID string //ID of channel message was sent in
|
||||||
|
Server string //name of guild message was sent in
|
||||||
|
ServerID string //ID of guild message was sent in
|
||||||
|
Attachments []MessageAttachment //any attachments bound to the message
|
||||||
|
Mentions []*dg.User
|
||||||
|
}
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
Message *Message
|
||||||
|
bolt *bolt
|
||||||
|
}
|
||||||
|
|
||||||
|
// React applies reaction to the message
|
||||||
|
func (c *Context) React(emoji Reaction) error {
|
||||||
|
return c.bolt.MessageReactionAdd(c.Message.ChannelID, c.Message.ID, fmt.Sprint(emoji))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respond sends a response to the message, handling chunking if the message exceeds max length
|
||||||
|
func (c *Context) Respond(res string) error {
|
||||||
|
if len(res) > MSG_MAX_LENGTH {
|
||||||
|
for len(res) > 0 {
|
||||||
|
//send full chunk size allowed by discord
|
||||||
|
sc := res[:MSG_MAX_LENGTH]
|
||||||
|
rep := c.bolt.createReply(sc, c.Message.ID, c.Message.ChannelID, c.Message.ServerID)
|
||||||
|
_, err := c.bolt.ChannelMessageSendComplex(c.Message.ChannelID, rep)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res = res[MSG_MAX_LENGTH:]
|
||||||
|
|
||||||
|
//if we have left than a full chunk send the rest and break the loop
|
||||||
|
if len(res) < MSG_MAX_LENGTH {
|
||||||
|
final := c.bolt.createReply(res, c.Message.ID, c.Message.ChannelID, c.Message.ServerID)
|
||||||
|
_, err := c.bolt.ChannelMessageSendComplex(c.Message.ChannelID, final)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//short enough message to send in one go
|
||||||
|
rep := c.bolt.createReply(res, c.Message.ID, c.Message.ChannelID, c.Message.ServerID)
|
||||||
|
_, err := c.bolt.ChannelMessageSendComplex(c.Message.ChannelID, rep)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete removes the message from the current channel
|
||||||
|
func (c *Context) Delete() error {
|
||||||
|
return c.bolt.ChannelMessageDelete(c.Message.ChannelID, c.Message.ID, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Timeout(userId string, duration time.Time) error {
|
||||||
|
return c.bolt.GuildMemberTimeout(c.Message.ServerID, userId, &duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) ClearTimeout(userId string) error {
|
||||||
|
return c.bolt.GuildMemberTimeout(c.Message.ServerID, userId, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Mute(userId string) error {
|
||||||
|
return c.bolt.GuildMemberMute(c.Message.ServerID, userId, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Unmute(userId string) error {
|
||||||
|
return c.bolt.GuildMemberMute(c.Message.ServerID, userId, false)
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ func WithPermissions(perms ...Permission) Option {
|
|||||||
return func(b *bolt) {
|
return func(b *bolt) {
|
||||||
var fullPerms dg.Intent
|
var fullPerms dg.Intent
|
||||||
for _, p := range perms {
|
for _, p := range perms {
|
||||||
if p == AdminPermissions {
|
// if p == AdminPermissions {
|
||||||
b.admin = true
|
// b.admin = true
|
||||||
}
|
// }
|
||||||
fullPerms |= dg.Intent(p)
|
fullPerms |= dg.Intent(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user