From 782fbe2bc989e77b9ba86b7cb3175c612c830e23 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Tue, 3 Nov 2015 10:56:09 -0600 Subject: [PATCH] Added Message func to client.go to pull channel messages --- _examples/demo.go | 9 ++++ client.go | 127 ++++++++++++++++++++++++++++++++-------------- notes.md | 15 +++--- structs.go | 37 +++++++------- 4 files changed, 123 insertions(+), 65 deletions(-) diff --git a/_examples/demo.go b/_examples/demo.go index 5e29d52..79420eb 100644 --- a/_examples/demo.go +++ b/_examples/demo.go @@ -46,11 +46,20 @@ func main() { servers, err := discord.Servers(&session, "@me") fmt.Println(servers) + // Use the Members function to pull all members of a given server. + members, err := discord.Members(&session, servers[0].Id) + fmt.Println(members) + // Use the Channels function to pull all available channels for a given // server. This returns a Channel structure. channels, err := discord.Channels(&session, servers[0].Id) fmt.Println(channels) + // Use the Messages function to pull messages from the given channel + // limit the result to 2 messages and don't provide beforeId or afterId + messages, err := discord.Messages(&session, channels[0].Id, 2, 0, 0) + fmt.Println(messages) + // Use the Logout function to Logout from the Discord server. discord.Logout(&session) return diff --git a/client.go b/client.go index 235177a..d2637fc 100644 --- a/client.go +++ b/client.go @@ -19,46 +19,8 @@ import ( "time" ) -// RequestToken asks the Discord server for an authentication token -func Login(session *Session, email string, password string) (token string, err error) { - - var urlStr string = fmt.Sprintf("%s/%s", discordApi, "auth/login") - req, err := http.NewRequest("POST", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(`{"email":"%s", "password":"%s"}`, email, password)))) - if err != nil { - return - } - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{Timeout: (20 * time.Second)} - resp, err := client.Do(req) - if err != nil { - return - } - defer resp.Body.Close() - - body, _ := ioutil.ReadAll(resp.Body) - if resp.StatusCode != 200 { - err = errors.New(fmt.Sprintf("StatusCode: %d, %s", resp.StatusCode, string(body))) - return - } - - if session.Debug { - var prettyJSON bytes.Buffer - error := json.Indent(&prettyJSON, body, "", "\t") - if error != nil { - fmt.Print("JSON parse error: ", error) - return - } - fmt.Println("requestToken Response:\n", string(prettyJSON.Bytes())) - } - - temp := &Session{} // TODO Must be a better way - err = json.Unmarshal(body, &temp) - token = temp.Token - return -} - // Request makes a REST API GET Request with Discord. +// TODO make this handle GET, POST, DELETE, etc func Request(session *Session, urlStr string) (body []byte, err error) { req, err := http.NewRequest("GET", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(``)))) @@ -97,6 +59,45 @@ func Request(session *Session, urlStr string) (body []byte, err error) { return } +// Login asks the Discord server for an authentication token +func Login(session *Session, email string, password string) (token string, err error) { + + var urlStr string = fmt.Sprintf("%s/%s", discordApi, "auth/login") + req, err := http.NewRequest("POST", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(`{"email":"%s", "password":"%s"}`, email, password)))) + if err != nil { + return + } + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{Timeout: (20 * time.Second)} + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + if resp.StatusCode != 200 { + err = errors.New(fmt.Sprintf("StatusCode: %d, %s", resp.StatusCode, string(body))) + return + } + + if session.Debug { + var prettyJSON bytes.Buffer + error := json.Indent(&prettyJSON, body, "", "\t") + if error != nil { + fmt.Print("JSON parse error: ", error) + return + } + fmt.Println("requestToken Response:\n", string(prettyJSON.Bytes())) + } + + temp := &Session{} // TODO Must be a better way + err = json.Unmarshal(body, &temp) + token = temp.Token + return +} + // Returns the user details of the given userId // session : An active session connection to Discord // user : A user Id or name @@ -126,6 +127,16 @@ func Servers(session *Session, userId string) (servers []Server, err error) { return } +// Members returns an array of Member structures for all members of a given +// server. +func Members(session *Session, serverId int) (members []Member, err error) { + + body, err := Request(session, fmt.Sprintf("%s/guilds/%d/members", discordApi, serverId)) + err = json.Unmarshal(body, &members) + + return +} + // Channels returns an array of Channel structures for all channels of a given // server. func Channels(session *Session, serverId int) (channels []Channel, err error) { @@ -136,6 +147,44 @@ func Channels(session *Session, serverId int) (channels []Channel, err error) { return } +// Messages returns an array of Message structures for messaages within a given +// channel. limit, beforeId, and afterId can be used to control what messages +// are returned. +func Messages(session *Session, channelId int, limit int, afterId int, beforeId int) (messages []Message, err error) { + + var urlStr string + + if limit > 0 { + urlStr = fmt.Sprintf("%s/channels/%d/messages?limit=%d", discordApi, channelId, limit) + } + + if afterId > 0 { + if urlStr != "" { + urlStr = urlStr + fmt.Sprintf("&after=%d", afterId) + } else { + urlStr = fmt.Sprintf("%s/channels/%d/messages?after=%d", discordApi, channelId, afterId) + } + } + + if beforeId > 0 { + if urlStr != "" { + urlStr = urlStr + fmt.Sprintf("&before=%d", beforeId) + } else { + urlStr = fmt.Sprintf("%s/channels/%d/messages?after=%d", discordApi, channelId, beforeId) + } + } + + if urlStr == "" { + urlStr = fmt.Sprintf("%s/channels/%d/messages", discordApi, channelId) + } + + fmt.Println(urlStr) + body, err := Request(session, urlStr) + err = json.Unmarshal(body, &messages) + + return +} + // Close ends a session and logs out from the Discord REST API. func Logout(session *Session) (err error) { req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", discordApi, fmt.Sprintf("auth/logout")), bytes.NewBuffer([]byte(fmt.Sprintf(``)))) diff --git a/notes.md b/notes.md index 1fc72ed..ecc8209 100644 --- a/notes.md +++ b/notes.md @@ -2,16 +2,15 @@ Known API Commands for my reference. Login - POST http://discordapp.com/api/auth/login +Logout - POST http://discordapp.com/api/auth/logout +User Info - GET http://discordapp.com/api/users/USERID +User Servers - GET http://discordapp.com/api/users/USERID/guilds +User PCs - GET http://discordapp.com/api/users/USERID/channels + +Channel List - GET http://discordapp.com/api/guilds/GUILDID/channels +Guild Members - GET http://discordapp.com/api/guilds/GUILDID/members Send Message - POST http://discordapp.com/api/channels/CHANNELID/messages Get Messages - GET http://discordapp.com/api/channels/CHANNELID/messages -About Self - GET http://discordapp.com/api/users/@me -Guild List - GET http://discordapp.com/api/users/@me/guilds -PM Channels - GET http://discordapp.com/api/users/@me/channels - -Above commands, you can remove @me with a specific user id to view that users information. - -Channel List - GET http://discordapp.com/api/guilds/GUILDID/channels -Guild Members - GET http://discordapp.com/api/guilds/GUILDID/members diff --git a/structs.go b/structs.go index 49c3888..d400b4a 100644 --- a/structs.go +++ b/structs.go @@ -9,6 +9,14 @@ type User struct { Discriminator string `json:"discriminator"` } +type Member struct { + 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"` @@ -20,17 +28,17 @@ type Role struct { } type Message struct { - Attachments []Attachment - Tts bool - Embeds []Embed - Timestamp string - Mention_everyone bool - Id int `json:",string"` - Edited_timestamp string - Author *Author - Content string - Channel_id int `json:",string"` - Mentions []Mention + Id int `json:"id,string"` + Author User `json:"author"` + Content string `json:"content"` + Attachments []Attachment `json:"attachments"` + Tts bool `json:"tts"` + Embeds []Embed `json:"embeds"` + Timestamp string `json:"timestamp"` + MentionEveryone bool `json:"mention_everyone"` + EditedTimestamp string `json:"edited_timestamp"` + Mentions []Mention `json:"mentions"` + ChannelId int `json:"channel_id,string"` } type Mention struct { @@ -41,10 +49,3 @@ type Attachment struct { type Embed struct { } - -type Author struct { - Username string - Discriminator int `json:",string"` - Id int `json:",string"` - Avatar string -}