Update vendor (slack)

This commit is contained in:
Wim 2016-11-06 00:07:24 +01:00
parent 2dbe0eb557
commit 37873acfcd
9 changed files with 220 additions and 23 deletions

View File

@ -1,5 +1,7 @@
package slack package slack
import "encoding/json"
// AttachmentField contains information for an attachment field // AttachmentField contains information for an attachment field
// An Attachment can contain multiple of these // An Attachment can contain multiple of these
type AttachmentField struct { type AttachmentField struct {
@ -12,12 +14,12 @@ type AttachmentField struct {
// using message buttons and otherwise not useful. A maximum of 5 actions may be // using message buttons and otherwise not useful. A maximum of 5 actions may be
// provided per attachment. // provided per attachment.
type AttachmentAction struct { type AttachmentAction struct {
Name string `json:"name"` // Required. Name string `json:"name"` // Required.
Text string `json:"text"` // Required. Text string `json:"text"` // Required.
Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger" Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger"
Type string `json:"type"` // Required. Must be set to "button" Type string `json:"type"` // Required. Must be set to "button"
Value string `json:"value,omitempty"` // Optional. Value string `json:"value,omitempty"` // Optional.
Confirm []ConfirmationField `json:"confirm,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) // 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"` Footer string `json:"footer,omitempty"`
FooterIcon string `json:"footer_icon,omitempty"` FooterIcon string `json:"footer_icon,omitempty"`
Ts int64 `json:"ts,omitempty"` Ts json.Number `json:"ts,omitempty"`
} }

44
vendor/github.com/nlopes/slack/bots.go generated vendored Normal file
View File

@ -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
}

View File

@ -18,7 +18,6 @@ type groupConversation struct {
Creator string `json:"creator"` Creator string `json:"creator"`
IsArchived bool `json:"is_archived"` IsArchived bool `json:"is_archived"`
Members []string `json:"members"` Members []string `json:"members"`
NumMembers int `json:"num_members,omitempty"`
Topic Topic `json:"topic"` Topic Topic `json:"topic"`
Purpose Purpose `json:"purpose"` Purpose Purpose `json:"purpose"`
} }

View File

@ -136,15 +136,9 @@ type Team struct {
// Icons XXX: needs further investigation // Icons XXX: needs further investigation
type Icons struct { type Icons struct {
Image48 string `json:"image_48"` Image36 string `json:"image_36,omitempty"`
} Image48 string `json:"image_48,omitempty"`
Image72 string `json:"image_72,omitempty"`
// 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"`
} }
// Info contains various details about Users, Channels, Bots and the authenticated user. // Info contains various details about Users, Channels, Bots and the authenticated user.

View File

@ -9,6 +9,7 @@ import (
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/http/httputil"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -96,6 +97,13 @@ func postWithMultipartResponse(path string, filepath string, values url.Values,
return err return err
} }
defer resp.Body.Close() 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) 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()) endpoint := fmt.Sprintf(SLACK_WEB_API_FORMAT, teamName, method, time.Now().Unix())
return postForm(endpoint, values, intf, debug) 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
}

View File

@ -3,6 +3,12 @@ package slack
import ( import (
"errors" "errors"
"net/url" "net/url"
"strconv"
)
const (
DEFAULT_LOGINS_COUNT = 100
DEFAULT_LOGINS_PAGE = 1
) )
type TeamResponse struct { type TeamResponse struct {
@ -18,6 +24,41 @@ type TeamInfo struct {
Icon map[string]interface{} `json:"icon"` 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) { func teamRequest(path string, values url.Values, debug bool) (*TeamResponse, error) {
response := &TeamResponse{} response := &TeamResponse{}
err := post(path, values, response, debug) err := post(path, values, response, debug)
@ -32,6 +73,19 @@ func teamRequest(path string, values url.Values, debug bool) (*TeamResponse, err
return response, nil 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 // GetTeamInfo gets the Team Information of the user
func (api *Client) GetTeamInfo() (*TeamInfo, error) { func (api *Client) GetTeamInfo() (*TeamInfo, error) {
values := url.Values{ values := url.Values{
@ -44,3 +98,22 @@ func (api *Client) GetTeamInfo() (*TeamInfo, error) {
} }
return &response.Team, nil 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
}

View File

@ -21,6 +21,8 @@ type UserProfile struct {
Image192 string `json:"image_192"` Image192 string `json:"image_192"`
ImageOriginal string `json:"image_original"` ImageOriginal string `json:"image_original"`
Title string `json:"title"` 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 // User contains all the information of a user
@ -55,6 +57,39 @@ type UserPresence struct {
LastActivity JSONTime `json:"last_activity,omitempty"` 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 { type userResponseFull struct {
Members []User `json:"members,omitempty"` // ListUsers Members []User `json:"members,omitempty"` // ListUsers
User `json:"user,omitempty"` // GetUserInfo User `json:"user,omitempty"` // GetUserInfo
@ -138,3 +173,19 @@ func (api *Client) SetUserPresence(presence string) error {
return nil 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
}

View File

@ -90,6 +90,7 @@ func (rtm *RTM) connect(connectionCount int) (*Info, *websocket.Conn, error) {
rtm.IncomingEvents <- RTMEvent{"invalid_auth", &InvalidAuthEvent{}} rtm.IncomingEvents <- RTMEvent{"invalid_auth", &InvalidAuthEvent{}}
return nil, nil, sErr return nil, nil, sErr
} }
// any other errors are treated as recoverable and we try again after // any other errors are treated as recoverable and we try again after
// sending the event along the IncomingEvents channel // sending the event along the IncomingEvents channel
rtm.IncomingEvents <- RTMEvent{"connection_error", &ConnectionErrorEvent{ 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. // sendOutgoingMessage sends the given OutgoingMessage to the slack websocket.
// //
// It does not currently detect if a outgoing message fails due to a disconnect // 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 return
} }
err := websocket.JSON.Send(rtm.conn, msg)
if err != nil { if err := rtm.sendWithDeadline(msg); err != nil {
rtm.IncomingEvents <- RTMEvent{"outgoing_error", &OutgoingErrorEvent{ rtm.IncomingEvents <- RTMEvent{"outgoing_error", &OutgoingErrorEvent{
Message: msg, Message: msg,
ErrorObj: err, ErrorObj: err,
@ -227,8 +240,8 @@ func (rtm *RTM) ping() error {
rtm.pings[id] = time.Now() rtm.pings[id] = time.Now()
msg := &Ping{ID: id, Type: "ping"} 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()) rtm.Debugf("RTM Error sending 'PING %d': %s", id, err.Error())
return err return err
} }

4
vendor/manifest vendored
View File

@ -138,8 +138,8 @@
"importpath": "github.com/nlopes/slack", "importpath": "github.com/nlopes/slack",
"repository": "https://github.com/nlopes/slack", "repository": "https://github.com/nlopes/slack",
"vcs": "git", "vcs": "git",
"revision": "4feee83bb2b31d790977ce727a028c6a542c72c7", "revision": "e595e9d8590a04ff76407e4e7d1791d25b095c66",
"branch": "HEAD", "branch": "master",
"notests": true "notests": true
}, },
{ {