diff options
Diffstat (limited to 'vendor/github.com/sromku/go-gitter/gitter.go')
-rw-r--r-- | vendor/github.com/sromku/go-gitter/gitter.go | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/vendor/github.com/sromku/go-gitter/gitter.go b/vendor/github.com/sromku/go-gitter/gitter.go new file mode 100644 index 00000000..375e6e35 --- /dev/null +++ b/vendor/github.com/sromku/go-gitter/gitter.go @@ -0,0 +1,367 @@ +// Package gitter is a Go client library for the Gitter API. +// +// Author: sromku +package gitter + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/mreiferson/go-httpclient" +) + +var ( + apiBaseURL = "https://api.gitter.im/v1/" + streamBaseURL = "https://stream.gitter.im/v1/" + fayeBaseURL = "https://ws.gitter.im/faye" +) + +type Gitter struct { + config struct { + apiBaseURL string + streamBaseURL string + token string + client *http.Client + } + debug bool + logWriter io.Writer +} + +// New initializes the Gitter API client +// +// For example: +// api := gitter.New("YOUR_ACCESS_TOKEN") +func New(token string) *Gitter { + + transport := &httpclient.Transport{ + ConnectTimeout: 5 * time.Second, + ReadWriteTimeout: 40 * time.Second, + } + defer transport.Close() + + s := &Gitter{} + s.config.apiBaseURL = apiBaseURL + s.config.streamBaseURL = streamBaseURL + s.config.token = token + s.config.client = &http.Client{ + Transport: transport, + } + return s +} + +// SetClient sets a custom http client. Can be useful in App Engine case. +func (gitter *Gitter) SetClient(client *http.Client) { + gitter.config.client = client +} + +// GetUser returns the current user +func (gitter *Gitter) GetUser() (*User, error) { + + var users []User + response, err := gitter.get(gitter.config.apiBaseURL + "user") + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &users) + if err != nil { + gitter.log(err) + return nil, err + } + + if len(users) > 0 { + return &users[0], nil + } + + err = APIError{What: "Failed to retrieve current user"} + gitter.log(err) + return nil, err +} + +// GetUserRooms returns a list of Rooms the user is part of +func (gitter *Gitter) GetUserRooms(userID string) ([]Room, error) { + + var rooms []Room + response, err := gitter.get(gitter.config.apiBaseURL + "user/" + userID + "/rooms") + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &rooms) + if err != nil { + gitter.log(err) + return nil, err + } + + return rooms, nil +} + +// GetRooms returns a list of rooms the current user is in +func (gitter *Gitter) GetRooms() ([]Room, error) { + + var rooms []Room + response, err := gitter.get(gitter.config.apiBaseURL + "rooms") + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &rooms) + if err != nil { + gitter.log(err) + return nil, err + } + + return rooms, nil +} + +// GetRoom returns a room with the passed id +func (gitter *Gitter) GetRoom(roomID string) (*Room, error) { + + var room Room + response, err := gitter.get(gitter.config.apiBaseURL + "rooms/" + roomID) + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &room) + if err != nil { + gitter.log(err) + return nil, err + } + + return &room, nil +} + +// GetMessages returns a list of messages in a room. +// Pagination is optional. You can pass nil or specific pagination params. +func (gitter *Gitter) GetMessages(roomID string, params *Pagination) ([]Message, error) { + + var messages []Message + url := gitter.config.apiBaseURL + "rooms/" + roomID + "/chatMessages" + if params != nil { + url += "?" + params.encode() + } + response, err := gitter.get(url) + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &messages) + if err != nil { + gitter.log(err) + return nil, err + } + + return messages, nil +} + +// GetMessage returns a message in a room. +func (gitter *Gitter) GetMessage(roomID, messageID string) (*Message, error) { + + var message Message + response, err := gitter.get(gitter.config.apiBaseURL + "rooms/" + roomID + "/chatMessages/" + messageID) + if err != nil { + gitter.log(err) + return nil, err + } + + err = json.Unmarshal(response, &message) + if err != nil { + gitter.log(err) + return nil, err + } + + return &message, nil +} + +// SendMessage sends a message to a room +func (gitter *Gitter) SendMessage(roomID, text string) error { + + message := Message{Text: text} + body, _ := json.Marshal(message) + err := gitter.post(gitter.config.apiBaseURL+"rooms/"+roomID+"/chatMessages", body) + if err != nil { + gitter.log(err) + return err + } + + return nil +} + +// JoinRoom joins a room +func (gitter *Gitter) JoinRoom(uri string) (*Room, error) { + + message := Room{URI: uri} + body, _ := json.Marshal(message) + err := gitter.post(apiBaseURL+"rooms", body) + if err != nil { + gitter.log(err) + return nil, err + } + + rooms, err := gitter.GetRooms() + if err != nil { + gitter.log(err) + return nil, err + } + + for _, room := range rooms { + if room.URI == uri { + return &room, nil + } + } + + err = APIError{What: fmt.Sprintf("Joined room (%v) not found in list of rooms", uri)} + gitter.log(err) + return nil, err +} + +// SetDebug traces errors if it's set to true. +func (gitter *Gitter) SetDebug(debug bool, logWriter io.Writer) { + gitter.debug = debug + gitter.logWriter = logWriter +} + +// Pagination params +type Pagination struct { + + // Skip n messages + Skip int + + // Get messages before beforeId + BeforeID string + + // Get messages after afterId + AfterID string + + // Maximum number of messages to return + Limit int + + // Search query + Query string +} + +func (messageParams *Pagination) encode() string { + values := url.Values{} + + if messageParams.AfterID != "" { + values.Add("afterId", messageParams.AfterID) + } + + if messageParams.BeforeID != "" { + values.Add("beforeId", messageParams.BeforeID) + } + + if messageParams.Skip > 0 { + values.Add("skip", strconv.Itoa(messageParams.Skip)) + } + + if messageParams.Limit > 0 { + values.Add("limit", strconv.Itoa(messageParams.Limit)) + } + + return values.Encode() +} + +func (gitter *Gitter) getResponse(url string, stream *Stream) (*http.Response, error) { + r, err := http.NewRequest("GET", url, nil) + if err != nil { + gitter.log(err) + return nil, err + } + r.Header.Set("Content-Type", "application/json") + r.Header.Set("Accept", "application/json") + r.Header.Set("Authorization", "Bearer "+gitter.config.token) + if stream != nil { + stream.streamConnection.request = r + } + response, err := gitter.config.client.Do(r) + if err != nil { + gitter.log(err) + return nil, err + } + return response, nil +} + +func (gitter *Gitter) get(url string) ([]byte, error) { + resp, err := gitter.getResponse(url, nil) + if err != nil { + gitter.log(err) + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + err = APIError{What: fmt.Sprintf("Status code: %v", resp.StatusCode)} + gitter.log(err) + return nil, err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + gitter.log(err) + return nil, err + } + + return body, nil +} + +func (gitter *Gitter) post(url string, body []byte) error { + r, err := http.NewRequest("POST", url, bytes.NewBuffer(body)) + if err != nil { + gitter.log(err) + return err + } + + r.Header.Set("Content-Type", "application/json") + r.Header.Set("Accept", "application/json") + r.Header.Set("Authorization", "Bearer "+gitter.config.token) + + resp, err := gitter.config.client.Do(r) + if err != nil { + gitter.log(err) + return err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + err = APIError{What: fmt.Sprintf("Status code: %v", resp.StatusCode)} + gitter.log(err) + return err + } + + return nil +} + +func (gitter *Gitter) log(a interface{}) { + if gitter.debug { + log.Println(a) + if gitter.logWriter != nil { + timestamp := time.Now().Format(time.RFC3339) + msg := fmt.Sprintf("%v: %v", timestamp, a) + fmt.Fprintln(gitter.logWriter, msg) + } + } +} + +// APIError holds data of errors returned from the API. +type APIError struct { + What string +} + +func (e APIError) Error() string { + return fmt.Sprintf("%v", e.What) +} |