4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-03 18:57:45 +00:00

Update dependencies (#1951)

This commit is contained in:
Wim
2023-01-28 22:57:53 +01:00
committed by GitHub
parent eac2a8c8dc
commit 880586bac4
325 changed files with 151452 additions and 141118 deletions

View File

@ -38,3 +38,37 @@ func (api *Client) SendAuthRevokeContext(ctx context.Context, token string) (*Au
return api.authRequest(ctx, "auth.revoke", values)
}
type listTeamsResponse struct {
Teams []Team `json:"teams"`
SlackResponse
}
type ListTeamsParameters struct {
Limit int
Cursor string
}
// ListTeams returns all workspaces a token can access.
// More info: https://api.slack.com/methods/admin.teams.list
func (api *Client) ListTeams(params ListTeamsParameters) ([]Team, string, error) {
return api.ListTeamsContext(context.Background(), params)
}
// ListTeams returns all workspaces a token can access with a custom context.
func (api *Client) ListTeamsContext(ctx context.Context, params ListTeamsParameters) ([]Team, string, error) {
values := url.Values{
"token": {api.token},
}
if params.Cursor != "" {
values.Add("cursor", params.Cursor)
}
response := &listTeamsResponse{}
err := api.postMethod(ctx, "auth.teams.list", values, response)
if err != nil {
return nil, "", err
}
return response.Teams, response.ResponseMetadata.Cursor, response.Err()
}

View File

@ -112,6 +112,10 @@ func (b *InputBlock) UnmarshalJSON(data []byte) error {
e = &TimePickerBlockElement{}
case "plain_text_input":
e = &PlainTextInputBlockElement{}
case "email_text_input":
e = &EmailTextInputBlockElement{}
case "url_text_input":
e = &URLTextInputBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
e = &SelectBlockElement{}
case "multi_static_select", "multi_external_select", "multi_users_select", "multi_conversations_select", "multi_channels_select":
@ -122,6 +126,8 @@ func (b *InputBlock) UnmarshalJSON(data []byte) error {
e = &OverflowBlockElement{}
case "radio_buttons":
e = &RadioButtonsBlockElement{}
case "number_input":
e = &NumberInputBlockElement{}
default:
return errors.New("unsupported block element type")
}
@ -186,12 +192,18 @@ func (b *BlockElements) UnmarshalJSON(data []byte) error {
blockElement = &TimePickerBlockElement{}
case "plain_text_input":
blockElement = &PlainTextInputBlockElement{}
case "email_text_input":
blockElement = &EmailTextInputBlockElement{}
case "url_text_input":
blockElement = &URLTextInputBlockElement{}
case "checkboxes":
blockElement = &CheckboxGroupsBlockElement{}
case "radio_buttons":
blockElement = &RadioButtonsBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
blockElement = &SelectBlockElement{}
case "number_input":
blockElement = &NumberInputBlockElement{}
default:
return fmt.Errorf("unsupported block element type %v", blockElementType)
}

View File

@ -11,6 +11,9 @@ const (
METTimepicker MessageElementType = "timepicker"
METPlainTextInput MessageElementType = "plain_text_input"
METRadioButtons MessageElementType = "radio_buttons"
METEmailTextInput MessageElementType = "email_text_input"
METURLTextInput MessageElementType = "url_text_input"
METNumber MessageElementType = "number_input"
MixedElementImage MixedElementType = "mixed_image"
MixedElementText MixedElementType = "mixed_text"
@ -389,6 +392,64 @@ func NewTimePickerBlockElement(actionID string) *TimePickerBlockElement {
}
}
// EmailTextInputBlockElement creates a field where a user can enter email
// data.
// email-text-input elements are currently only available in modals.
//
// More Information: https://api.slack.com/reference/block-kit/block-elements#email
type EmailTextInputBlockElement struct {
Type MessageElementType `json:"type"`
ActionID string `json:"action_id,omitempty"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
InitialValue string `json:"initial_value,omitempty"`
DispatchActionConfig *DispatchActionConfig `json:"dispatch_action_config,omitempty"`
FocusOnLoad bool `json:"focus_on_load,omitempty"`
}
// ElementType returns the type of the Element
func (s EmailTextInputBlockElement) ElementType() MessageElementType {
return s.Type
}
// NewEmailTextInputBlockElement returns an instance of a plain-text input
// element
func NewEmailTextInputBlockElement(placeholder *TextBlockObject, actionID string) *EmailTextInputBlockElement {
return &EmailTextInputBlockElement{
Type: METEmailTextInput,
ActionID: actionID,
Placeholder: placeholder,
}
}
// URLTextInputBlockElement creates a field where a user can enter url data.
//
// url-text-input elements are currently only available in modals.
//
// More Information: https://api.slack.com/reference/block-kit/block-elements#url
type URLTextInputBlockElement struct {
Type MessageElementType `json:"type"`
ActionID string `json:"action_id,omitempty"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
InitialValue string `json:"initial_value,omitempty"`
DispatchActionConfig *DispatchActionConfig `json:"dispatch_action_config,omitempty"`
FocusOnLoad bool `json:"focus_on_load,omitempty"`
}
// ElementType returns the type of the Element
func (s URLTextInputBlockElement) ElementType() MessageElementType {
return s.Type
}
// NewURLTextInputBlockElement returns an instance of a plain-text input
// element
func NewURLTextInputBlockElement(placeholder *TextBlockObject, actionID string) *URLTextInputBlockElement {
return &URLTextInputBlockElement{
Type: METURLTextInput,
ActionID: actionID,
Placeholder: placeholder,
}
}
// PlainTextInputBlockElement creates a field where a user can enter freeform
// data.
// Plain-text input elements are currently only available in modals.
@ -475,3 +536,34 @@ func NewRadioButtonsBlockElement(actionID string, options ...*OptionBlockObject)
Options: options,
}
}
// NumberInputBlockElement creates a field where a user can enter number
// data.
// Number input elements are currently only available in modals.
//
// More Information: https://api.slack.com/reference/block-kit/block-elements#number
type NumberInputBlockElement struct {
Type MessageElementType `json:"type"`
IsDecimalAllowed bool `json:"is_decimal_allowed"`
ActionID string `json:"action_id,omitempty"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
InitialValue string `json:"initial_value,omitempty"`
MinValue string `json:"min_value,omitempty"`
MaxValue string `json:"max_value,omitempty"`
DispatchActionConfig *DispatchActionConfig `json:"dispatch_action_config,omitempty"`
}
// ElementType returns the type of the Element
func (s NumberInputBlockElement) ElementType() MessageElementType {
return s.Type
}
// NewNumberInputBlockElement returns an instance of a number input element
func NewNumberInputBlockElement(placeholder *TextBlockObject, actionID string, isDecimalAllowed bool) *NumberInputBlockElement {
return &NumberInputBlockElement{
Type: METNumber,
ActionID: actionID,
Placeholder: placeholder,
IsDecimalAllowed: isDecimalAllowed,
}
}

View File

@ -327,17 +327,17 @@ func NewRichTextSectionUserGroupElement(usergroupID string) *RichTextSectionUser
type RichTextSectionDateElement struct {
Type RichTextSectionElementType `json:"type"`
Timestamp string `json:"timestamp"`
Timestamp JSONTime `json:"timestamp"`
}
func (r RichTextSectionDateElement) RichTextSectionElementType() RichTextSectionElementType {
return r.Type
}
func NewRichTextSectionDateElement(timestamp string) *RichTextSectionDateElement {
func NewRichTextSectionDateElement(timestamp int64) *RichTextSectionDateElement {
return &RichTextSectionDateElement{
Type: RTSEDate,
Timestamp: timestamp,
Timestamp: JSONTime(timestamp),
}
}

View File

@ -2,6 +2,7 @@ package slack
import (
"context"
"errors"
"net/url"
"strconv"
"strings"
@ -71,6 +72,7 @@ type GetConversationsForUserParameters struct {
Types []string
Limit int
ExcludeArchived bool
TeamID string
}
type responseMetaData struct {
@ -137,6 +139,10 @@ func (api *Client) GetConversationsForUserContext(ctx context.Context, params *G
if params.ExcludeArchived {
values.Add("exclude_archived", "true")
}
if params.TeamID != "" {
values.Add("team_id", params.TeamID)
}
response := struct {
Channels []Channel `json:"channels"`
ResponseMetaData responseMetaData `json:"response_metadata"`
@ -337,17 +343,26 @@ func (api *Client) CloseConversationContext(ctx context.Context, channelID strin
return response.NoOp, response.AlreadyClosed, response.Err()
}
type CreateConversationParams struct {
ChannelName string
IsPrivate bool
TeamID string
}
// CreateConversation initiates a public or private channel-based conversation
func (api *Client) CreateConversation(channelName string, isPrivate bool) (*Channel, error) {
return api.CreateConversationContext(context.Background(), channelName, isPrivate)
func (api *Client) CreateConversation(params CreateConversationParams) (*Channel, error) {
return api.CreateConversationContext(context.Background(), params)
}
// CreateConversationContext initiates a public or private channel-based conversation with a custom context
func (api *Client) CreateConversationContext(ctx context.Context, channelName string, isPrivate bool) (*Channel, error) {
func (api *Client) CreateConversationContext(ctx context.Context, params CreateConversationParams) (*Channel, error) {
values := url.Values{
"token": {api.token},
"name": {channelName},
"is_private": {strconv.FormatBool(isPrivate)},
"name": {params.ChannelName},
"is_private": {strconv.FormatBool(params.IsPrivate)},
}
if params.TeamID != "" {
values.Set("team_id", params.TeamID)
}
response, err := api.channelRequest(ctx, "conversations.create", values)
if err != nil {
@ -357,17 +372,33 @@ func (api *Client) CreateConversationContext(ctx context.Context, channelName st
return &response.Channel, nil
}
// GetConversationInfoInput Defines the parameters of a GetConversationInfo and GetConversationInfoContext function
type GetConversationInfoInput struct {
ChannelID string
IncludeLocale bool
IncludeNumMembers bool
}
// GetConversationInfo retrieves information about a conversation
func (api *Client) GetConversationInfo(channelID string, includeLocale bool) (*Channel, error) {
return api.GetConversationInfoContext(context.Background(), channelID, includeLocale)
func (api *Client) GetConversationInfo(input *GetConversationInfoInput) (*Channel, error) {
return api.GetConversationInfoContext(context.Background(), input)
}
// GetConversationInfoContext retrieves information about a conversation with a custom context
func (api *Client) GetConversationInfoContext(ctx context.Context, channelID string, includeLocale bool) (*Channel, error) {
func (api *Client) GetConversationInfoContext(ctx context.Context, input *GetConversationInfoInput) (*Channel, error) {
if input == nil {
return nil, errors.New("GetConversationInfoInput must not be nil")
}
if input.ChannelID == "" {
return nil, errors.New("ChannelID must be defined")
}
values := url.Values{
"token": {api.token},
"channel": {channelID},
"include_locale": {strconv.FormatBool(includeLocale)},
"token": {api.token},
"channel": {input.ChannelID},
"include_locale": {strconv.FormatBool(input.IncludeLocale)},
"include_num_members": {strconv.FormatBool(input.IncludeNumMembers)},
}
response, err := api.channelRequest(ctx, "conversations.info", values)
if err != nil {
@ -398,13 +429,14 @@ func (api *Client) LeaveConversationContext(ctx context.Context, channelID strin
}
type GetConversationRepliesParameters struct {
ChannelID string
Timestamp string
Cursor string
Inclusive bool
Latest string
Limit int
Oldest string
ChannelID string
Timestamp string
Cursor string
Inclusive bool
Latest string
Limit int
Oldest string
IncludeAllMetadata bool
}
// GetConversationReplies retrieves a thread of messages posted to a conversation
@ -436,6 +468,11 @@ func (api *Client) GetConversationRepliesContext(ctx context.Context, params *Ge
} else {
values.Add("inclusive", "0")
}
if params.IncludeAllMetadata {
values.Add("include_all_metadata", "1")
} else {
values.Add("include_all_metadata", "0")
}
response := struct {
SlackResponse
HasMore bool `json:"has_more"`

View File

@ -2,6 +2,7 @@ package slack
import (
"context"
"encoding/json"
"fmt"
"io"
"net/url"
@ -145,6 +146,58 @@ type ListFilesParameters struct {
Cursor string
}
type UploadFileV2Parameters struct {
File string
FileSize int
Content string
Reader io.Reader
Filename string
Title string
InitialComment string
Channel string
ThreadTimestamp string
AltTxt string
SnippetText string
}
type getUploadURLExternalParameters struct {
altText string
fileSize int
fileName string
snippetText string
}
type getUploadURLExternalResponse struct {
UploadURL string `json:"upload_url"`
FileID string `json:"file_id"`
SlackResponse
}
type uploadToURLParameters struct {
UploadURL string
Reader io.Reader
File string
Content string
Filename string
}
type FileSummary struct {
ID string `json:"id"`
Title string `json:"title"`
}
type completeUploadExternalParameters struct {
title string
channel string
initialComment string
threadTimestamp string
}
type completeUploadExternalResponse struct {
SlackResponse
Files []FileSummary `json:"files"`
}
type fileResponseFull struct {
File `json:"file"`
Paging `json:"paging"`
@ -416,3 +469,129 @@ func (api *Client) ShareFilePublicURLContext(ctx context.Context, fileID string)
}
return &response.File, response.Comments, &response.Paging, nil
}
// getUploadURLExternal gets a URL and fileID from slack which can later be used to upload a file
func (api *Client) getUploadURLExternal(ctx context.Context, params getUploadURLExternalParameters) (*getUploadURLExternalResponse, error) {
values := url.Values{
"token": {api.token},
"filename": {params.fileName},
"length": {strconv.Itoa(params.fileSize)},
}
if params.altText != "" {
values.Add("initial_comment", params.altText)
}
if params.snippetText != "" {
values.Add("thread_ts", params.snippetText)
}
response := &getUploadURLExternalResponse{}
err := api.postMethod(ctx, "files.getUploadURLExternal", values, response)
if err != nil {
return nil, err
}
return response, response.Err()
}
// uploadToURL uploads the file to the provided URL using post method
func (api *Client) uploadToURL(ctx context.Context, params uploadToURLParameters) (err error) {
values := url.Values{}
if params.Content != "" {
values.Add("content", params.Content)
values.Add("token", api.token)
err = postForm(ctx, api.httpclient, params.UploadURL, values, nil, api)
} else if params.File != "" {
err = postLocalWithMultipartResponse(ctx, api.httpclient, params.UploadURL, params.File, "file", api.token, values, nil, api)
} else if params.Reader != nil {
err = postWithMultipartResponse(ctx, api.httpclient, params.UploadURL, params.Filename, "file", api.token, values, params.Reader, nil, api)
}
return err
}
// completeUploadExternal once files are uploaded, this completes the upload and shares it to the specified channel
func (api *Client) completeUploadExternal(ctx context.Context, fileID string, params completeUploadExternalParameters) (file *completeUploadExternalResponse, err error) {
request := []FileSummary{{ID: fileID, Title: params.title}}
requestBytes, err := json.Marshal(request)
if err != nil {
return nil, err
}
values := url.Values{
"token": {api.token},
"files": {string(requestBytes)},
"channel_id": {params.channel},
}
if params.initialComment != "" {
values.Add("initial_comment", params.initialComment)
}
if params.threadTimestamp != "" {
values.Add("thread_ts", params.threadTimestamp)
}
response := &completeUploadExternalResponse{}
err = api.postMethod(ctx, "files.completeUploadExternal", values, response)
if err != nil {
return nil, err
}
if response.Err() != nil {
return nil, response.Err()
}
return response, nil
}
// UploadFileV2 uploads file to a given slack channel using 3 steps -
// 1. Get an upload URL using files.getUploadURLExternal API
// 2. Send the file as a post to the URL provided by slack
// 3. Complete the upload and share it to the specified channel using files.completeUploadExternal
func (api *Client) UploadFileV2(params UploadFileV2Parameters) (*FileSummary, error) {
return api.UploadFileV2Context(context.Background(), params)
}
// UploadFileV2 uploads file to a given slack channel using 3 steps with a custom context -
// 1. Get an upload URL using files.getUploadURLExternal API
// 2. Send the file as a post to the URL provided by slack
// 3. Complete the upload and share it to the specified channel using files.completeUploadExternal
func (api *Client) UploadFileV2Context(ctx context.Context, params UploadFileV2Parameters) (file *FileSummary, err error) {
if params.Filename == "" {
return nil, fmt.Errorf("file.upload.v2: filename cannot be empty")
}
if params.FileSize == 0 {
return nil, fmt.Errorf("file.upload.v2: file size cannot be 0")
}
if params.Channel == "" {
return nil, fmt.Errorf("file.upload.v2: channel cannot be empty")
}
u, err := api.getUploadURLExternal(ctx, getUploadURLExternalParameters{
altText: params.AltTxt,
fileName: params.Filename,
fileSize: params.FileSize,
snippetText: params.SnippetText,
})
if err != nil {
return nil, err
}
err = api.uploadToURL(ctx, uploadToURLParameters{
UploadURL: u.UploadURL,
Reader: params.Reader,
File: params.File,
Content: params.Content,
Filename: params.Filename,
})
if err != nil {
return nil, err
}
c, err := api.completeUploadExternal(ctx, u.FileID, completeUploadExternalParameters{
title: params.Title,
channel: params.Channel,
initialComment: params.InitialComment,
threadTimestamp: params.ThreadTimestamp,
})
if err != nil {
return nil, err
}
if len(c.Files) != 1 {
return nil, fmt.Errorf("file.upload.v2: something went wrong; received %d files instead of 1", len(c.Files))
}
return &c.Files[0], nil
}

View File

@ -307,6 +307,9 @@ type responseParser func(*http.Response) error
func newJSONParser(dst interface{}) responseParser {
return func(resp *http.Response) error {
if dst == nil {
return nil
}
return json.NewDecoder(resp.Body).Decode(dst)
}
}

View File

@ -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,11 +115,41 @@ 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())
}
// GetOtherTeamInfoContext gets Team information for any team with a custom context
func (api *Client) GetOtherTeamInfoContext(ctx context.Context, team string) (*TeamInfo, error) {
if team == "" {
return api.GetTeamInfoContext(ctx)
}
values := url.Values{
"token": {api.token},
}
values.Add("team", team)
response, err := api.teamRequest(ctx, "team.info", values)
if err != nil {
return nil, err
}
return &response.Team, nil
}
// GetOtherTeamInfo gets Team information for any team
func (api *Client) GetOtherTeamInfo(team string) (*TeamInfo, error) {
return api.GetOtherTeamInfoContext(context.Background(), team)
}
// GetTeamInfoContext gets the Team Information of the user with a custom context
func (api *Client) GetTeamInfoContext(ctx context.Context) (*TeamInfo, error) {
values := url.Values{
@ -113,6 +163,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)

View File

@ -17,30 +17,38 @@ const (
// UserProfile contains all the information details of a given user
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"`
Image512 string `json:"image_512"`
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"`
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"`
Image512 string `json:"image_512"`
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"`
StatusEmojiDisplayInfo []UserProfileStatusEmojiDisplayInfo `json:"status_emoji_display_info,omitempty"`
StatusExpiration int `json:"status_expiration"`
Team string `json:"team"`
Fields UserProfileCustomFields `json:"fields"`
}
type UserProfileStatusEmojiDisplayInfo struct {
EmojiName string `json:"emoji_name"`
DisplayAlias string `json:"display_alias,omitempty"`
DisplayURL string `json:"display_url,omitempty"`
Unicode string `json:"unicode,omitempty"`
}
// UserProfileCustomFields represents user profile's custom fields.
@ -556,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 ""

