State: Added Reaction state handlers

This commit is contained in:
diamondburned (Forefront) 2020-04-12 16:14:27 -07:00
parent 9411dcc74f
commit 9873d475aa
3 changed files with 100 additions and 13 deletions

View File

@ -14,10 +14,6 @@ type Message struct {
// message object.
Author User `json:"author"`
// The member object exists in MESSAGE_CREATE and MESSAGE_UPDATE
// events from text-based guild channels.
Member *Member `json:"member,omitempty"`
Content string `json:"content"`
Timestamp Timestamp `json:"timestamp,omitempty"`

View File

@ -173,8 +173,14 @@ func (u GuildMemberUpdateEvent) Update(m *discord.Member) {
// https://discordapp.com/developers/docs/topics/gateway#messages
type (
MessageCreateEvent discord.Message
MessageUpdateEvent discord.Message
MessageCreateEvent struct {
discord.Message
Member *discord.Member `json:"member,omitempty"`
}
MessageUpdateEvent struct {
discord.Message
Member *discord.Member `json:"member,omitempty"`
}
MessageDeleteEvent struct {
ID discord.Snowflake `json:"id"`
ChannelID discord.Snowflake `json:"channel_id"`
@ -200,13 +206,19 @@ type (
UserID discord.Snowflake `json:"user_id"`
ChannelID discord.Snowflake `json:"channel_id"`
MessageID discord.Snowflake `json:"message_id"`
Emoji discord.Emoji `json:"emoji"`
GuildID discord.Snowflake `json:"guild_id,omitempty"`
Emoji discord.Emoji `json:"emoji"`
GuildID discord.Snowflake `json:"guild_id,omitempty"`
}
MessageReactionRemoveAllEvent struct {
ChannelID discord.Snowflake `json:"channel_id"`
MessageID discord.Snowflake `json:"message_id"`
GuildID discord.Snowflake `json:"guild_id,omitempty"`
}
MessageReactionRemoveEmoji struct {
ChannelID discord.Snowflake `json:"channel_id"`
MessageID discord.Snowflake `json:"message_id"`
Emoji discord.Emoji `json:"emoji"`
GuildID discord.Snowflake `json:"guild_id,omitempty"`
}
MessageAckEvent struct {

View File

@ -134,14 +134,15 @@ func (s *State) onEvent(iface interface{}) {
s.stateErr(err, "Failed to remove a channel in state")
}
// *gateway.ChannelPinsUpdateEvent is not tracked.
case *gateway.ChannelPinsUpdateEvent:
// not tracked.
case *gateway.MessageCreateEvent:
if err := s.Store.MessageSet((*discord.Message)(ev)); err != nil {
if err := s.Store.MessageSet(&ev.Message); err != nil {
s.stateErr(err, "Failed to add a message in state")
}
case *gateway.MessageUpdateEvent:
if err := s.Store.MessageSet((*discord.Message)(ev)); err != nil {
if err := s.Store.MessageSet(&ev.Message); err != nil {
s.stateErr(err, "Failed to update a message in state")
}
case *gateway.MessageDeleteEvent:
@ -154,6 +155,62 @@ func (s *State) onEvent(iface interface{}) {
s.stateErr(err, "Failed to delete bulk meessages in state")
}
}
case *gateway.MessageReactionAddEvent:
s.editMessage(ev.ChannelID, ev.MessageID, func(m *discord.Message) bool {
if i := findReaction(m.Reactions, ev.Emoji); i > -1 {
m.Reactions[i].Count++
} else {
u, err := s.Store.Me()
if err != nil {
s.stateErr(err, "Failed to get self for reaction add")
return false
}
m.Reactions = append(m.Reactions, discord.Reaction{
Count: 1,
Me: ev.UserID == u.ID,
Emoji: ev.Emoji,
})
}
return true
})
case *gateway.MessageReactionRemoveEvent:
s.editMessage(ev.ChannelID, ev.MessageID, func(m *discord.Message) bool {
var i = findReaction(m.Reactions, ev.Emoji)
if i < 0 {
return false
}
r := &m.Reactions[i]
r.Count--
switch {
case r.Count < 1: // If the count is 0:
// Remove the reaction.
m.Reactions = append(m.Reactions[:i], m.Reactions[i+1:]...)
case r.Me: // If reaction removal is the user's
u, err := s.Store.Me()
if err == nil && ev.UserID == u.ID {
r.Me = false
}
}
return true
})
case *gateway.MessageReactionRemoveAllEvent:
s.editMessage(ev.ChannelID, ev.MessageID, func(m *discord.Message) bool {
m.Reactions = nil
return true
})
case *gateway.MessageReactionRemoveEmoji:
s.editMessage(ev.ChannelID, ev.MessageID, func(m *discord.Message) bool {
var i = findReaction(m.Reactions, ev.Emoji)
if i < 0 {
return false
}
m.Reactions = append(m.Reactions[:i], m.Reactions[i+1:]...)
return true
})
case *gateway.PresenceUpdateEvent:
presence := (*discord.Presence)(ev)
@ -201,6 +258,28 @@ func (s *State) batchLog(errors ...error) {
// Helper functions
func (s *State) editMessage(ch, msg discord.Snowflake, fn func(m *discord.Message) bool) {
m, err := s.Store.Message(ch, msg)
if err != nil {
return
}
if !fn(m) {
return
}
if err := s.Store.MessageSet(m); err != nil {
s.stateErr(err, "Failed to save message in reaction add")
}
}
func findReaction(rs []discord.Reaction, emoji discord.Emoji) int {
for i := range rs {
if rs[i].Emoji.ID == emoji.ID && rs[i].Emoji.Name == emoji.Name {
return i
}
}
return -1
}
func handleGuildCreate(store Store, guild *gateway.GuildCreateEvent) []error {
// If a guild is unavailable, don't populate it in the state, as the guild
// data is very incomplete.