diff options
Diffstat (limited to 'vendor/github.com/nlopes/slack')
-rw-r--r-- | vendor/github.com/nlopes/slack/attachments.go | 16 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/bots.go | 44 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/conversation.go | 1 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/info.go | 12 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/misc.go | 21 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/team.go | 73 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/users.go | 51 | ||||
-rw-r--r-- | vendor/github.com/nlopes/slack/websocket_managed_conn.go | 21 |
8 files changed, 218 insertions, 21 deletions
diff --git a/vendor/github.com/nlopes/slack/attachments.go b/vendor/github.com/nlopes/slack/attachments.go index 4faf3e3f..f7b81617 100644 --- a/vendor/github.com/nlopes/slack/attachments.go +++ b/vendor/github.com/nlopes/slack/attachments.go @@ -1,5 +1,7 @@ package slack +import "encoding/json" + // AttachmentField contains information for an attachment field // An Attachment can contain multiple of these type AttachmentField struct { @@ -12,12 +14,12 @@ type AttachmentField struct { // using message buttons and otherwise not useful. A maximum of 5 actions may be // provided per attachment. type AttachmentAction struct { - Name string `json:"name"` // Required. - Text string `json:"text"` // Required. - Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger" - Type string `json:"type"` // Required. Must be set to "button" - Value string `json:"value,omitempty"` // Optional. - Confirm []ConfirmationField `json:"confirm,omitempty"` // Optional. + Name string `json:"name"` // Required. + Text string `json:"text"` // Required. + Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger" + Type string `json:"type"` // Required. Must be set to "button" + Value string `json:"value,omitempty"` // Optional. + Confirm *ConfirmationField `json:"confirm,omitempty"` // Optional. } // AttachmentActionCallback is sent from Slack when a user clicks a button in an interactive message (aka AttachmentAction) @@ -72,5 +74,5 @@ type Attachment struct { Footer string `json:"footer,omitempty"` FooterIcon string `json:"footer_icon,omitempty"` - Ts int64 `json:"ts,omitempty"` + Ts json.Number `json:"ts,omitempty"` } diff --git a/vendor/github.com/nlopes/slack/bots.go b/vendor/github.com/nlopes/slack/bots.go new file mode 100644 index 00000000..dc031ef5 --- /dev/null +++ b/vendor/github.com/nlopes/slack/bots.go @@ -0,0 +1,44 @@ +package slack + +import ( + "errors" + "net/url" +) + +// Bot contains information about a bot +type Bot struct { + ID string `json:"id"` + Name string `json:"name"` + Deleted bool `json:"deleted"` + Icons Icons `json:"icons"` +} + +type botResponseFull struct { + Bot `json:"bot,omitempty"` // GetBotInfo + SlackResponse +} + +func botRequest(path string, values url.Values, debug bool) (*botResponseFull, error) { + response := &botResponseFull{} + err := post(path, values, response, debug) + if err != nil { + return nil, err + } + if !response.Ok { + return nil, errors.New(response.Error) + } + return response, nil +} + +// GetBotInfo will retrive the complete bot information +func (api *Client) GetBotInfo(bot string) (*Bot, error) { + values := url.Values{ + "token": {api.config.token}, + "bot": {bot}, + } + response, err := botRequest("bots.info", values, api.debug) + if err != nil { + return nil, err + } + return &response.Bot, nil +} diff --git a/vendor/github.com/nlopes/slack/conversation.go b/vendor/github.com/nlopes/slack/conversation.go index 51b993d1..83a1d4ee 100644 --- a/vendor/github.com/nlopes/slack/conversation.go +++ b/vendor/github.com/nlopes/slack/conversation.go @@ -18,7 +18,6 @@ type groupConversation struct { Creator string `json:"creator"` IsArchived bool `json:"is_archived"` Members []string `json:"members"` - NumMembers int `json:"num_members,omitempty"` Topic Topic `json:"topic"` Purpose Purpose `json:"purpose"` } diff --git a/vendor/github.com/nlopes/slack/info.go b/vendor/github.com/nlopes/slack/info.go index 5f0e5414..445df832 100644 --- a/vendor/github.com/nlopes/slack/info.go +++ b/vendor/github.com/nlopes/slack/info.go @@ -136,15 +136,9 @@ type Team struct { // Icons XXX: needs further investigation type Icons struct { - Image48 string `json:"image_48"` -} - -// Bot contains information about a bot -type Bot struct { - ID string `json:"id"` - Name string `json:"name"` - Deleted bool `json:"deleted"` - Icons Icons `json:"icons"` + Image36 string `json:"image_36,omitempty"` + Image48 string `json:"image_48,omitempty"` + Image72 string `json:"image_72,omitempty"` } // Info contains various details about Users, Channels, Bots and the authenticated user. diff --git a/vendor/github.com/nlopes/slack/misc.go b/vendor/github.com/nlopes/slack/misc.go index c0f023cb..57f39104 100644 --- a/vendor/github.com/nlopes/slack/misc.go +++ b/vendor/github.com/nlopes/slack/misc.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "mime/multipart" "net/http" + "net/http/httputil" "net/url" "os" "path/filepath" @@ -96,6 +97,13 @@ func postWithMultipartResponse(path string, filepath string, values url.Values, return err } defer resp.Body.Close() + + // Slack seems to send an HTML body along with 5xx error codes. Don't parse it. + if resp.StatusCode != 200 { + logResponse(resp, debug) + return fmt.Errorf("Slack server error: %s.", resp.Status) + } + return parseResponseBody(resp.Body, &intf, debug) } @@ -117,3 +125,16 @@ func parseAdminResponse(method string, teamName string, values url.Values, intf endpoint := fmt.Sprintf(SLACK_WEB_API_FORMAT, teamName, method, time.Now().Unix()) return postForm(endpoint, values, intf, debug) } + +func logResponse(resp *http.Response, debug bool) error { + if debug { + text, err := httputil.DumpResponse(resp, true) + if err != nil { + return err + } + + logger.Print(text) + } + + return nil +} diff --git a/vendor/github.com/nlopes/slack/team.go b/vendor/github.com/nlopes/slack/team.go index 41507f68..d4e7899f 100644 --- a/vendor/github.com/nlopes/slack/team.go +++ b/vendor/github.com/nlopes/slack/team.go @@ -3,6 +3,12 @@ package slack import ( "errors" "net/url" + "strconv" +) + +const ( + DEFAULT_LOGINS_COUNT = 100 + DEFAULT_LOGINS_PAGE = 1 ) type TeamResponse struct { @@ -18,6 +24,41 @@ type TeamInfo struct { Icon map[string]interface{} `json:"icon"` } +type LoginResponse struct { + Logins []Login `json:"logins"` + Paging `json:"paging"` + SlackResponse +} + + +type Login struct { + UserID string `json:"user_id"` + Username string `json:"username"` + DateFirst int `json:"date_first"` + DateLast int `json:"date_last"` + Count int `json:"count"` + IP string `json:"ip"` + UserAgent string `json:"user_agent"` + ISP string `json:"isp"` + Country string `json:"country"` + Region string `json:"region"` +} + +// AccessLogParameters contains all the parameters necessary (including the optional ones) for a GetAccessLogs() request +type AccessLogParameters struct { + Count int + Page int +} + +// NewAccessLogParameters provides an instance of AccessLogParameters with all the sane default values set +func NewAccessLogParameters() AccessLogParameters { + return AccessLogParameters{ + Count: DEFAULT_LOGINS_COUNT, + Page: DEFAULT_LOGINS_PAGE, + } +} + + func teamRequest(path string, values url.Values, debug bool) (*TeamResponse, error) { response := &TeamResponse{} err := post(path, values, response, debug) @@ -32,6 +73,19 @@ func teamRequest(path string, values url.Values, debug bool) (*TeamResponse, err return response, nil } +func accessLogsRequest(path string, values url.Values, debug bool) (*LoginResponse, error) { + response := &LoginResponse{} + err := post(path, values, response, debug) + if err != nil { + return nil, err + } + if !response.Ok { + return nil, errors.New(response.Error) + } + return response, nil +} + + // GetTeamInfo gets the Team Information of the user func (api *Client) GetTeamInfo() (*TeamInfo, error) { values := url.Values{ @@ -44,3 +98,22 @@ func (api *Client) GetTeamInfo() (*TeamInfo, error) { } return &response.Team, nil } + +// GetAccessLogs retrieves a page of logins according to the parameters given +func (api *Client) GetAccessLogs(params AccessLogParameters) ([]Login, *Paging, error) { + values := url.Values{ + "token": {api.config.token}, + } + if params.Count != DEFAULT_LOGINS_COUNT { + values.Add("count", strconv.Itoa(params.Count)) + } + if params.Page != DEFAULT_LOGINS_PAGE { + values.Add("page", strconv.Itoa(params.Page)) + } + response, err := accessLogsRequest("team.accessLogs", values, api.debug) + if err != nil { + return nil, nil, err + } + return response.Logins, &response.Paging, nil +} + diff --git a/vendor/github.com/nlopes/slack/users.go b/vendor/github.com/nlopes/slack/users.go index a0ed81e6..f2d5447f 100644 --- a/vendor/github.com/nlopes/slack/users.go +++ b/vendor/github.com/nlopes/slack/users.go @@ -21,6 +21,8 @@ type UserProfile struct { Image192 string `json:"image_192"` ImageOriginal string `json:"image_original"` Title string `json:"title"` + BotID string `json:"bot_id,omitempty"` + ApiAppID string `json:"api_app_id,omitempty"` } // User contains all the information of a user @@ -55,6 +57,39 @@ type UserPresence struct { LastActivity JSONTime `json:"last_activity,omitempty"` } +type UserIdentityResponse struct { + User UserIdentity `json:"user"` + Team TeamIdentity `json:"team"` + SlackResponse +} + +type UserIdentity struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + Image24 string `json:"image_24"` + Image32 string `json:"image_32"` + Image48 string `json:"image_48"` + Image72 string `json:"image_72"` + Image192 string `json:"image_192"` + Image512 string `json:"image_512"` +} + +type TeamIdentity struct { + ID string `json:"id"` + Name string `json:"name"` + Domain string `json:"domain"` + Image34 string `json:"image_34"` + Image44 string `json:"image_44"` + Image68 string `json:"image_68"` + Image88 string `json:"image_88"` + Image102 string `json:"image_102"` + Image132 string `json:"image_132"` + Image230 string `json:"image_230"` + ImageDefault bool `json:"image_default"` + ImageOriginal string `json:"image_original"` +} + type userResponseFull struct { Members []User `json:"members,omitempty"` // ListUsers User `json:"user,omitempty"` // GetUserInfo @@ -138,3 +173,19 @@ func (api *Client) SetUserPresence(presence string) error { return nil } + +// GetUserIdentity will retrieve user info available per identity scopes +func (api *Client) GetUserIdentity() (*UserIdentityResponse, error) { + values := url.Values{ + "token": {api.config.token}, + } + response := &UserIdentityResponse{} + err := post("users.identity", values, response, api.debug) + if err != nil { + return nil, err + } + if !response.Ok { + return nil, errors.New(response.Error) + } + return response, nil +} diff --git a/vendor/github.com/nlopes/slack/websocket_managed_conn.go b/vendor/github.com/nlopes/slack/websocket_managed_conn.go index db2df902..65bb7299 100644 --- a/vendor/github.com/nlopes/slack/websocket_managed_conn.go +++ b/vendor/github.com/nlopes/slack/websocket_managed_conn.go @@ -90,6 +90,7 @@ func (rtm *RTM) connect(connectionCount int) (*Info, *websocket.Conn, error) { rtm.IncomingEvents <- RTMEvent{"invalid_auth", &InvalidAuthEvent{}} return nil, nil, sErr } + // any other errors are treated as recoverable and we try again after // sending the event along the IncomingEvents channel rtm.IncomingEvents <- RTMEvent{"connection_error", &ConnectionErrorEvent{ @@ -191,6 +192,18 @@ func (rtm *RTM) handleIncomingEvents(keepRunning <-chan bool) { } } +func (rtm *RTM) sendWithDeadline(msg interface{}) error { + // set a write deadline on the connection + if err := rtm.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)); err != nil { + return err + } + if err := websocket.JSON.Send(rtm.conn, msg); err != nil { + return err + } + // remove write deadline + return rtm.conn.SetWriteDeadline(time.Time{}) +} + // sendOutgoingMessage sends the given OutgoingMessage to the slack websocket. // // It does not currently detect if a outgoing message fails due to a disconnect @@ -204,8 +217,8 @@ func (rtm *RTM) sendOutgoingMessage(msg OutgoingMessage) { }} return } - err := websocket.JSON.Send(rtm.conn, msg) - if err != nil { + + if err := rtm.sendWithDeadline(msg); err != nil { rtm.IncomingEvents <- RTMEvent{"outgoing_error", &OutgoingErrorEvent{ Message: msg, ErrorObj: err, @@ -227,8 +240,8 @@ func (rtm *RTM) ping() error { rtm.pings[id] = time.Now() msg := &Ping{ID: id, Type: "ping"} - err := websocket.JSON.Send(rtm.conn, msg) - if err != nil { + + if err := rtm.sendWithDeadline(msg); err != nil { rtm.Debugf("RTM Error sending 'PING %d': %s", id, err.Error()) return err } |