Huge update to Websocket support.

Changed "Server" to "Guild" to remain consistant with Discords
API naming.
This commit is contained in:
Bruce Marriner 2015-11-12 23:25:48 -06:00
parent 666adbe0b4
commit 074d1bcdae
6 changed files with 274 additions and 48 deletions

View file

@ -1,18 +1,26 @@
package discordgo package discordgo
type Channel struct { type Channel struct {
Server_id int `json:"guild_id,string,omitempty"` GuildId int `json:"guild_id,string,omitempty"`
Id int `json:"id,string"` Id int `json:"id,string"`
Name string `json:"name"` Name string `json:"name"`
Topic string `json:"topic"` Topic string `json:"topic"`
Position int `json:"position"` Position int `json:"position"`
Last_message_id int `json:"last_message_id,string"`
Type string `json:"type"` Type string `json:"type"`
Is_private bool `json:"is_private"` PermissionOverwrites []PermissionOverwrite `json:"permission_overwrites"`
Permission_overwrites string `json:"-"` // ignored for now IsPrivate bool `json:"is_private"`
LastMessageId int `json:"last_message_id,string"`
Recipient User `json:"recipient"`
Session *Session Session *Session
} }
type PermissionOverwrite struct {
Type string `json:"type"`
Id int `json:"id,string"`
Deny int `json:"deny"`
Allow int `json:"allow"`
}
/* /*
func (c *Channel) Messages() (messages []Message) { func (c *Channel) Messages() (messages []Message) {
} }

81
guild.go Normal file
View file

@ -0,0 +1,81 @@
package discordgo
type Guild struct {
Id int `json:"id,string"`
Name string `json:"name"`
Icon string `json:"icon"`
Region string `json:"region"`
Joined_at string `json:"joined_at"` // make time stamp
Afk_timeout int `json:"afk_timeout"`
Afk_channel_id int `json:"afk_channel_id"`
Embed_channel_id int `json:"embed_channel_id"`
Embed_enabled bool `json:"embed_enabled"`
Owner_id int `json:"owner_id,string"`
Large bool `json:"large"` // ??
JoinedAt string `json:"joined_at"` // make this a timestamp
Roles []Role `json:"roles"`
Members []Member `json:"members"`
Presences []Presence `json:"presences"`
Channels []Channel `json:"channels"`
VoiceStates []VoiceState `json:"voice_states"`
Session *Session // I got to be doing it wrong here.
}
type VoiceState struct {
UserId int `json:"user_id,string"`
Suppress bool `json:"suppress"`
SessionId string `json:"session_id"`
SelfMute bool `json:"self_mute"`
SelfDeaf bool `json:"self_deaf"`
Mute bool `json:"mute"`
Deaf bool `json:"deaf"`
ChannelId int `json:"channel_id,string"`
}
type Presence struct {
User User `json:"user"`
Status string `json:"status"`
GameId int `json:"game_id"`
}
// TODO: Member vs User?
type Member struct {
GuildId int `json:"guild_id"`
JoinedAt string `json:"joined_at"`
Deaf bool `json:"deaf"`
mute bool `json:"mute"`
User User `json:"user"`
Roles []Role `json:"roles"`
}
type Role struct {
Id int `json:"id,string"`
Name string `json:"name"`
Managed bool `json:"managed"`
Color int `json:"color"`
Hoist bool `json:"hoist"`
Position int `json:"position"`
Permissions int `json:"permissions"`
}
// Channels returns an array of Channel structures for channels within
// this Server
/*
TODO: How to name these? If we make a variable to store
channels from READY packet, etc. We can't have a Channel
func? And which is better. Channels func gets live up
to date data on each call.. so, there is some benefit there.
Maybe it should have both, but make the Channels check and
pull new data based on a cache time?
func (s *Server) Channels() (c []Channel, err error) {
c, err = Channels(s.Session, s.Id)
return
}
*/
/*
func (s *Server) Members() (m []Users, err error) {
}
*/

View file

