Browse Source

Refactoring stuff, moved things around :)

Bruce Marriner 9 years ago
parent
commit
c0f68b4bd5
3 changed files with 229 additions and 27 deletions
  1. 52 0
      discord.go
  2. 141 0
      session.go
  3. 36 27
      structs.go

+ 52 - 0
discord.go

@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Discordgo v0 by Bruce Marriner <bruce@sqls.net>
+ * A DiscordApp API for Golang.
+ *
+ * Currently only the REST API is functional.  I will add on the websocket
+ * layer once I get the API section where I want it.
+ *
+ */
+
+package discordgo
+
+// Define known API URL paths as global constants
+const (
+	discordUrl = "http://discordapp.com"
+	discordApi = discordUrl + "/api/"
+	servers    = discordApi + "guilds"
+	channels   = discordApi + "channels"
+	users      = discordApi + "users"
+)
+
+// possible all-inclusive strut..
+type Discord struct {
+	Session
+	User    User
+	Servers []Server
+}
+
+// Create a new connection to Discord API.  Returns a client session handle.
+// this is a all inclusive type of easy setup command that will return
+// a connection, user information, and available channels.
+// This is probably the most common way to use the library but you
+// can use the "manual" functions below instead.
+func New(email string, password string) (discord *Discord, err error) {
+
+	session := Session{}
+
+	session.Token, err = session.RequestToken(email, password)
+	if err != nil {
+		return
+	}
+
+	user, err := session.Self()
+	if err != nil {
+		return
+	}
+
+	servers, err := session.Servers()
+
+	discord = &Discord{session, user, servers}
+
+	return
+}

+ 141 - 0
session.go

@@ -0,0 +1,141 @@
+/******************************************************************************
+ * Discordgo v0 by Bruce Marriner <bruce@sqls.net>
+ * A DiscordApp API for Golang.
+ *
+ * Currently only the REST API is functional.  I will add on the websocket
+ * layer once I get the API section where I want it.
+ *
+ */
+
+package discordgo
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+// Represents a session connection to the Discord REST API.
+// I suspect I'll be adding more to this later :)
+type Session struct {
+	Token string
+	Debug bool
+}
+
+// RequestToken asks the Rest server for a token by provided email/password
+func (session *Session) RequestToken(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
+}
+
+// Identify session user
+func (session *Session) Self() (user User, err error) {
+
+	body, err := Request(session, fmt.Sprintf("%s/%s", discordApi, "users/@me"))
+	err = json.Unmarshal(body, &user)
+
+	return
+}
+
+// Request makes a API GET Request.  This is a general purpose function
+// and is used by all API functions.  It is exposed currently so it can
+// also be used outside of this library.
+func Request(session *Session, urlStr string) (body []byte, err error) {
+
+	req, err := http.NewRequest("GET", urlStr, bytes.NewBuffer([]byte(fmt.Sprintf(``))))
+	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
+	}
+
+	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
+	}
+
+	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(urlStr+" Response:\n", string(prettyJSON.Bytes()))
+	}
+	return
+}
+
+func (session *Session) Servers() (servers []Server, err error) {
+
+	body, err := Request(session, fmt.Sprintf("%s/%s", discordApi, fmt.Sprintf("users/@me/guilds")))
+	//body, err := Request(session, fmt.Sprintf("%s/%s", discordApi, fmt.Sprintf("users/%s/guilds", session.Id)))
+	err = json.Unmarshal(body, &servers)
+
+	return
+}
+
+func (session *Session) Channels(serverId int) (channels []Channel, err error) {
+
+	body, err := Request(session, fmt.Sprintf("%s/%s", discordApi, fmt.Sprintf("guilds/%d/channels", serverId)))
+	err = json.Unmarshal(body, &channels)
+
+	return
+}
+
+func (session *Session) PrivateChannels() (channels []Channel, err error) {
+
+	body, err := Request(session, fmt.Sprintf("%s/%s", discordApi, fmt.Sprintf("users/@me/channels")))
+	err = json.Unmarshal(body, &channels)
+
+	return
+}

+ 36 - 27
structs.go

@@ -1,36 +1,48 @@
 package discordgo
 
+type User struct {
+	Id            int    `json:"id,string"`
+	Email         string `json:"email"`
+	Username      string `json:"username"`
+	Avatar        string `json:"Avatar"`
+	Verified      bool   `json:"verified"`
+	Discriminator string `json:"discriminator"`
+}
+
 type Server struct {
-	Afk_timeout int
-	Joined_at   string
-	// Afk_channel_id int `json:",string"`
-	Id   int `json:",string"`
-	Icon string
-	Name string
-	//	Roles          []Role
-	Region string
-	//Embed_channel_id int `json:",string"`
-	//	Embed_channel_id string
-	//	Embed_enabled    bool
-	Owner_id int `json:",string"`
+	Id               int    `json:"id,string"`
+	Name             string `json:"name"`
+	Icon             string `json:"icon"`
+	Region           string `json:"region"`
+	Joined_at        string `json:"joined_at"`
+	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"`
+	Roles            []Role `json:"roles"`
 }
 
 type Role struct {
-	Permissions int
-	Id          int `json:",string"`
-	Name        string
+	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"`
 }
 
 type Channel struct {
-	Guild_id        int `json:",string"`
-	Id              int `json:",string"`
-	Name            string
-	Last_message_id string
-	Is_private      string
-
-	//	Permission_overwrites string
-	//	Position              int `json:",string"`
-	//	Type                  string
+	Server_id             int    `json:"guild_id,string,omitempty"`
+	Id                    int    `json:"id,string"`
+	Name                  string `json:"name"`
+	Topic                 string `json:"topic"`
+	Position              int    `json:"position"`
+	Last_message_id       int    `json:"last_message_id,string"`
+	Type                  string `json:"type"`
+	Is_private            bool   `json:"is_private"`
+	Permission_overwrites string `json:"-"` // ignored for now
 }
 
 type Message struct {
@@ -62,6 +74,3 @@ type Author struct {
 	Id            int `json:",string"`
 	Avatar        string
 }
-
-type User struct {
-}