package bolt import ( "fmt" "time" dg "github.com/bwmarrin/discordgo" ) const ( // the max length allowed for basic messages, if the message content exceeds this amount // then messages are split unto chunks of max size MSG_MAX_LENGTH = 2000 ) // command and message payload function type type Payload func(c *Context) error type MessageAttachment struct { ID string URL string ProxyURL string Filename string ContentType string Width int Height int Size int DurationSecs float64 } // Author contains basic information about message authors type Author struct { Name string ID string Roles []string } // Message contains all needed data to handle message events type Message struct { Author Author //current message ID ID string //message content split on whitespace to allow for easy argument parsing with commands Words []string //entire message content unchanged Content string //channel message was sent in, name and ID Channel string ChannelID string //guild message was sent in, name and ID Server string ServerID string //message extras Attachments []MessageAttachment //any attachments bound to the message Mentions []*dg.User //users mention in the message with @ } // Context is the struct passed to message and command handlers, it contains all needed message data as well as // some methods to make interaction with the message as easy as possible type Context struct { Message *Message bolt *bolt } // React applies the 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, so ship it 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) } // Timeout creates a user timeout for the supplied userID that lasts until duration is exceeded or the // timeout is cleared func (c *Context) Timeout(userId string, duration time.Time) error { return c.bolt.GuildMemberTimeout(c.Message.ServerID, userId, &duration) } // ClearTimeout clears existing user timeouts, allowing them access again func (c *Context) ClearTimeout(userId string) error { return c.bolt.GuildMemberTimeout(c.Message.ServerID, userId, nil) } // Mute handles muting a user from Voice Chat, this mute stays until it is Unmute()'d func (c *Context) Mute(userId string) error { return c.bolt.GuildMemberMute(c.Message.ServerID, userId, true) } // Unmute removes a mute on the user, allowing them vc access again func (c *Context) Unmute(userId string) error { return c.bolt.GuildMemberMute(c.Message.ServerID, userId, false) }