diff options
Diffstat (limited to 'vendor/github.com/nlopes/slack/users.go')
-rw-r--r-- | vendor/github.com/nlopes/slack/users.go | 169 |
1 files changed, 104 insertions, 65 deletions
diff --git a/vendor/github.com/nlopes/slack/users.go b/vendor/github.com/nlopes/slack/users.go index 74b79372..4da8e4ce 100644 --- a/vendor/github.com/nlopes/slack/users.go +++ b/vendor/github.com/nlopes/slack/users.go @@ -3,16 +3,15 @@ package slack import ( "context" "encoding/json" - "errors" "net/url" "strconv" + "time" ) const ( DEFAULT_USER_PHOTO_CROP_X = -1 DEFAULT_USER_PHOTO_CROP_Y = -1 DEFAULT_USER_PHOTO_CROP_W = -1 - errPaginationComplete = errorString("pagination complete") ) // UserProfile contains all the information details of a given user @@ -37,6 +36,7 @@ type UserProfile struct { ApiAppID string `json:"api_app_id,omitempty"` StatusText string `json:"status_text,omitempty"` StatusEmoji string `json:"status_emoji,omitempty"` + StatusExpiration int `json:"status_expiration"` Team string `json:"team"` Fields UserProfileCustomFields `json:"fields"` } @@ -100,28 +100,31 @@ type UserProfileCustomField struct { // User contains all the information of a user type User struct { - ID string `json:"id"` - TeamID string `json:"team_id"` - Name string `json:"name"` - Deleted bool `json:"deleted"` - Color string `json:"color"` - RealName string `json:"real_name"` - TZ string `json:"tz,omitempty"` - TZLabel string `json:"tz_label"` - TZOffset int `json:"tz_offset"` - Profile UserProfile `json:"profile"` - IsBot bool `json:"is_bot"` - IsAdmin bool `json:"is_admin"` - IsOwner bool `json:"is_owner"` - IsPrimaryOwner bool `json:"is_primary_owner"` - IsRestricted bool `json:"is_restricted"` - IsUltraRestricted bool `json:"is_ultra_restricted"` - IsStranger bool `json:"is_stranger"` - IsAppUser bool `json:"is_app_user"` - Has2FA bool `json:"has_2fa"` - HasFiles bool `json:"has_files"` - Presence string `json:"presence"` - Locale string `json:"locale"` + ID string `json:"id"` + TeamID string `json:"team_id"` + Name string `json:"name"` + Deleted bool `json:"deleted"` + Color string `json:"color"` + RealName string `json:"real_name"` + TZ string `json:"tz,omitempty"` + TZLabel string `json:"tz_label"` + TZOffset int `json:"tz_offset"` + Profile UserProfile `json:"profile"` + IsBot bool `json:"is_bot"` + IsAdmin bool `json:"is_admin"` + IsOwner bool `json:"is_owner"` + IsPrimaryOwner bool `json:"is_primary_owner"` + IsRestricted bool `json:"is_restricted"` + IsUltraRestricted bool `json:"is_ultra_restricted"` + IsStranger bool `json:"is_stranger"` + IsAppUser bool `json:"is_app_user"` + IsInvitedUser bool `json:"is_invited_user"` + Has2FA bool `json:"has_2fa"` + HasFiles bool `json:"has_files"` + Presence string `json:"presence"` + Locale string `json:"locale"` + Updated JSONTime `json:"updated"` + Enterprise EnterpriseUser `json:"enterprise_user,omitempty"` } // UserPresence contains details about a user online status @@ -152,6 +155,17 @@ type UserIdentity struct { Image512 string `json:"image_512"` } +// EnterpriseUser is present when a user is part of Slack Enterprise Grid +// https://api.slack.com/types/user#enterprise_grid_user_objects +type EnterpriseUser struct { + ID string `json:"id"` + EnterpriseID string `json:"enterprise_id"` + EnterpriseName string `json:"enterprise_name"` + IsAdmin bool `json:"is_admin"` + IsOwner bool `json:"is_owner"` + Teams []string `json:"teams"` +} + type TeamIdentity struct { ID string `json:"id"` Name string `json:"name"` @@ -189,9 +203,9 @@ func NewUserSetPhotoParams() UserSetPhotoParams { } } -func userRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*userResponseFull, error) { +func (api *Client) userRequest(ctx context.Context, path string, values url.Values) (*userResponseFull, error) { response := &userResponseFull{} - err := postForm(ctx, client, APIURL+path, values, response, d) + err := api.postMethod(ctx, path, values, response) if err != nil { return nil, err } @@ -211,7 +225,7 @@ func (api *Client) GetUserPresenceContext(ctx context.Context, user string) (*Us "user": {user}, } - response, err := userRequest(ctx, api.httpclient, "users.getPresence", values, api) + response, err := api.userRequest(ctx, "users.getPresence", values) if err != nil { return nil, err } @@ -231,7 +245,7 @@ func (api *Client) GetUserInfoContext(ctx context.Context, user string) (*User, "include_locale": {strconv.FormatBool(true)}, } - response, err := userRequest(ctx, api.httpclient, "users.info", values, api) + response, err := api.userRequest(ctx, "users.info", values) if err != nil { return nil, err } @@ -310,7 +324,7 @@ func (t UserPagination) Next(ctx context.Context) (_ UserPagination, err error) "include_locale": {strconv.FormatBool(true)}, } - if resp, err = userRequest(ctx, t.c.httpclient, "users.list", values, t.c); err != nil { + if resp, err = t.c.userRequest(ctx, "users.list", values); err != nil { return t, err } @@ -333,12 +347,19 @@ func (api *Client) GetUsers() ([]User, error) { // GetUsersContext returns the list of users (with their detailed information) with a custom context func (api *Client) GetUsersContext(ctx context.Context) (results []User, err error) { - var ( - p UserPagination - ) - - for p = api.GetUsersPaginated(); !p.Done(err); p, err = p.Next(ctx) { - results = append(results, p.Users...) + p := api.GetUsersPaginated() + for err == nil { + p, err = p.Next(ctx) + if err == nil { + results = append(results, p.Users...) + } else if rateLimitedError, ok := err.(*RateLimitedError); ok { + select { + case <-ctx.Done(): + err = ctx.Err() + case <-time.After(rateLimitedError.RetryAfter): + err = nil + } + } } return results, p.Failure(err) @@ -355,7 +376,7 @@ func (api *Client) GetUserByEmailContext(ctx context.Context, email string) (*Us "token": {api.token}, "email": {email}, } - response, err := userRequest(ctx, api.httpclient, "users.lookupByEmail", values, api) + response, err := api.userRequest(ctx, "users.lookupByEmail", values) if err != nil { return nil, err } @@ -373,7 +394,7 @@ func (api *Client) SetUserAsActiveContext(ctx context.Context) (err error) { "token": {api.token}, } - _, err = userRequest(ctx, api.httpclient, "users.setActive", values, api) + _, err = api.userRequest(ctx, "users.setActive", values) return err } @@ -389,7 +410,7 @@ func (api *Client) SetUserPresenceContext(ctx context.Context, presence string) "presence": {presence}, } - _, err := userRequest(ctx, api.httpclient, "users.setPresence", values, api) + _, err := api.userRequest(ctx, "users.setPresence", values) return err } @@ -399,19 +420,21 @@ func (api *Client) GetUserIdentity() (*UserIdentityResponse, error) { } // GetUserIdentityContext will retrieve user info available per identity scopes with a custom context -func (api *Client) GetUserIdentityContext(ctx context.Context) (*UserIdentityResponse, error) { +func (api *Client) GetUserIdentityContext(ctx context.Context) (response *UserIdentityResponse, err error) { values := url.Values{ "token": {api.token}, } - response := &UserIdentityResponse{} + response = &UserIdentityResponse{} - err := postForm(ctx, api.httpclient, APIURL+"users.identity", values, response, api) + err = api.postMethod(ctx, "users.identity", values, response) if err != nil { return nil, err } - if !response.Ok { - return nil, errors.New(response.Error) + + if err := response.Err(); err != nil { + return nil, err } + return response, nil } @@ -421,7 +444,7 @@ func (api *Client) SetUserPhoto(image string, params UserSetPhotoParams) error { } // SetUserPhotoContext changes the currently authenticated user's profile image using a custom context -func (api *Client) SetUserPhotoContext(ctx context.Context, image string, params UserSetPhotoParams) error { +func (api *Client) SetUserPhotoContext(ctx context.Context, image string, params UserSetPhotoParams) (err error) { response := &SlackResponse{} values := url.Values{ "token": {api.token}, @@ -436,7 +459,7 @@ func (api *Client) SetUserPhotoContext(ctx context.Context, image string, params values.Add("crop_w", strconv.Itoa(params.CropW)) } - err := postLocalWithMultipartResponse(ctx, api.httpclient, "users.setPhoto", image, "image", values, response, api) + err = postLocalWithMultipartResponse(ctx, api.httpclient, api.endpoint+"users.setPhoto", image, "image", values, response, api) if err != nil { return err } @@ -450,13 +473,13 @@ func (api *Client) DeleteUserPhoto() error { } // DeleteUserPhotoContext deletes the current authenticated user's profile image with a custom context -func (api *Client) DeleteUserPhotoContext(ctx context.Context) error { +func (api *Client) DeleteUserPhotoContext(ctx context.Context) (err error) { response := &SlackResponse{} values := url.Values{ "token": {api.token}, } - err := postForm(ctx, api.httpclient, APIURL+"users.deletePhoto", values, response, api) + err = api.postMethod(ctx, "users.deletePhoto", values, response) if err != nil { return err } @@ -467,15 +490,30 @@ func (api *Client) DeleteUserPhotoContext(ctx context.Context) error { // SetUserCustomStatus will set a custom status and emoji for the currently // authenticated user. If statusEmoji is "" and statusText is not, the Slack API // will automatically set it to ":speech_balloon:". Otherwise, if both are "" -// the Slack API will unset the custom status/emoji. -func (api *Client) SetUserCustomStatus(statusText, statusEmoji string) error { - return api.SetUserCustomStatusContext(context.Background(), statusText, statusEmoji) +// the Slack API will unset the custom status/emoji. If statusExpiration is set to 0 +// the status will not expire. +func (api *Client) SetUserCustomStatus(statusText, statusEmoji string, statusExpiration int64) error { + return api.SetUserCustomStatusContextWithUser(context.Background(), "", statusText, statusEmoji, statusExpiration) } // SetUserCustomStatusContext will set a custom status and emoji for the currently authenticated user with a custom context // // For more information see SetUserCustomStatus -func (api *Client) SetUserCustomStatusContext(ctx context.Context, statusText, statusEmoji string) error { +func (api *Client) SetUserCustomStatusContext(ctx context.Context, statusText, statusEmoji string, statusExpiration int64) error { + return api.SetUserCustomStatusContextWithUser(context.Background(), "", statusText, statusEmoji, statusExpiration) +} + +// SetUserCustomStatusWithUser will set a custom status and emoji for the provided user. +// +// For more information see SetUserCustomStatus +func (api *Client) SetUserCustomStatusWithUser(user, statusText, statusEmoji string, statusExpiration int64) error { + return api.SetUserCustomStatusContextWithUser(context.Background(), user, statusText, statusEmoji, statusExpiration) +} + +// SetUserCustomStatusContextWithUser will set a custom status and emoji for the provided user with a custom context +// +// For more information see SetUserCustomStatus +func (api *Client) SetUserCustomStatusContextWithUser(ctx context.Context, user, statusText, statusEmoji string, statusExpiration int64) error { // XXX(theckman): this anonymous struct is for making requests to the Slack // API for setting and unsetting a User's Custom Status/Emoji. To change // these values we must provide a JSON document as the profile POST field. @@ -488,11 +526,13 @@ func (api *Client) SetUserCustomStatusContext(ctx context.Context, statusText, s // - https://api.slack.com/docs/presence-and-status#custom_status profile, err := json.Marshal( &struct { - StatusText string `json:"status_text"` - StatusEmoji string `json:"status_emoji"` + StatusText string `json:"status_text"` + StatusEmoji string `json:"status_emoji"` + StatusExpiration int64 `json:"status_expiration"` }{ - StatusText: statusText, - StatusEmoji: statusEmoji, + StatusText: statusText, + StatusEmoji: statusEmoji, + StatusExpiration: statusExpiration, }, ) @@ -501,20 +541,17 @@ func (api *Client) SetUserCustomStatusContext(ctx context.Context, statusText, s } values := url.Values{ + "user": {user}, "token": {api.token}, "profile": {string(profile)}, } response := &userResponseFull{} - if err = postForm(ctx, api.httpclient, APIURL+"users.profile.set", values, response, api); err != nil { + if err = api.postMethod(ctx, "users.profile.set", values, response); err != nil { return err } - if !response.Ok { - return errors.New(response.Error) - } - - return nil + return response.Err() } // UnsetUserCustomStatus removes the custom status message for the currently @@ -526,7 +563,7 @@ func (api *Client) UnsetUserCustomStatus() error { // UnsetUserCustomStatusContext removes the custom status message for the currently authenticated user // with a custom context. This is a convenience method that wraps (*Client).SetUserCustomStatus(). func (api *Client) UnsetUserCustomStatusContext(ctx context.Context) error { - return api.SetUserCustomStatusContext(ctx, "", "") + return api.SetUserCustomStatusContext(ctx, "", "", 0) } // GetUserProfile retrieves a user's profile information. @@ -547,12 +584,14 @@ func (api *Client) GetUserProfileContext(ctx context.Context, userID string, inc } resp := &getUserProfileResponse{} - err := postSlackMethod(ctx, api.httpclient, "users.profile.get", values, &resp, api) + err := api.postMethod(ctx, "users.profile.get", values, &resp) if err != nil { return nil, err } - if !resp.Ok { - return nil, errors.New(resp.Error) + + if err := resp.Err(); err != nil { + return nil, err } + return resp.Profile, nil } |