func (api *Client) UnsetUserCustomStatusContext(ctx context.Context) error {
	return api.SetUserCustomStatusContext(ctx, "", "", 0)
}
UnsetUserCustomStatusContext removes the custom status message for the currently authenticated user
with a custom context. This is a convenience method that wraps (*Client).SetUserCustomStatus().
package slack
import (
	"context"
	"encoding/json"
	"net/url"
	"strconv"
	"strings"
	"time"
)
const (
	DEFAULT_USER_PHOTO_CROP_X = -1
	DEFAULT_USER_PHOTO_CROP_Y = -1
	DEFAULT_USER_PHOTO_CROP_W = -1
)
type UserProfile struct {
	FirstName             string                  `json:"first_name"`
	LastName              string                  `json:"last_name"`
	RealName              string                  `json:"real_name"`
	RealNameNormalized    string                  `json:"real_name_normalized"`
	DisplayName           string                  `json:"display_name"`
	DisplayNameNormalized string                  `json:"display_name_normalized"`
	Email                 string                  `json:"email"`
	Skype                 string                  `json:"skype"`
	Phone                 string                  `json:"phone"`
	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"`
	ImageOriginal         string                  `json:"image_original"`
	Title                 string                  `json:"title"`
	BotID                 string                  `json:"bot_id,omitempty"`
	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"`
}
type UserProfileCustomFields struct {
	fields map[string]UserProfileCustomField
}
func (fields *UserProfileCustomFields) UnmarshalJSON(b []byte) error {
	if string(b) == "[]" {
		return nil
	}
	return json.Unmarshal(b, &fields.fields)
}
func (fields UserProfileCustomFields) MarshalJSON() ([]byte, error) {
	if len(fields.fields) == 0 {
		return []byte("[]"), nil
	}
	return json.Marshal(fields.fields)
}
func (fields *UserProfileCustomFields) ToMap() map[string]UserProfileCustomField {
	return fields.fields
}
func (fields *UserProfileCustomFields) Len() int {
	return len(fields.fields)
}
func (fields *UserProfileCustomFields) SetMap(m map[string]UserProfileCustomField) {
	fields.fields = m
}
func (profile *UserProfile) FieldsMap() map[string]UserProfileCustomField {
	return profile.Fields.ToMap()
}
func (profile *UserProfile) SetFieldsMap(m map[string]UserProfileCustomField) {
	profile.Fields.SetMap(m)
}
type UserProfileCustomField struct {
	Value string `json:"value"`
	Alt   string `json:"alt"`
	Label string `json:"label"`
}
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"`
	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"`
}
type UserPresence struct {
	Presence        string   `json:"presence,omitempty"`
	Online          bool     `json:"online,omitempty"`
	AutoAway        bool     `json:"auto_away,omitempty"`
	ManualAway      bool     `json:"manual_away,omitempty"`
	ConnectionCount int      `json:"connection_count,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 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"`
	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"`
	User    `json:"user,omitempty"`
	Users   []User `json:"users,omitempty"`
	UserPresence
	SlackResponse
	Metadata ResponseMetadata `json:"response_metadata"`
}
type UserSetPhotoParams struct {
	CropX int
	CropY int
	CropW int
}
func NewUserSetPhotoParams() UserSetPhotoParams {
	return UserSetPhotoParams{
		CropX: DEFAULT_USER_PHOTO_CROP_X,
		CropY: DEFAULT_USER_PHOTO_CROP_Y,
		CropW: DEFAULT_USER_PHOTO_CROP_W,
	}
}
func (api *Client) userRequest(ctx context.Context, path string, values url.Values) (*userResponseFull, error) {
	response := &userResponseFull{}
	err := api.postMethod(ctx, path, values, response)
	if err != nil {
		return nil, err
	}
	return response, response.Err()
}
func (api *Client) GetUserPresence(user string) (*UserPresence, error) {
	return api.GetUserPresenceContext(context.Background(), user)
}
func (api *Client) GetUserPresenceContext(ctx context.Context, user string) (*UserPresence, error) {
	values := url.Values{
		"token": {api.token},
		"user":  {user},
	}
	response, err := api.userRequest(ctx, "users.getPresence", values)
	if err != nil {
		return nil, err
	}
	return &response.UserPresence, nil
}
func (api *Client) GetUserInfo(user string) (*User, error) {
	return api.GetUserInfoContext(context.Background(), user)
}
func (api *Client) GetUserInfoContext(ctx context.Context, user string) (*User, error) {
	values := url.Values{
		"token":          {api.token},
		"user":           {user},
		"include_locale": {strconv.FormatBool(true)},
	}
	response, err := api.userRequest(ctx, "users.info", values)
	if err != nil {
		return nil, err
	}
	return &response.User, nil
}
func (api *Client) GetUsersInfo(users ...string) (*[]User, error) {
	return api.GetUsersInfoContext(context.Background(), users...)
}
func (api *Client) GetUsersInfoContext(ctx context.Context, users ...string) (*[]User, error) {
	values := url.Values{
		"token":          {api.token},
		"users":          {strings.Join(users, ",")},
		"include_locale": {strconv.FormatBool(true)},
	}
	response, err := api.userRequest(ctx, "users.info", values)
	if err != nil {
		return nil, err
	}
	return &response.Users, nil
}
type GetUsersOption func(*UserPagination)
func GetUsersOptionLimit(n int) GetUsersOption {
	return func(p *UserPagination) {
		p.limit = n
	}
}
func GetUsersOptionPresence(n bool) GetUsersOption {
	return func(p *UserPagination) {
		p.presence = n
	}
}
func newUserPagination(c *Client, options ...GetUsersOption) (up UserPagination) {
	up = UserPagination{
		c:     c,
		limit: 200,  
	}
	for _, opt := range options {
		opt(&up)
	}
	return up
}
type UserPagination struct {
	Users        []User
	limit        int
	presence     bool
	previousResp *ResponseMetadata
	c            *Client
}
func (UserPagination) Done(err error) bool {
	return err == errPaginationComplete
}
func (t UserPagination) Failure(err error) error {
	if t.Done(err) {
		return nil
	}
	return err
}
func (t UserPagination) Next(ctx context.Context) (_ UserPagination, err error) {
	var (
		resp *userResponseFull
	)
	if t.c == nil || (t.previousResp != nil && t.previousResp.Cursor == "") {
		return t, errPaginationComplete
	}
	t.previousResp = t.previousResp.initialize()
	values := url.Values{
		"limit":          {strconv.Itoa(t.limit)},
		"presence":       {strconv.FormatBool(t.presence)},
		"token":          {t.c.token},
		"cursor":         {t.previousResp.Cursor},
		"include_locale": {strconv.FormatBool(true)},
	}
	if resp, err = t.c.userRequest(ctx, "users.list", values); err != nil {
		return t, err
	}
	t.c.Debugf("GetUsersContext: got %d users; metadata %v", len(resp.Members), resp.Metadata)
	t.Users = resp.Members
	t.previousResp = &resp.Metadata
	return t, nil
}
func (api *Client) GetUsersPaginated(options ...GetUsersOption) UserPagination {
	return newUserPagination(api, options...)
}
func (api *Client) GetUsers() ([]User, error) {
	return api.GetUsersContext(context.Background())
}
func (api *Client) GetUsersContext(ctx context.Context) (results []User, err error) {
	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)
}
func (api *Client) GetUserByEmail(email string) (*User, error) {
	return api.GetUserByEmailContext(context.Background(), email)
}
func (api *Client) GetUserByEmailContext(ctx context.Context, email string) (*User, error) {
	values := url.Values{
		"token": {api.token},
		"email": {email},
	}
	response, err := api.userRequest(ctx, "users.lookupByEmail", values)
	if err != nil {
		return nil, err
	}
	return &response.User, nil
}
func (api *Client) SetUserAsActive() error {
	return api.SetUserAsActiveContext(context.Background())
}
func (api *Client) SetUserAsActiveContext(ctx context.Context) (err error) {
	values := url.Values{
		"token": {api.token},
	}
	_, err = api.userRequest(ctx, "users.setActive", values)
	return err
}
func (api *Client) SetUserPresence(presence string) error {
	return api.SetUserPresenceContext(context.Background(), presence)
}
func (api *Client) SetUserPresenceContext(ctx context.Context, presence string) error {
	values := url.Values{
		"token":    {api.token},
		"presence": {presence},
	}
	_, err := api.userRequest(ctx, "users.setPresence", values)
	return err
}
func (api *Client) GetUserIdentity() (*UserIdentityResponse, error) {
	return api.GetUserIdentityContext(context.Background())
}
func (api *Client) GetUserIdentityContext(ctx context.Context) (response *UserIdentityResponse, err error) {
	values := url.Values{
		"token": {api.token},
	}
	response = &UserIdentityResponse{}
	err = api.postMethod(ctx, "users.identity", values, response)
	if err != nil {
		return nil, err
	}
	if err := response.Err(); err != nil {
		return nil, err
	}
	return response, nil
}
func (api *Client) SetUserPhoto(image string, params UserSetPhotoParams) error {
	return api.SetUserPhotoContext(context.Background(), image, params)
}
func (api *Client) SetUserPhotoContext(ctx context.Context, image string, params UserSetPhotoParams) (err error) {
	response := &SlackResponse{}
	values := url.Values{
		"token": {api.token},
	}
	if params.CropX != DEFAULT_USER_PHOTO_CROP_X {
		values.Add("crop_x", strconv.Itoa(params.CropX))
	}
	if params.CropY != DEFAULT_USER_PHOTO_CROP_Y {
		values.Add("crop_y", strconv.Itoa(params.CropX))
	}
	if params.CropW != DEFAULT_USER_PHOTO_CROP_W {
		values.Add("crop_w", strconv.Itoa(params.CropW))
	}
	err = postLocalWithMultipartResponse(ctx, api.httpclient, api.endpoint+"users.setPhoto", image, "image", values, response, api)
	if err != nil {
		return err
	}
	return response.Err()
}
func (api *Client) DeleteUserPhoto() error {
	return api.DeleteUserPhotoContext(context.Background())
}
func (api *Client) DeleteUserPhotoContext(ctx context.Context) (err error) {
	response := &SlackResponse{}
	values := url.Values{
		"token": {api.token},
	}
	err = api.postMethod(ctx, "users.deletePhoto", values, response)
	if err != nil {
		return err
	}
	return response.Err()
}
func (api *Client) SetUserCustomStatus(statusText, statusEmoji string, statusExpiration int64) error {
	return api.SetUserCustomStatusContextWithUser(context.Background(), "", statusText, statusEmoji, statusExpiration)
}
func (api *Client) SetUserCustomStatusContext(ctx context.Context, statusText, statusEmoji string, statusExpiration int64) error {
	return api.SetUserCustomStatusContextWithUser(context.Background(), "", statusText, statusEmoji, statusExpiration)
}
func (api *Client) SetUserCustomStatusWithUser(user, statusText, statusEmoji string, statusExpiration int64) error {
	return api.SetUserCustomStatusContextWithUser(context.Background(), user, statusText, statusEmoji, statusExpiration)
}
func (api *Client) SetUserCustomStatusContextWithUser(ctx context.Context, user, statusText, statusEmoji string, statusExpiration int64) error {
	profile, err := json.Marshal(
		&struct {
			StatusText       string `json:"status_text"`
			StatusEmoji      string `json:"status_emoji"`
			StatusExpiration int64  `json:"status_expiration"`
		}{
			StatusText:       statusText,
			StatusEmoji:      statusEmoji,
			StatusExpiration: statusExpiration,
		},
	)
	if err != nil {
		return err
	}
	values := url.Values{
		"user":    {user},
		"token":   {api.token},
		"profile": {string(profile)},
	}
	response := &userResponseFull{}
	if err = api.postMethod(ctx, "users.profile.set", values, response); err != nil {
		return err
	}
	return response.Err()
}
func (api *Client) UnsetUserCustomStatus() error {
	return api.UnsetUserCustomStatusContext(context.Background())
}