Files
Dmitry VerkhoturovandUmputun 80c12a3f10 chore(deps): update Go modules
Bump Go dependencies in both backend/ and backend/_example/memory_store.

Notable updates:
- github.com/go-pkgz/lgr v0.12.1 -> v0.12.3
- github.com/klauspost/compress v1.18.2 -> v1.18.5
- github.com/PuerkitoBio/goquery v1.11.0 -> v1.12.0
- github.com/montanaflynn/stats v0.7.1 -> v0.9.0
- github.com/redis/go-redis/v9 v9.17.2 -> v9.18.0
- github.com/slack-go/slack v0.17.3 -> v0.21.1
- go.mongodb.org/mongo-driver v1.17.6 -> v1.17.9
- golang.org/x/crypto v0.48.0 -> v0.50.0
- golang.org/x/net v0.49.0 -> v0.53.0
- golang.org/x/image v0.36.0 -> v0.39.0
- golang.org/x/sys v0.41.0 -> v0.43.0
- golang.org/x/{oauth2,sync,text} minor bumps

Key markdown/sanitisation libs (bluemonday v1.0.27,
alecthomas/chroma/v2 v2.23.1, russross/blackfriday/v2 v2.1.0,
Depado/bfchroma/v2 v2.0.0) are already at the latest available
versions and were not bumped.

Verified the Chroma span-class allowlist regex in
backend/app/store/comment.go:128-131 is still fully in sync with
chroma/v2 types.go StandardTypes map (86 classes, byte-equal after
sorting). The inline comment references commit c263f6f which is
stale (Chroma is at v2 now), but the class list content is current.

Ran `go mod tidy` + `go mod vendor` + full race test suite on both
modules. All green. Added a reminder in CLAUDE.md that updating
backend/ Go modules also requires `go mod tidy` in
backend/_example/memory_store since the example module uses a
local replace directive and inherits indirect deps from the main
module.
2026-04-12 11:52:57 -05:00

808 lines
28 KiB
Go

