Browse Source

Added Message func to client.go to pull channel messages

Bruce Marriner 9 years ago
parent
commit
782fbe2bc9
4 changed files with 108 additions and 50 deletions
  1. 9 0
      _examples/demo.go
  2. 73 24
      client.go
  3. 7 8
      notes.md
  4. 19 18
      structs.go

+ 9 - 0
_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

+ 73 - 24
client.go

@@ -19,24 +19,29 @@ import (
 	"time"
 )
 
-// RequestToken asks the Discord server for an authentication token
-func Login(session *Session, email string, password string) (token string, err error) {
+// 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) {
 
-	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))))
+	req, err := http.NewRequest("GET", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(``))))
 	if err != nil {
 		return
 	}
-	req.Header.Set("Content-Type", "application/json")
 
+	req.Header.Set("authorization", session.Token)
+	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)
+	body, err = ioutil.ReadAll(resp.Body)
+	resp.Body.Close()
+	if err != nil {
+		return
+	}
+
 	if resp.StatusCode != 200 {
 		err = errors.New(fmt.Sprintf("StatusCode: %d, %s", resp.StatusCode, string(body)))
 		return
@@ -49,37 +54,29 @@ func Login(session *Session, email string, password string) (token string, err e
 			fmt.Print("JSON parse error: ", error)
 			return
 		}
-		fmt.Println("requestToken Response:\n", string(prettyJSON.Bytes()))
+		fmt.Println(urlStr+" 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.
-func Request(session *Session, urlStr string) (body []byte, err error) {
+// Login asks the Discord server for an authentication token
+func Login(session *Session, email string, password string) (token string, err error) {
 
-	req, err := http.NewRequest("GET", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(``))))
+	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("authorization", session.Token)
 	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, err = ioutil.ReadAll(resp.Body)
-	resp.Body.Close()
-	if err != nil {
-		return
-	}
-
+	body, _ := ioutil.ReadAll(resp.Body)
 	if resp.StatusCode != 200 {
 		err = errors.New(fmt.Sprintf("StatusCode: %d, %s", resp.StatusCode, string(body)))
 		return
@@ -92,8 +89,12 @@ func Request(session *Session, urlStr string) (body []byte, err error) {
 			fmt.Print("JSON parse error: ", error)
 			return
 		}
-		fmt.Println(urlStr+" Response:\n", string(prettyJSON.Bytes()))
+		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
 }
 
@@ -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(``))))

+ 7 - 8
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

+ 19 - 18
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
-}