Skip to content

Commit

Permalink
Merge pull request #1097 from MattDavisRV/CustomProfileField_Update
Browse files Browse the repository at this point in the history
Support team.profile.get method
  • Loading branch information
kanata2 committed Dec 12, 2022
2 parents 5a47d3e + d0f246b commit f50586f
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
48 changes: 48 additions & 0 deletions team.go
Expand Up @@ -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"`
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -129,6 +158,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)
Expand Down
70 changes: 70 additions & 0 deletions team_test.go
Expand Up @@ -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": [{
Expand Down
49 changes: 49 additions & 0 deletions users.go
Expand Up @@ -564,6 +564,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 ""
Expand Down

0 comments on commit f50586f

Please sign in to comment.