@ -162,8 +162,8 @@ func PrivateChannels(session *Session, userId string) (channels []Channel, err e
return return
} }
// Servers returns an array of Server structures for all servers for a user // Guilds returns an array of Guild structures for all servers for a user
func Servers(session *Session, userId string) (servers []Server, err error) { func Guilds(session *Session, userId string) (servers []Guild, err error) {
body, err := Request(session, "GET", fmt.Sprintf("%s/%s/guilds", USERS, userId), ``) body, err := Request(session, "GET", fmt.Sprintf("%s/%s/guilds", USERS, userId), ``)
err = json.Unmarshal(body, &servers) err = json.Unmarshal(body, &servers)

View file

@ -18,24 +18,25 @@ type Session struct {
// Settable Callback functions for Websocket Events // Settable Callback functions for Websocket Events
OnEvent func(*Session, Event) // should Event be *Event? OnEvent func(*Session, Event) // should Event be *Event?
OnReady func(*Session, Ready) OnReady func(*Session, Ready)
OnTypingStart func(*Session, TypingStart)
OnMessageCreate func(*Session, Message) OnMessageCreate func(*Session, Message)
OnTypingStart func(*Session, Event) OnMessageUpdate func(*Session, Message)
OnMessageAck func(*Session, Event) OnMessageDelete func(*Session, MessageDelete)
OnMessageUpdate func(*Session, Event) OnMessageAck func(*Session, MessageAck)
OnMessageDelete func(*Session, Event) OnPresenceUpdate func(*Session, PresenceUpdate)
OnPresenceUpdate func(*Session, Event) OnVoiceStateUpdate func(*Session, VoiceState)
OnChannelCreate func(*Session, Event) OnChannelCreate func(*Session, Channel)
OnChannelUpdate func(*Session, Event) OnChannelUpdate func(*Session, Channel)
OnChannelDelete func(*Session, Event) OnChannelDelete func(*Session, Channel)
OnGuildCreate func(*Session, Event) OnGuildCreate func(*Session, Guild)
OnGuildDelete func(*Session, Event) OnGuildDelete func(*Session, Guild)
OnGuildMemberAdd func(*Session, Event) OnGuildMemberAdd func(*Session, Member)
OnGuildMemberRemove func(*Session, Event) OnGuildMemberRemove func(*Session, Member)
OnGuildMemberDelete func(*Session, Event) // which is it? OnGuildMemberDelete func(*Session, Member) // which is it?
OnGuildMemberUpdate func(*Session, Event) OnGuildMemberUpdate func(*Session, Member)
OnGuildRoleCreate func(*Session, Event) OnGuildRoleCreate func(*Session, Role)
OnGuildRoleDelete func(*Session, Event) OnGuildRoleDelete func(*Session, Role)
OnGuildIntegrationsUpdate func(*Session, Event) OnGuildIntegrationsUpdate func(*Session, GuildIntegrationsUpdate)
// OnMessageCreate func(Session, Event, Message) // OnMessageCreate func(Session, Event, Message)
// ^^ Any value to passing session, event, message? // ^^ Any value to passing session, event, message?
@ -69,8 +70,8 @@ func (session *Session) PrivateChannels() (channels []Channel, err error) {
return return
} }
func (session *Session) Servers() (servers []Server, err error) { func (session *Session) Guilds() (servers []Guild, err error) {
servers, err = Servers(session, "@me") servers, err = Guilds(session, "@me")
return return
} }

View file

@ -14,6 +14,6 @@ type PrivateChannel struct {
IsPrivate bool `json:"is_private"` IsPrivate bool `json:"is_private"`
LastMessageId int `json:"last_message_id,string"` LastMessageId int `json:"last_message_id,string"`
Recipient User `json:"recipient"` Recipient User `json:"recipient"`
} } // merge with channel?
// PM function to PM a user. // PM function to PM a user.

154
wsapi.go
View file

@ -37,7 +37,7 @@ type Ready struct {
User User `json:"user"` User User `json:"user"`
ReadState []ReadState ReadState []ReadState
PrivateChannels []PrivateChannel PrivateChannels []PrivateChannel
Servers []Server Guilds []Guild
} }
// ReadState might need to move? Gives me the read status // ReadState might need to move? Gives me the read status
@ -48,6 +48,34 @@ type ReadState struct {
ID int `json:"id,string"` ID int `json:"id,string"`
} }
type TypingStart struct {
UserId int `json:"user_id,string"`
ChannelId int `json:"channel_id,string"`
Timestamp int `json:"timestamp"`
}
type PresenceUpdate struct {
User User `json:"user"`
Status string `json:"status"`
Roles []Role `json:"roles"`
GuildId int `json:"guild_id,string"`
GameId int `json:"game_id"`
}
type MessageAck struct {
MessageId int `json:"message_id,string"`
ChannelId int `json:"channel_id,string"`
}
type MessageDelete struct {
Id int `json:"id,string"`
ChannelId int `json:"channel_id,string"`
} // so much like MessageAck..
type GuildIntegrationsUpdate struct {
GuildId int `json:"guild_id,string"`
}
// Open a websocket connection to Discord // Open a websocket connection to Discord
func Open(s *Session) (err error) { func Open(s *Session) (err error) {
@ -139,70 +167,178 @@ func event(s *Session, messageType int, message []byte) (err error) {
if s.OnReady != nil { if s.OnReady != nil {
var st Ready var st Ready
if err := json.Unmarshal(e.RawData, &st); err != nil { if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err return err
} }
s.OnReady(s, st) s.OnReady(s, st)
return return
} }
case "VOICE_STATE_UPDATE":
if s.OnVoiceStateUpdate != nil {
var st VoiceState
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
}
s.OnVoiceStateUpdate(s, st)
return
}
case "PRESENCE_UPDATE":
if s.OnPresenceUpdate != nil {
var st PresenceUpdate
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
}
s.OnPresenceUpdate(s, st)
return
}
case "TYPING_START": case "TYPING_START":
if s.OnTypingStart != nil { if s.OnTypingStart != nil {
var st TypingStart
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
}
s.OnTypingStart(s, st)
return
} }
case "MESSAGE_CREATE": case "MESSAGE_CREATE":
if s.OnMessageCreate != nil { if s.OnMessageCreate != nil {
var st Message var st Message
if err := json.Unmarshal(e.RawData, &st); err != nil { if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err return err
} }
s.OnMessageCreate(s, st) s.OnMessageCreate(s, st)
return return
} }
case "MESSAGE_ACK":
if s.OnMessageAck != nil {
}
case "MESSAGE_UPDATE": case "MESSAGE_UPDATE":
if s.OnMessageUpdate != nil { if s.OnMessageUpdate != nil {
var st Message
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
}
s.OnMessageUpdate(s, st)
return
} }
case "MESSAGE_DELETE": case "MESSAGE_DELETE":
if s.OnMessageDelete != nil { if s.OnMessageDelete != nil {
var st MessageDelete
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
} }
case "PRESENCE_UPDATE": s.OnMessageDelete(s, st)
if s.OnPresenceUpdate != nil { }
case "MESSAGE_ACK":
if s.OnMessageAck != nil {
var st MessageAck
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logging
return err
}
s.OnMessageAck(s, st)
return
} }
case "CHANNEL_CREATE": case "CHANNEL_CREATE":
if s.OnChannelCreate != nil { if s.OnChannelCreate != nil {
var st Channel
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnChannelCreate(s, st)
return
} }
case "CHANNEL_UPDATE": case "CHANNEL_UPDATE":
if s.OnChannelUpdate != nil { if s.OnChannelUpdate != nil {
var st Channel
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnChannelUpdate(s, st)
return
} }
case "CHANNEL_DELETE": case "CHANNEL_DELETE":
if s.OnChannelDelete != nil { if s.OnChannelDelete != nil {
var st Channel
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnChannelDelete(s, st)
return
} }
case "GUILD_CREATE": case "GUILD_CREATE":
if s.OnGuildCreate != nil { if s.OnGuildCreate != nil {
var st Guild
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnGuildCreate(s, st)
return
} }
case "GUILD_DELETE": case "GUILD_DELETE":
if s.OnGuildDelete != nil { if s.OnGuildDelete != nil {
var st Guild
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnGuildDelete(s, st)
return
} }
case "GUILD_MEMBER_ADD": case "GUILD_MEMBER_ADD":
if s.OnGuildMemberAdd != nil { if s.OnGuildMemberAdd != nil {
var st Member
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
} }
case "GUILD_MEMBER_REMOVE": // which is it. s.OnGuildMemberAdd(s, st)
return
}
case "GUILD_MEMBER_REMOVE":
if s.OnGuildMemberRemove != nil { if s.OnGuildMemberRemove != nil {
var st Member
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
} }
case "GUILD_MEMBER_DELETE": s.OnGuildMemberRemove(s, st)
if s.OnGuildMemberDelete != nil { return
} }
case "GUILD_MEMBER_UPDATE": case "GUILD_MEMBER_UPDATE":
if s.OnGuildMemberUpdate != nil { if s.OnGuildMemberUpdate != nil {
var st Member
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
} }
s.OnGuildMemberUpdate(s, st)
return
}
/*
case "GUILD_ROLE_CREATE": case "GUILD_ROLE_CREATE":
if s.OnGuildRoleCreate != nil { if s.OnGuildRoleCreate != nil {
} }
case "GUILD_ROLE_DELETE": case "GUILD_ROLE_DELETE":
if s.OnGuildRoleDelete != nil { if s.OnGuildRoleDelete != nil {
} }
*/
case "GUILD_INTEGRATIONS_UPDATE": case "GUILD_INTEGRATIONS_UPDATE":
if s.OnGuildIntegrationsUpdate != nil { if s.OnGuildIntegrationsUpdate != nil {
var st GuildIntegrationsUpdate
if err := json.Unmarshal(e.RawData, &st); err != nil {
printJSON(e.RawData) // TODO: Better error logginEventg
return err
}
s.OnGuildIntegrationsUpdate(s, st)
return
} }
default: default:
fmt.Println("UNKNOWN EVENT: ", e.Type) fmt.Println("UNKNOWN EVENT: ", e.Type)