View File

@ -21,8 +21,8 @@ type WebhookMessage struct {
Parse string `json:"parse,omitempty"`
Blocks *Blocks `json:"blocks,omitempty"`
ResponseType string `json:"response_type,omitempty"`
ReplaceOriginal bool `json:"replace_original,omitempty"`
DeleteOriginal bool `json:"delete_original,omitempty"`
ReplaceOriginal bool `json:"replace_original"`
DeleteOriginal bool `json:"delete_original"`
ReplyBroadcast bool `json:"reply_broadcast,omitempty"`
}

View File

@ -1,7 +1,7 @@
package slack
// reactionItem is a lighter-weight item than is returned by the reactions list.
type reactionItem struct {
// ReactionItem is a lighter-weight item than is returned by the reactions list.
type ReactionItem struct {
Type string `json:"type"`
Channel string `json:"channel,omitempty"`
File string `json:"file,omitempty"`
@ -9,17 +9,17 @@ type reactionItem struct {
Timestamp string `json:"ts,omitempty"`
}
type reactionEvent struct {
type ReactionEvent struct {
Type string `json:"type"`
User string `json:"user"`
ItemUser string `json:"item_user"`
Item reactionItem `json:"item"`
Item ReactionItem `json:"item"`
Reaction string `json:"reaction"`
EventTimestamp string `json:"event_ts"`
}
// ReactionAddedEvent represents the Reaction added event
type ReactionAddedEvent reactionEvent
type ReactionAddedEvent ReactionEvent
// ReactionRemovedEvent represents the Reaction removed event
type ReactionRemovedEvent reactionEvent
type ReactionRemovedEvent ReactionEvent

View File

@ -19,10 +19,10 @@ type (
}
)
type WorkflowStepCompletedRequestOption func(opt WorkflowStepCompletedRequest) error
type WorkflowStepCompletedRequestOption func(opt *WorkflowStepCompletedRequest) error
func WorkflowStepCompletedRequestOptionOutput(outputs map[string]string) WorkflowStepCompletedRequestOption {
return func(opt WorkflowStepCompletedRequest) error {
return func(opt *WorkflowStepCompletedRequest) error {
if len(outputs) > 0 {
opt.Outputs = outputs
}
@ -33,7 +33,7 @@ func WorkflowStepCompletedRequestOptionOutput(outputs map[string]string) Workflo
// WorkflowStepCompleted indicates step is completed
func (api *Client) WorkflowStepCompleted(workflowStepExecuteID string, options ...WorkflowStepCompletedRequestOption) error {
// More information: https://api.slack.com/methods/workflows.stepCompleted
r := WorkflowStepCompletedRequest{
r := &WorkflowStepCompletedRequest{
WorkflowStepExecuteID: workflowStepExecuteID,
}
for _, option := range options {