diff --git a/state.go b/state.go index 88b30f5..6151bbf 100644 --- a/state.go +++ b/state.go @@ -43,6 +43,7 @@ func (s *State) GuildAdd(guild *Guild) error { return nil } } + s.Guilds = append(s.Guilds, *guild) return nil } @@ -59,6 +60,7 @@ func (s *State) GuildRemove(guild *Guild) error { return nil } } + return errors.New("Guild not found.") } @@ -76,6 +78,7 @@ func (s *State) Guild(guildID string) (*Guild, error) { return &g, nil } } + return nil, errors.New("Guild not found.") } @@ -126,7 +129,7 @@ func (s *State) MemberRemove(member *Member) error { } // Member gets a member by ID from a guild. -func (s *State) Member(guildID string, userID string) (*Member, error) { +func (s *State) Member(guildID, userID string) (*Member, error) { if s == nil { return nil, nilError } @@ -178,6 +181,7 @@ func (s *State) ChannelAdd(channel *Channel) error { guild.Channels = append(guild.Channels, *channel) } + return nil } @@ -212,7 +216,7 @@ func (s *State) ChannelRemove(channel *Channel) error { } // GuildChannel gets a channel by ID from a guild. -func (s *State) GuildChannel(guildID string, channelID string) (*Channel, error) { +func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) { if s == nil { return nil, nilError } @@ -266,3 +270,55 @@ func (s *State) Channel(channelID string) (*Channel, error) { return nil, errors.New("Channel not found.") } + +// Emoji returns an emoji for a guild and emoji id. +func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) { + if s == nil { + return nil, nilError + } + + guild, err := s.Guild(guildID) + if err != nil { + return nil, err + } + + for _, e := range guild.Emojis { + if e.ID == emojiID { + return &e, nil + } + } + + return nil, errors.New("Emoji not found.") +} + +// EmojiAdd adds an emoji to the current world state. +func (s *State) EmojiAdd(guildID string, emoji *Emoji) error { + if s == nil { + return nilError + } + + guild, err := s.Guild(guildID) + if err != nil { + return err + } + + for i, e := range guild.Emojis { + if e.ID == emoji.ID { + guild.Emojis[i] = *emoji + return nil + } + } + + guild.Emojis = append(guild.Emojis, *emoji) + return nil +} + +// EmojisAdd adds multiple emojis to the world state. +func (s *State) EmojisAdd(guildID string, emojis []Emoji) error { + for _, e := range emojis { + if err := s.EmojiAdd(guildID, &e); err != nil { + return err + } + } + return nil +} diff --git a/structs.go b/structs.go index bc7df1d..dee340d 100644 --- a/structs.go +++ b/structs.go @@ -58,6 +58,7 @@ type Session struct { OnGuildIntegrationsUpdate func(*Session, GuildIntegrationsUpdate) OnGuildBanAdd func(*Session, GuildBan) OnGuildBanRemove func(*Session, GuildBan) + OnGuildEmojisUpdate func(*Session, GuildEmojisUpdate) OnUserSettingsUpdate func(*Session, map[string]interface{}) // TODO: Find better way? // Exposed but should not be modified by User. @@ -187,6 +188,14 @@ type PermissionOverwrite struct { Allow int `json:"allow"` } +type Emoji struct { + Roles []string `json:"roles"` + RequireColons bool `json:"require_colons"` + Name string `json:"name"` + Managed bool `json:"managed"` + ID string `json:"id"` +} + // A Guild holds all data related to a specific Discord Guild. Guilds are also // sometimes referred to as Servers in the Discord client. type Guild struct { @@ -202,6 +211,7 @@ type Guild struct { Large bool `json:"large"` // ?? JoinedAt string `json:"joined_at"` // make this a timestamp Roles []Role `json:"roles"` + Emojis []Emoji `json:"emojis"` Members []Member `json:"members"` Presences []Presence `json:"presences"` Channels []Channel `json:"channels"` @@ -363,6 +373,12 @@ type GuildBan struct { GuildID string `json:"guild_id"` } +// A GuildEmojisUpdate stores data for a guild emoji update event. +type GuildEmojisUpdate struct { + GuildID string `json:"guild_id"` + Emojis []Emoji `json:"emojis"` +} + // A State contains the current known state. // As discord sends this in a READY blob, it seems reasonable to simply // use that struct as the data store. diff --git a/wsapi.go b/wsapi.go index 1b7a734..953057d 100644 --- a/wsapi.go +++ b/wsapi.go @@ -384,6 +384,17 @@ func (s *Session) event(messageType int, message []byte) (err error) { } return } + case "GUILD_EMOJIS_UPDATE": + var st GuildEmojisUpdate + if err = unmarshalEvent(e, &st); err == nil { + if s.StateEnabled { + s.State.EmojisAdd(st.GuildID, st.Emojis) + } + if s.OnGuildEmojisUpdate != nil { + s.OnGuildEmojisUpdate(s, st) + } + } + return case "USER_SETTINGS_UPDATE": if s.OnUserSettingsUpdate != nil { var st map[string]interface{} @@ -394,8 +405,7 @@ func (s *Session) event(messageType int, message []byte) (err error) { } default: fmt.Println("UNKNOWN EVENT: ", e.Type) - // TODO learn the log package - // log.print type and JSON data + printJSON(message) } // if still here, send to generic OnEvent