diff --git a/team.go b/team.go index 029e2b5bc..cc1d700cd 100644 --- a/team.go +++ b/team.go @@ -24,6 +24,26 @@ type TeamInfo struct { Icon map[string]interface{} `json:"icon"` } +type TeamProfileResponse struct { + Profile TeamProfile `json:"profile"` + SlackResponse +} + +type TeamProfile struct { + Fields []TeamProfileField `json:"fields"` +} + +type TeamProfileField struct { + ID string `json:"id"` + Ordering int `json:"ordering"` + Label string `json:"label"` + Hint string `json:"hint"` + Type string `json:"type"` + PossibleValues []string `json:"possible_values"` + IsHidden bool `json:"is_hidden"` + Options map[string]bool `json:"options"` +} + type LoginResponse struct { Logins []Login `json:"logins"` Paging `json:"paging"` @@ -95,6 +115,15 @@ func (api *Client) accessLogsRequest(ctx context.Context, path string, values ur return response, response.Err() } +func (api *Client) teamProfileRequest(ctx context.Context, client httpClient, path string, values url.Values) (*TeamProfileResponse, error) { + response := &TeamProfileResponse{} + err := api.postMethod(ctx, path, values, response) + if err != nil { + return nil, err + } + return response, response.Err() +} + // GetTeamInfo gets the Team Information of the user func (api *Client) GetTeamInfo() (*TeamInfo, error) { return api.GetTeamInfoContext(context.Background()) @@ -113,6 +142,25 @@ func (api *Client) GetTeamInfoContext(ctx context.Context) (*TeamInfo, error) { return &response.Team, nil } +// GetTeamProfile gets the Team Profile settings of the user +func (api *Client) GetTeamProfile() (*TeamProfile, error) { + return api.GetTeamProfileContext(context.Background()) +} + +// GetTeamProfileContext gets the Team Profile settings of the user with a custom context +func (api *Client) GetTeamProfileContext(ctx context.Context) (*TeamProfile, error) { + values := url.Values{ + "token": {api.token}, + } + + response, err := api.teamProfileRequest(ctx, api.httpclient, "team.profile.get", values) + if err != nil { + return nil, err + } + return &response.Profile, nil + +} + // GetAccessLogs retrieves a page of logins according to the parameters given func (api *Client) GetAccessLogs(params AccessLogParameters) ([]Login, *Paging, error) { return api.GetAccessLogsContext(context.Background(), params) diff --git a/team_test.go b/team_test.go index ecc3769e2..d0055d177 100644 --- a/team_test.go +++ b/team_test.go @@ -54,6 +54,76 @@ func TestGetTeamInfo(t *testing.T) { } } +func getTeamProfile(rw http.ResponseWriter, r *http.Request) { + rw.Header().Set("Content-Type", "application/json") + response := []byte(`{ + "ok":true, + "profile":{ + "fields":[ + { + "id":"XXXD7KN555", + "ordering":2, + "field_name":"", + "label":"Skype", + "hint":"This will be displayed on your profile.", + "type":"text", + "possible_values":null, + "options":null, + "is_hidden":true + }, + { + "id":"XXXGGE5AAN7", + "ordering":4, + "field_name":"title", + "label":"Title", + "hint":"", + "type":"text", + "possible_values":null, + "options":{ + "is_protected":true, + "is_scim":true + }, + "is_hidden":false + } + ] + } + }`) + + rw.Write(response) +} + +func TestGetTeamProfile(t *testing.T) { + http.HandleFunc("/team.profile.get", getTeamProfile) + + once.Do(startServer) + api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/")) + + teamProfile, err := api.GetTeamProfile() + if err != nil { + t.Errorf("Unexpected error: %s", err) + return + } + + // t.Fatal refers to -> t.Errorf & return + if teamProfile.Fields[0].ID != "XXXD7KN555" { + t.Fatal(ErrIncorrectResponse) + } + if teamProfile.Fields[0].Label != "Skype" { + t.Fatal(ErrIncorrectResponse) + } + + if teamProfile.Fields[1].ID != "XXXGGE5AAN7" { + t.Fatal(ErrIncorrectResponse) + } + if teamProfile.Fields[1].Label != "Title" { + t.Fatal(ErrIncorrectResponse) + } + if !teamProfile.Fields[1].Options["is_protected"] { + t.Fatal(ErrIncorrectResponse) + } + +} + func getTeamAccessLogs(rw http.ResponseWriter, r *http.Request) { rw.Header().Set("Content-Type", "application/json") response := []byte(`{"ok": true, "logins": [{ diff --git a/users.go b/users.go index d22b44f8c..f11ca6831 100644 --- a/users.go +++ b/users.go @@ -556,6 +556,55 @@ func (api *Client) SetUserRealNameContextWithUser(ctx context.Context, user, rea return response.Err() } +// SetUserCustomFields sets Custom Profile fields on the provided users account. Due to the non-repeating elements +// within the request, a map fields is required. The key in the map signifies the field that will be updated. +// +// Note: You may need to change the way the custom field is populated within the Profile section of the Admin Console from +// SCIM or User Entered to API. +// +// See GetTeamProfile for information to retrieve possible fields for your account. +func (api *Client) SetUserCustomFields(userID string, customFields map[string]UserProfileCustomField) error { + return api.SetUserCustomFieldsContext(context.Background(), userID, customFields) +} + +// SetUserCustomFieldsContext will set a users custom profile field with context. +// +// For more information see SetUserCustomFields +func (api *Client) SetUserCustomFieldsContext(ctx context.Context, userID string, customFields map[string]UserProfileCustomField) error { + + // Convert data to data type with custom marshall / unmarshall + // For more information, see UserProfileCustomFields definition. + updateFields := UserProfileCustomFields{} + updateFields.SetMap(customFields) + + // This anonymous struct is needed to set the fields level of the request data. The base struct for + // UserProfileCustomFields has an unexported variable named fields that does not contain a struct tag, + // which has resulted in this configuration. + profile, err := json.Marshal(&struct { + Fields UserProfileCustomFields `json:"fields"` + }{ + Fields: updateFields, + }) + + if err != nil { + return err + } + + values := url.Values{ + "token": {api.token}, + "user": {userID}, + "profile": {string(profile)}, + } + + response := &userResponseFull{} + if err := postForm(ctx, api.httpclient, APIURL+"users.profile.set", values, response, api); err != nil { + return err + } + + return response.Err() + +} + // 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 ""