Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions conversation.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,47 @@ func (api *Client) GetConversationInfoContext(ctx context.Context, input *GetCon
return &response.Channel, response.Err()
}

// ConversationRetention represents a conversation's message retention policy.
// Type uses 1 = never delete, 2 = delete after Duration days (Slack's preset
// "keep for N days" options), 3 = custom timeline (also delete after Duration),
// 0 = inherit the workspace default. Duration is in days.
type ConversationRetention struct {
Type int `json:"retention_type"`
Duration int `json:"retention_duration"`
}

type getConversationRetentionResponse struct {
SlackResponse
Retention ConversationRetention `json:"retention"`
}

// GetConversationRetention retrieves a conversation's message retention policy.
// For more details, see GetConversationRetentionContext documentation.
func (api *Client) GetConversationRetention(channelID string) (*ConversationRetention, error) {
return api.GetConversationRetentionContext(context.Background(), channelID)
}

// GetConversationRetentionContext retrieves a conversation's message retention
// policy with a custom context. This uses the undocumented conversations.getRetention
// method that the Slack web client calls; unlike admin.conversations.getCustomRetention
// it works with a regular user token. It returns the "not_paid" error on workspaces
// without the custom-retention feature.
func (api *Client) GetConversationRetentionContext(ctx context.Context, channelID string) (*ConversationRetention, error) {
values := url.Values{
"token": {api.token},
"channel": {channelID},
}
response := &getConversationRetentionResponse{}
err := api.postMethod(ctx, "conversations.getRetention", values, response)
if err != nil {
return nil, err
}
if err := response.Err(); err != nil {
return nil, err
}
return &response.Retention, nil
}

// LeaveConversation leaves a conversation.
// For more details, see LeaveConversationContext documentation.
func (api *Client) LeaveConversation(channelID string) (bool, error) {
Expand Down
11 changes: 11 additions & 0 deletions users.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ type ClientUserBootSubteams struct {
type TeamPrefs struct {
MsgEditWindowMins *int `json:"msg_edit_window_mins,omitempty"`
AllowMessageDeletion *bool `json:"allow_message_deletion,omitempty"`

// Message retention defaults. The *_type fields use 1 = retain all messages,
// 2 = delete after the matching *_duration (in days); other values mean no
// automatic deletion. Public channels use RetentionType/RetentionDuration,
// private channels use the Group* fields and DMs/MPIMs use the DM* fields.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc inconsistency with ConversationRetention.Type: the comment over in conversation.go enumerates 0/1/2/3 with concrete meanings (0=inherit workspace default, 3=custom timeline), but here "other values" is left vague. Since both fields are decoding the same Slack retention enum it would be clearer to use the same enumeration here so callers know about the 3 and 0 cases.

RetentionType int `json:"retention_type,omitempty"`
RetentionDuration int `json:"retention_duration,omitempty"`
GroupRetentionType int `json:"group_retention_type,omitempty"`
GroupRetentionDuration int `json:"group_retention_duration,omitempty"`
DMRetentionType int `json:"dm_retention_type,omitempty"`
DMRetentionDuration int `json:"dm_retention_duration,omitempty"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type inconsistency with surrounding TeamPrefs fields: the existing prefs in this struct use pointer types (*int, *bool) so callers can distinguish an absent field from a zero value. The new retention fields use plain int with omitempty, which means a JSON payload that omits e.g. retention_type is indistinguishable from one that sends 0. Per your own doc comment, value 0 is meaningful (other values mean no automatic deletion), so an unset field and an explicit unset look the same to callers. Consider matching the existing style with *int for symmetry and to preserve the absent-vs-zero signal.

}

type BootTeam struct {
Expand Down
Loading