package slack
import (
"context"
"encoding/json"
"net/url"
"strconv"
"strings"
)
// AdminConversationsInviteParams contains arguments for AdminConversationsInvite method call.
type AdminConversationsInviteParams struct {
ChannelID string
UserIDs []string
}
// AdminConversationsInvite invites users to a channel.
// For more information see the admin.conversations.invite docs:
// https://api.slack.com/methods/admin.conversations.invite
func (api *Client) AdminConversationsInvite(ctx context.Context, params AdminConversationsInviteParams) error {
values := url.Values{
"token": {api.token},
"channel_id": {params.ChannelID},
"user_ids": {strings.Join(params.UserIDs, ",")},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.invite", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsArchive archives a public or private channel.
// For more information see the admin.conversations.archive docs:
// https://api.slack.com/methods/admin.conversations.archive
func (api *Client) AdminConversationsArchive(ctx context.Context, channelID string) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.archive", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsUnarchive unarchives a public or private channel.
// For more information see the admin.conversations.unarchive docs:
// https://api.slack.com/methods/admin.conversations.unarchive
func (api *Client) AdminConversationsUnarchive(ctx context.Context, channelID string) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.unarchive", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsRename renames a public or private channel.
// For more information see the admin.conversations.rename docs:
// https://api.slack.com/methods/admin.conversations.rename
func (api *Client) AdminConversationsRename(ctx context.Context, channelID, name string) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
"name": {name},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.rename", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsDelete deletes a public or private channel.
// For more information see the admin.conversations.delete docs:
// https://api.slack.com/methods/admin.conversations.delete
func (api *Client) AdminConversationsDelete(ctx context.Context, channelID string) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.delete", values, response)
if err != nil {
return err
}
return response.Err()
}
type adminConversationsDisconnectSharedParams struct {
leavingTeamIDs []string
}
// AdminConversationsDisconnectSharedOption is an option for AdminConversationsDisconnectShared.
type AdminConversationsDisconnectSharedOption func(*adminConversationsDisconnectSharedParams)
// AdminConversationsDisconnectSharedOptionLeavingTeamIDs sets the team IDs of the workspaces to disconnect.
func AdminConversationsDisconnectSharedOptionLeavingTeamIDs(teamIDs []string) AdminConversationsDisconnectSharedOption {
return func(params *adminConversationsDisconnectSharedParams) {
params.leavingTeamIDs = teamIDs
}
}
// AdminConversationsDisconnectShared disconnects a connected channel from one or more workspaces.
// For more information see the admin.conversations.disconnectShared docs:
// https://api.slack.com/methods/admin.conversations.disconnectShared
func (api *Client) AdminConversationsDisconnectShared(ctx context.Context, channelID string, options ...AdminConversationsDisconnectSharedOption) error {
params := adminConversationsDisconnectSharedParams{}
for _, opt := range options {
opt(&params)
}
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
if len(params.leavingTeamIDs) > 0 {
values.Add("leaving_team_ids", strings.Join(params.leavingTeamIDs, ","))
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.disconnectShared", values, response)
if err != nil {
return err
}
return response.Err()
}
type adminConversationsCreateParams struct {
description string
orgWide bool
teamID string
}
// AdminConversationsCreateOption is an option for AdminConversationsCreate.
type AdminConversationsCreateOption func(*adminConversationsCreateParams)
// AdminConversationsCreateOptionDescription sets the description of the channel.
func AdminConversationsCreateOptionDescription(description string) AdminConversationsCreateOption {
return func(params *adminConversationsCreateParams) {
params.description = description
}
}
// AdminConversationsCreateOptionOrgWide sets whether the channel should be org-wide.
func AdminConversationsCreateOptionOrgWide(orgWide bool) AdminConversationsCreateOption {
return func(params *adminConversationsCreateParams) {
params.orgWide = orgWide
}
}
// AdminConversationsCreateOptionTeamID sets the team ID where the channel should be created.
func AdminConversationsCreateOptionTeamID(teamID string) AdminConversationsCreateOption {
return func(params *adminConversationsCreateParams) {
params.teamID = teamID
}
}
// AdminConversationsCreateResponse represents the response from admin.conversations.create.
type AdminConversationsCreateResponse struct {
SlackResponse
ChannelID string `json:"channel_id"`
}
// AdminConversationsCreate creates a public or private channel-based conversation.
// For more information see the admin.conversations.create docs:
// https://api.slack.com/methods/admin.conversations.create
func (api *Client) AdminConversationsCreate(ctx context.Context, name string, isPrivate bool, options ...AdminConversationsCreateOption) (string, error) {
params := adminConversationsCreateParams{}
for _, opt := range options {
opt(&params)
}
values := url.Values{
"token": {api.token},
"is_private": {strconv.FormatBool(isPrivate)},
"name": {name},
}
if params.description != "" {
values.Add("description", params.description)
}
if params.orgWide {
values.Add("org_wide", "true")
}
if params.teamID != "" {
values.Add("team_id", params.teamID)
}
response := &AdminConversationsCreateResponse{}
err := api.postMethod(ctx, "admin.conversations.create", values, response)
if err != nil {
return "", err
}
return response.ChannelID, response.Err()
}
// AdminConversationsGetTeamsParams contains arguments for AdminConversationsGetTeams method call.
type AdminConversationsGetTeamsParams struct {
ChannelID string
Cursor string
Limit int
}
// AdminConversationsGetTeamsResponse represents the response from admin.conversations.getTeams.
type AdminConversationsGetTeamsResponse struct {
SlackResponse
TeamIDs []string `json:"team_ids"`
}
// AdminConversationsGetTeams gets all the workspaces a given public or private channel is connected to within this Enterprise org.
// For more information see the admin.conversations.getTeams docs:
// https://api.slack.com/methods/admin.conversations.getTeams
func (api *Client) AdminConversationsGetTeams(ctx context.Context, params AdminConversationsGetTeamsParams) ([]string, string, error) {
values := url.Values{
"token": {api.token},
"channel_id": {params.ChannelID},
}
if params.Cursor != "" {
values.Add("cursor", params.Cursor)
}
if params.Limit > 0 {
values.Add("limit", strconv.Itoa(params.Limit))
}
response := &AdminConversationsGetTeamsResponse{}
err := api.postMethod(ctx, "admin.conversations.getTeams", values, response)
if err != nil {
return nil, "", err
}
return response.TeamIDs, response.ResponseMetadata.Cursor, response.Err()
}
type adminConversationsSearchParams struct {
cursor string
limit int
query string
searchChannelType []string
sort string
sortDir string
teamIDs []string
connectedTeamIDs []string
totalCountOnly bool
}
// AdminConversationsSearchOption is an option for AdminConversationsSearch.
type AdminConversationsSearchOption func(*adminConversationsSearchParams)
// AdminConversationsSearchOptionCursor sets the cursor for pagination.
func AdminConversationsSearchOptionCursor(cursor string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.cursor = cursor
}
}
// AdminConversationsSearchOptionLimit sets the maximum number of results to return.
func AdminConversationsSearchOptionLimit(limit int) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.limit = limit
}
}
// AdminConversationsSearchOptionQuery sets the search query.
func AdminConversationsSearchOptionQuery(query string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.query = query
}
}
// AdminConversationsSearchOptionSearchChannelTypes sets the channel types to search.
// Valid values: "private", "public", "private_exclude", "multi_workspace", "org_wide", "external_shared_exclude", "external_shared"
func AdminConversationsSearchOptionSearchChannelTypes(types []string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.searchChannelType = types
}
}
// AdminConversationsSearchOptionSort sets the sort field.
// Valid values: "name", "member_count", "created"
func AdminConversationsSearchOptionSort(sort string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.sort = sort
}
}
// AdminConversationsSearchOptionSortDir sets the sort direction.
// Valid values: "asc", "desc"
func AdminConversationsSearchOptionSortDir(sortDir string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.sortDir = sortDir
}
}
// AdminConversationsSearchOptionTeamIDs filters results to channels in the specified teams.
func AdminConversationsSearchOptionTeamIDs(teamIDs []string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.teamIDs = teamIDs
}
}
// AdminConversationsSearchOptionConnectedTeamIDs filters results to channels connected to the specified teams.
func AdminConversationsSearchOptionConnectedTeamIDs(teamIDs []string) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.connectedTeamIDs = teamIDs
}
}
// AdminConversationsSearchOptionTotalCountOnly when true, only returns the total count of matching channels.
func AdminConversationsSearchOptionTotalCountOnly(totalCountOnly bool) AdminConversationsSearchOption {
return func(params *adminConversationsSearchParams) {
params.totalCountOnly = totalCountOnly
}
}
// ChannelEmailAddress represents an email address associated with a channel.
type ChannelEmailAddress struct {
Address string `json:"address"`
CreatorID string `json:"creator_id"`
TeamID string `json:"team_id"`
}
// AdminConversationOwnershipDetail represents ownership details for lists/canvas.
type AdminConversationOwnershipDetail struct {
Count int `json:"count,omitempty"`
TeamID string `json:"team_id,omitempty"`
}
// AdminConversationLists represents lists/canvas information in admin conversations.
type AdminConversationLists struct {
OwnershipDetails []AdminConversationOwnershipDetail `json:"ownership_details,omitempty"`
TotalCount int `json:"total_count,omitempty"`
}
// AdminConversation represents a conversation in admin API responses.
type AdminConversation struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Purpose string `json:"purpose,omitempty"`
MemberCount int `json:"member_count,omitempty"`
Created int64 `json:"created,omitempty"`
CreatorID string `json:"creator_id,omitempty"`
IsPrivate bool `json:"is_private,omitempty"`
IsArchived bool `json:"is_archived,omitempty"`
IsGeneral bool `json:"is_general,omitempty"`
LastActivityTimestamp int64 `json:"last_activity_ts,omitempty"`
IsFrozen bool `json:"is_frozen,omitempty"`
IsOrgDefault bool `json:"is_org_default,omitempty"`
IsOrgMandatory bool `json:"is_org_mandatory,omitempty"`
IsOrgShared bool `json:"is_org_shared,omitempty"`
IsExtShared bool `json:"is_ext_shared,omitempty"`
IsGlobalShared bool `json:"is_global_shared,omitempty"`
IsPendingExtShared bool `json:"is_pending_ext_shared,omitempty"`
IsDisconnectInProgress bool `json:"is_disconnect_in_progress,omitempty"`
ConnectedTeamIDs []string `json:"connected_team_ids,omitempty"`
ConnectedLimitedTeamIDs []string `json:"connected_limited_team_ids,omitempty"`
PendingConnectedTeamIDs []string `json:"pending_connected_team_ids,omitempty"`
InternalTeamIDs []string `json:"internal_team_ids,omitempty"`
InternalTeamIDsCount int `json:"internal_team_ids_count,omitempty"`
InternalTeamIDsSampleTeam string `json:"internal_team_ids_sample_team,omitempty"`
ContextTeamID string `json:"context_team_id,omitempty"`
ConversationHostID string `json:"conversation_host_id,omitempty"`
ChannelEmailAddresses []ChannelEmailAddress `json:"channel_email_addresses,omitempty"`
ChannelManagerCount int `json:"channel_manager_count,omitempty"`
ExternalUserCount int `json:"external_user_count,omitempty"`
Canvas *AdminConversationLists `json:"canvas,omitempty"`
Lists *AdminConversationLists `json:"lists,omitempty"`
Properties *Properties `json:"properties,omitempty"`
}
// AdminConversationsSearchResponse represents the response from admin.conversations.search.
type AdminConversationsSearchResponse struct {
SlackResponse
Conversations []AdminConversation `json:"conversations"`
TotalCount int `json:"total_count"`
NextCursor string `json:"next_cursor"`
}
// AdminConversationsSearch searches for public or private channels in an Enterprise organization.
// For more information see the admin.conversations.search docs:
// https://api.slack.com/methods/admin.conversations.search
func (api *Client) AdminConversationsSearch(ctx context.Context, options ...AdminConversationsSearchOption) (*AdminConversationsSearchResponse, error) {
params := adminConversationsSearchParams{}
for _, opt := range options {
opt(&params)
}
values := url.Values{
"token": {api.token},
}
if params.cursor != "" {
values.Add("cursor", params.cursor)
}
if params.limit > 0 {
values.Add("limit", strconv.Itoa(params.limit))
}
if params.query != "" {
values.Add("query", params.query)
}
if len(params.searchChannelType) > 0 {
values.Add("search_channel_types", strings.Join(params.searchChannelType, ","))
}
if params.sort != "" {
values.Add("sort", params.sort)
}
if params.sortDir != "" {
values.Add("sort_dir", params.sortDir)
}
if len(params.teamIDs) > 0 {
values.Add("team_ids", strings.Join(params.teamIDs, ","))
}
if len(params.connectedTeamIDs) > 0 {
values.Add("connected_team_ids", strings.Join(params.connectedTeamIDs, ","))
}
if params.totalCountOnly {
values.Add("total_count_only", "true")
}
response := &AdminConversationsSearchResponse{}
err := api.postMethod(ctx, "admin.conversations.search", values, response)
if err != nil {
return nil, err
}
return response, response.Err()
}
type adminConversationsLookupParams struct {
cursor string
limit int
maxMemberCount int
}
// AdminConversationsLookupOption is an option for AdminConversationsLookup.
type AdminConversationsLookupOption func(*adminConversationsLookupParams)
// AdminConversationsLookupOptionCursor sets the cursor for pagination.
func AdminConversationsLookupOptionCursor(cursor string) AdminConversationsLookupOption {
return func(params *adminConversationsLookupParams) {
params.cursor = cursor
}
}
// AdminConversationsLookupOptionLimit sets the maximum number of results to return.
func AdminConversationsLookupOptionLimit(limit int) AdminConversationsLookupOption {
return func(params *adminConversationsLookupParams) {
params.limit = limit
}
}
// AdminConversationsLookupOptionMaxMemberCount filters to channels with at most this many members.
func AdminConversationsLookupOptionMaxMemberCount(maxMemberCount int) AdminConversationsLookupOption {
return func(params *adminConversationsLookupParams) {
params.maxMemberCount = maxMemberCount
}
}
// AdminConversationsLookupResponse represents the response from admin.conversations.lookup.
type AdminConversationsLookupResponse struct {
SlackResponse
Channels []string `json:"channels"`
}
// AdminConversationsLookup returns channels on the given team matching the specified filters.
// For more information see the admin.conversations.lookup docs:
// https://api.slack.com/methods/admin.conversations.lookup
func (api *Client) AdminConversationsLookup(ctx context.Context, teamIDs []string, lastMessageActivityBefore int64, options ...AdminConversationsLookupOption) ([]string, string, error) {
params := adminConversationsLookupParams{}
for _, opt := range options {
opt(&params)
}
values := url.Values{
"token": {api.token},
"last_message_activity_before": {strconv.FormatInt(lastMessageActivityBefore, 10)},
"team_ids": {strings.Join(teamIDs, ",")},
}
if params.cursor != "" {
values.Add("cursor", params.cursor)
}
if params.limit > 0 {
values.Add("limit", strconv.Itoa(params.limit))
}
if params.maxMemberCount > 0 {
values.Add("max_member_count", strconv.Itoa(params.maxMemberCount))
}
response := &AdminConversationsLookupResponse{}
err := api.postMethod(ctx, "admin.conversations.lookup", values, response)
if err != nil {
return nil, "", err
}
return response.Channels, response.ResponseMetadata.Cursor, response.Err()
}
// AdminConversationsBulkArchive archives public or private channels in bulk.
// For more information see the admin.conversations.bulkArchive docs:
// https://api.slack.com/methods/admin.conversations.bulkArchive
func (api *Client) AdminConversationsBulkArchive(ctx context.Context, channelIDs []string) error {
values := url.Values{
"token": {api.token},
"channel_ids": {strings.Join(channelIDs, ",")},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.bulkArchive", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsBulkDelete deletes public or private channels in bulk.
// For more information see the admin.conversations.bulkDelete docs:
// https://api.slack.com/methods/admin.conversations.bulkDelete
func (api *Client) AdminConversationsBulkDelete(ctx context.Context, channelIDs []string) error {
values := url.Values{
"token": {api.token},
"channel_ids": {strings.Join(channelIDs, ",")},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.bulkDelete", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsBulkMoveParams contains arguments for AdminConversationsBulkMove method call.
type AdminConversationsBulkMoveParams struct {
ChannelIDs []string
TargetTeamID string
}
// AdminConversationsBulkMove moves public or private channels in bulk.
// For more information see the admin.conversations.bulkMove docs:
// https://api.slack.com/methods/admin.conversations.bulkMove
func (api *Client) AdminConversationsBulkMove(ctx context.Context, params AdminConversationsBulkMoveParams) error {
values := url.Values{
"token": {api.token},
"channel_ids": {strings.Join(params.ChannelIDs, ",")},
"target_team_id": {params.TargetTeamID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.bulkMove", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationPrefs represents conversation preferences.
type AdminConversationPrefs struct {
WhoCanPost *AdminConversationPref `json:"who_can_post,omitempty"`
CanThread *AdminConversationPref `json:"can_thread,omitempty"`
CanHuddle *AdminConversationPref `json:"can_huddle,omitempty"`
EnableAtHere *AdminConversationPrefEnabled `json:"enable_at_here,omitempty"`
EnableAtChannel *AdminConversationPrefEnabled `json:"enable_at_channel,omitempty"`
}
// AdminConversationPrefEnabled represents an enabled/disabled preference.
type AdminConversationPrefEnabled struct {
Enabled bool `json:"enabled"`
}
// AdminConversationPref represents a single conversation preference.
type AdminConversationPref struct {
Type []string `json:"type,omitempty"`
User []string `json:"user,omitempty"`
}
// AdminConversationsGetConversationPrefsResponse represents the response from admin.conversations.getConversationPrefs.
type AdminConversationsGetConversationPrefsResponse struct {
SlackResponse
Prefs AdminConversationPrefs `json:"prefs"`
}
// AdminConversationsGetConversationPrefs gets conversation preferences for a public or private channel.
// For more information see the admin.conversations.getConversationPrefs docs:
// https://api.slack.com/methods/admin.conversations.getConversationPrefs
func (api *Client) AdminConversationsGetConversationPrefs(ctx context.Context, channelID string) (*AdminConversationPrefs, error) {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &AdminConversationsGetConversationPrefsResponse{}
err := api.postMethod(ctx, "admin.conversations.getConversationPrefs", values, response)
if err != nil {
return nil, err
}
return &response.Prefs, response.Err()
}
// AdminConversationsSetConversationPrefsParams contains arguments for AdminConversationsSetConversationPrefs method call.
type AdminConversationsSetConversationPrefsParams struct {
ChannelID string
Prefs AdminConversationPrefs
}
// AdminConversationsSetConversationPrefs sets conversation preferences for a public or private channel.
// For more information see the admin.conversations.setConversationPrefs docs:
// https://api.slack.com/methods/admin.conversations.setConversationPrefs
func (api *Client) AdminConversationsSetConversationPrefs(ctx context.Context, params AdminConversationsSetConversationPrefsParams) error {
prefsJSON, err := json.Marshal(params.Prefs)
if err != nil {
return err
}
values := url.Values{
"token": {api.token},
"channel_id": {params.ChannelID},
"prefs": {string(prefsJSON)},
}
response := &SlackResponse{}
err = api.postMethod(ctx, "admin.conversations.setConversationPrefs", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsGetCustomRetentionResponse represents the response from admin.conversations.getCustomRetention.
type AdminConversationsGetCustomRetentionResponse struct {
SlackResponse
DurationDays int `json:"duration_days"`
IsPolicyEnabled bool `json:"is_policy_enabled"`
}
// AdminConversationsGetCustomRetention gets a conversation's custom retention policy.
// For more information see the admin.conversations.getCustomRetention docs:
// https://api.slack.com/methods/admin.conversations.getCustomRetention
func (api *Client) AdminConversationsGetCustomRetention(ctx context.Context, channelID string) (*AdminConversationsGetCustomRetentionResponse, error) {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &AdminConversationsGetCustomRetentionResponse{}
err := api.postMethod(ctx, "admin.conversations.getCustomRetention", values, response)
if err != nil {
return nil, err
}
return response, response.Err()
}
// AdminConversationsSetCustomRetention sets a conversation's custom retention policy.
// For more information see the admin.conversations.setCustomRetention docs:
// https://api.slack.com/methods/admin.conversations.setCustomRetention
func (api *Client) AdminConversationsSetCustomRetention(ctx context.Context, channelID string, durationDays int) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
"duration_days": {strconv.Itoa(durationDays)},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.setCustomRetention", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsRemoveCustomRetention removes a conversation's custom retention policy.
// For more information see the admin.conversations.removeCustomRetention docs:
// https://api.slack.com/methods/admin.conversations.removeCustomRetention
func (api *Client) AdminConversationsRemoveCustomRetention(ctx context.Context, channelID string) error {
values := url.Values{
"token": {api.token},
"channel_id": {channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.removeCustomRetention", values, response)
if err != nil {
return err
}
return response.Err()
}
// AdminConversationsSetTeamsParams contains arguments for AdminConversationsSetTeams
// method calls.
type AdminConversationsSetTeamsParams struct {
ChannelID string
OrgChannel *bool
TargetTeamIDs []string
TeamID *string
}
// Set the workspaces in an Enterprise Grid organisation that connect to a public or
// private channel.
// See: https://api.slack.com/methods/admin.conversations.setTeams
func (api *Client) AdminConversationsSetTeams(ctx context.Context, params AdminConversationsSetTeamsParams) error {
values := url.Values{
"token": {api.token},
"channel_id": {params.ChannelID},
}
if params.OrgChannel != nil {
values.Add("org_channel", strconv.FormatBool(*params.OrgChannel))
}
if len(params.TargetTeamIDs) > 0 {
values.Add("target_team_ids", strings.Join(params.TargetTeamIDs, ",")) // ["T123", "T456"] - > "T123,T456"
}
if params.TeamID != nil {
values.Add("team_id", *params.TeamID)
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.setTeams", values, response)
if err != nil {
return err
}
return response.Err()
}
// ConversationsConvertToPrivate converts a public channel to a private channel. To do
// this, you must have the admin.conversations:write scope. There are other requirements:
// you should read the Slack documentation for more details.
// See: https://api.slack.com/methods/admin.conversations.convertToPrivate
func (api *Client) AdminConversationsConvertToPrivate(ctx context.Context, channelID string) error {
values := url.Values{
"token": []string{api.token},
"channel_id": []string{channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.convertToPrivate", values, response)
if err != nil {
return err
}
return response.Err()
}
// ConversationsConvertToPublic converts a private channel to a public channel. To do
// this, you must have the admin.conversations:write scope. There are other requirements:
// you should read the Slack documentation for more details.
// See: https://api.slack.com/methods/admin.conversations.convertToPublic
func (api *Client) AdminConversationsConvertToPublic(ctx context.Context, channelID string) error {
values := url.Values{
"token": []string{api.token},
"channel_id": []string{channelID},
}
response := &SlackResponse{}
err := api.postMethod(ctx, "admin.conversations.convertToPublic", values, response)
if err != nil {
return err
}
return response.Err()
}