Several updates to make library more idiomatic Go

This commit is contained in:
Bruce Marriner 2015-11-16 21:39:39 -06:00
parent 1ae6895552
commit f655167761
8 changed files with 94 additions and 78 deletions

View file

@ -1,21 +1,23 @@
package discordgo package discordgo
// A Channel holds all data related to an individual Discord channel.
type Channel struct { type Channel struct {
Id string `json:"id"` ID string `json:"id"`
GuildId string `json:"guild_idomitempty"` GuildID string `json:"guild_idomitempty"`
Name string `json:"name"` Name string `json:"name"`
Topic string `json:"topic"` Topic string `json:"topic"`
Position int `json:"position"` Position int `json:"position"`
Type string `json:"type"` Type string `json:"type"`
PermissionOverwrites []PermissionOverwrite `json:"permission_overwrites"` PermissionOverwrites []PermissionOverwrite `json:"permission_overwrites"`
IsPrivate bool `json:"is_private"` IsPrivate bool `json:"is_private"`
LastMessageId string `json:"last_message_id"` LastMessageID string `json:"last_message_id"`
Recipient User `json:"recipient"` Recipient User `json:"recipient"`
Session *Session Session *Session
} }
// A PermissionOverwrite holds permission overwrite data for a Channel
type PermissionOverwrite struct { type PermissionOverwrite struct {
Id string `json:"id"` ID string `json:"id"`
Type string `json:"type"` Type string `json:"type"`
Deny int `json:"deny"` Deny int `json:"deny"`
Allow int `json:"allow"` Allow int `json:"allow"`

View file

@ -1,15 +1,17 @@
package discordgo package discordgo
// 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 { type Guild struct {
Id string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Icon string `json:"icon"` Icon string `json:"icon"`
Region string `json:"region"` Region string `json:"region"`
AfkTimeout int `json:"afk_timeout"` AfkTimeout int `json:"afk_timeout"`
AfkChannelId string `json:"afk_channel_id"` AfkChannelID string `json:"afk_channel_id"`
EmbedChannelId string `json:"embed_channel_id"` EmbedChannelID string `json:"embed_channel_id"`
EmbedEnabled bool `json:"embed_enabled"` EmbedEnabled bool `json:"embed_enabled"`
OwnerId string `json:"owner_id"` OwnerID string `json:"owner_id"`
Large bool `json:"large"` // ?? Large bool `json:"large"` // ??
JoinedAt string `json:"joined_at"` // make this a timestamp JoinedAt string `json:"joined_at"` // make this a timestamp
Roles []Role `json:"roles"` Roles []Role `json:"roles"`
@ -19,8 +21,9 @@ type Guild struct {
VoiceStates []VoiceState `json:"voice_states"` VoiceStates []VoiceState `json:"voice_states"`
} }
// A Role stores information about Discord guild member roles.
type Role struct { type Role struct {
Id string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Managed bool `json:"managed"` Managed bool `json:"managed"`
Color int `json:"color"` Color int `json:"color"`
@ -29,26 +32,28 @@ type Role struct {
Permissions int `json:"permissions"` Permissions int `json:"permissions"`
} }
// A VoiceState stores the voice states of Guilds
type VoiceState struct { type VoiceState struct {
UserId string `json:"user_id"` UserID string `json:"user_id"`
Suppress bool `json:"suppress"` Suppress bool `json:"suppress"`
SessionId string `json:"session_id"` SessionID string `json:"session_id"`
SelfMute bool `json:"self_mute"` SelfMute bool `json:"self_mute"`
SelfDeaf bool `json:"self_deaf"` SelfDeaf bool `json:"self_deaf"`
Mute bool `json:"mute"` Mute bool `json:"mute"`
Deaf bool `json:"deaf"` Deaf bool `json:"deaf"`
ChannelId string `json:"channel_id"` ChannelID string `json:"channel_id"`
} }
// A Presence stores the online, offline, or idle and game status of Guild members.
type Presence struct { type Presence struct {
User User `json:"user"` User User `json:"user"`
Status string `json:"status"` Status string `json:"status"`
GameId int `json:"game_id"` GameID int `json:"game_id"`
} }
// TODO: Member vs User? // A Member stores user information for Guild members.
type Member struct { type Member struct {
GuildId string `json:"guild_id"` GuildID string `json:"guild_id"`
JoinedAt string `json:"joined_at"` JoinedAt string `json:"joined_at"`
Deaf bool `json:"deaf"` Deaf bool `json:"deaf"`
Mute bool `json:"mute"` Mute bool `json:"mute"`

View file

@ -541,8 +541,8 @@ func (s *Session) VoiceRegions() (st []VoiceRegion, err error) {
return return
} }
// VoiceIce returns the voice server ICE information // VoiceICE returns the voice server ICE information
func (s *Session) VoiceIce() (st VoiceIce, err error) { func (s *Session) VoiceICE() (st VoiceICE, err error) {
body, err := s.Request("GET", VOICE_ICE, ``) body, err := s.Request("GET", VOICE_ICE, ``)
err = json.Unmarshal(body, &st) err = json.Unmarshal(body, &st)

View file

@ -59,22 +59,3 @@ type Session struct {
// lets put all the general session // lets put all the general session
// tracking and infos here.. clearly // tracking and infos here.. clearly
} }
/******************************************************************************
* The below functions are "shortcut" methods for functions in restapi.go
* Reference the client.go file for more documentation.
*/
func (s *Session) Self() (user User, err error) {
user, err = s.User("@me")
return
}
func (s *Session) MyPrivateChannels() (channels []Channel, err error) {
channels, err = s.UserChannels("@me")
return
}
func (s *Session) MyGuilds() (servers []Guild, err error) {
servers, err = s.UserGuilds("@me")
return
}

View file

@ -2,8 +2,9 @@ package discordgo
// TODO: Eventually everything here gets moved to a better place. // TODO: Eventually everything here gets moved to a better place.
// A Message stores all data related to a specific Discord message.
type Message struct { type Message struct {
Id int `json:"id,string"` ID int `json:"id,string"`
Author User `json:"author"` Author User `json:"author"`
Content string `json:"content"` Content string `json:"content"`
Attachments []Attachment `json:"attachments"` Attachments []Attachment `json:"attachments"`
@ -13,33 +14,39 @@ type Message struct {
MentionEveryone bool `json:"mention_everyone"` MentionEveryone bool `json:"mention_everyone"`
EditedTimestamp string `json:"edited_timestamp"` EditedTimestamp string `json:"edited_timestamp"`
Mentions []User `json:"mentions"` Mentions []User `json:"mentions"`
ChannelId int `json:"channel_id,string"` ChannelID int `json:"channel_id,string"`
} }
// An Attachment stores data for message attachments.
type Attachment struct { //TODO figure this out type Attachment struct { //TODO figure this out
} }
// An Embed stores data for message embeds.
type Embed struct { // TODO figure this out type Embed struct { // TODO figure this out
} }
// A VoiceRegion stores data for a specific voice region server.
type VoiceRegion struct { type VoiceRegion struct {
Id string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
SampleHostname string `json:"sample_hostname"` SampleHostname string `json:"sample_hostname"`
SamplePort int `json:"sample_port"` SamplePort int `json:"sample_port"`
} }
type VoiceIce struct { // A VoiceICE stores data for voice ICE servers.
Ttl int `json:"ttl,string"` type VoiceICE struct {
Servers []IceServer `json:"servers"` TTL int `json:"ttl,string"`
Servers []ICEServer `json:"servers"`
} }
type IceServer struct { // A ICEServer stores data for a specific voice ICE server.
Url string `json:"url"` type ICEServer struct {
URL string `json:"url"`
Username string `json:"username"` Username string `json:"username"`
Credential string `json:"credential"` Credential string `json:"credential"`
} }
// A Invite stores all data related to a specific Discord Guild or Channel invite.
type Invite struct { type Invite struct {
MaxAge int `json:"max_age"` MaxAge int `json:"max_age"`
Code string `json:"code"` Code string `json:"code"`

View file

@ -1,7 +1,8 @@
package discordgo package discordgo
// A User stores all data for an individual Discord user.
type User struct { type User struct {
Id string `json:"id"` ID string `json:"id"`
Email string `json:"email"` Email string `json:"email"`
Username string `json:"username"` Username string `json:"username"`
Avatar string `json:"Avatar"` Avatar string `json:"Avatar"`
@ -18,13 +19,15 @@ type User struct {
// it just doesn't seem able to handle this one // it just doesn't seem able to handle this one
// field correctly. Need to research this more. // field correctly. Need to research this more.
// A PrivateChannel stores all data for a specific user private channel.
type PrivateChannel struct { type PrivateChannel struct {
Id string `json:"id"` ID string `json:"id"`
IsPrivate bool `json:"is_private"` IsPrivate bool `json:"is_private"`
LastMessageId string `json:"last_message_id"` LastMessageID string `json:"last_message_id"`
Recipient User `json:"recipient"` Recipient User `json:"recipient"`
} // merge with channel? } // merge with channel?
// A Settings stores data for a specific users Discord client settings.
type Settings struct { type Settings struct {
RenderEmbeds bool `json:"render_embeds"` RenderEmbeds bool `json:"render_embeds"`
InlineEmbedMedia bool `json:"inline_embed_media"` InlineEmbedMedia bool `json:"inline_embed_media"`
@ -35,5 +38,3 @@ type Settings struct {
Theme string `json:"theme"` Theme string `json:"theme"`
MutedChannels []string `json:"muted_channels"` MutedChannels []string `json:"muted_channels"`
} }
// PM function to PM a user.

View file

@ -9,7 +9,7 @@ import (
"fmt" "fmt"
) )
// convert to return as string // printJSON is a helper function to display JSON data in a easy to read format.
func printJSON(body []byte) { func printJSON(body []byte) {
var prettyJSON bytes.Buffer var prettyJSON bytes.Buffer
error := json.Indent(&prettyJSON, body, "", "\t") error := json.Indent(&prettyJSON, body, "", "\t")

View file

@ -17,19 +17,16 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
// Basic struct for all Websocket Event messages // An Event provides a basic initial struct for all websocket event.
type Event struct { type Event struct {
Type string `json:"t"` Type string `json:"t"`
State int `json:"s"` State int `json:"s"`
Operation int `json:"o"` Operation int `json:"o"`
Direction int `json:"dir"` Direction int `json:"dir"`
//Direction of command, 0-received, 1-sent -- thanks Xackery/discord
RawData json.RawMessage `json:"d"` RawData json.RawMessage `json:"d"`
Session *Session
} }
// The Ready Event given after initial connection // A Ready stores all data for the websocket READY event.
type Ready struct { type Ready struct {
Version int `json:"v"` Version int `json:"v"`
SessionID string `json:"session_id"` SessionID string `json:"session_id"`
@ -42,51 +39,61 @@ type Ready struct {
// ReadState might need to move? Gives me the read status // ReadState might need to move? Gives me the read status
// of all my channels when first connecting. I think :) // of all my channels when first connecting. I think :)
// A ReadState stores data on the read state of channels.
type ReadState struct { type ReadState struct {
MentionCount int MentionCount int
LastMessageId string `json:"last_message_id"` LastMessageID string `json:"last_message_id"`
Id string `json:"id"` ID string `json:"id"`
} }
// A TypingStart stores data for the typing start websocket event.
type TypingStart struct { type TypingStart struct {
UserId string `json:"user_id"` UserID string `json:"user_id"`
ChannelId string `json:"channel_id"` ChannelID string `json:"channel_id"`
Timestamp int `json:"timestamp"` Timestamp int `json:"timestamp"`
} }
// A PresenceUpdate stores data for the pressence update websocket event.
type PresenceUpdate struct { type PresenceUpdate struct {
User User `json:"user"` User User `json:"user"`
Status string `json:"status"` Status string `json:"status"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
GuildId string `json:"guild_id"` GuildID string `json:"guild_id"`
GameId int `json:"game_id"` GameID int `json:"game_id"`
} }
// A MessageAck stores data for the message ack websocket event.
type MessageAck struct { type MessageAck struct {
MessageId string `json:"message_id"` MessageID string `json:"message_id"`
ChannelId string `json:"channel_id"` ChannelID string `json:"channel_id"`
} }
// A MessageDelete stores data for the message delete websocket event.
type MessageDelete struct { type MessageDelete struct {
Id string `json:"id"` ID string `json:"id"`
ChannelId string `json:"channel_id"` ChannelID string `json:"channel_id"`
} // so much like MessageAck.. } // so much like MessageAck..
// A GuildIntegrationsUpdate stores data for the guild integrations update
// websocket event.
type GuildIntegrationsUpdate struct { type GuildIntegrationsUpdate struct {
GuildId string `json:"guild_id"` GuildID string `json:"guild_id"`
} }
// A GuildRole stores data for guild role websocket events.
type GuildRole struct { type GuildRole struct {
Role Role `json:"role"` Role Role `json:"role"`
GuildId string `json:"guild_id"` GuildID string `json:"guild_id"`
} }
// A GuildRoleDelete stores data for the guild role delete websocket event.
type GuildRoleDelete struct { type GuildRoleDelete struct {
RoleId string `json:"role_id"` RoleID string `json:"role_id"`
GuildId string `json:"guild_id"` GuildID string `json:"guild_id"`
} }
// Open a websocket connection to Discord // Open opens a websocket connection to Discord.
func (s *Session) Open() (err error) { func (s *Session) Open() (err error) {
// Get the gateway to use for the Websocket connection // Get the gateway to use for the Websocket connection
@ -101,6 +108,8 @@ func (s *Session) Open() (err error) {
// maybe this is SendOrigin? not sure the right name here // maybe this is SendOrigin? not sure the right name here
// also bson.M vs string interface map? Read about // also bson.M vs string interface map? Read about
// how to send JSON the right way. // how to send JSON the right way.
// Handshake sends the client data to Discord during websocket initial connection.
func (s *Session) Handshake() (err error) { func (s *Session) Handshake() (err error) {
err = s.wsConn.WriteJSON(map[string]interface{}{ err = s.wsConn.WriteJSON(map[string]interface{}{
@ -121,21 +130,23 @@ func (s *Session) Handshake() (err error) {
return return
} }
func (s *Session) UpdateStatus(idleSince, gameId string) (err error) { // UpdateStatus is used to update the authenticated user's status.
func (s *Session) UpdateStatus(idleSince, gameID string) (err error) {
err = s.wsConn.WriteJSON(map[string]interface{}{ err = s.wsConn.WriteJSON(map[string]interface{}{
"op": 2, "op": 2,
"d": map[string]interface{}{ "d": map[string]interface{}{
"idle_since": idleSince, "idle_since": idleSince,
"game_id": gameId, "game_id": gameID,
}, },
}) })
return return
} }
// TODO: need a channel or something to communicate // TODO: need a channel or something to communicate
// to this so I can tell it to stop listening // to this so I can tell it to stop listening
// Listen starts listening to the websocket connection for events.
func (s *Session) Listen() (err error) { func (s *Session) Listen() (err error) {
if s.wsConn == nil { if s.wsConn == nil {
@ -157,12 +168,17 @@ func (s *Session) Listen() (err error) {
// Not sure how needed this is and where it would be best to call it. // Not sure how needed this is and where it would be best to call it.
// somewhere. // somewhere.
// Close closes the connection to the websocket.
func (s *Session) Close() { func (s *Session) Close() {
s.wsConn.Close() s.wsConn.Close()
} }
// Front line handler for all Websocket Events. Determines the // Front line handler for all Websocket Events. Determines the
// event type and passes the message along to the next handler. // event type and passes the message along to the next handler.
// event is the front line handler for all events. This needs to be
// broken up into smaller functions to be more idiomatic Go.
func (s *Session) event(messageType int, message []byte) (err error) { func (s *Session) event(messageType int, message []byte) (err error) {
if s.Debug { if s.Debug {
@ -429,6 +445,10 @@ func (s *Session) event(messageType int, message []byte) (err error) {
// This heartbeat is sent to keep the Websocket conenction // This heartbeat is sent to keep the Websocket conenction
// to Discord alive. If not sent, Discord will close the // to Discord alive. If not sent, Discord will close the
// connection. // connection.
// Heartbeat sends regular heartbeats to Discord so it knows the client
// is still connected. If you do not send these heartbeats Discord will
// disconnect the websocket connection after a few seconds.
func (s *Session) Heartbeat(i time.Duration) { func (s *Session) Heartbeat(i time.Duration) {
if s.wsConn == nil { if s.wsConn == nil {