Skip to content

Commit 9f3240d

Browse files
authored
Fix #1108 add support for admin.conversations retention (#1109)
1 parent 01993c7 commit 9f3240d

File tree

5 files changed

+229
-5
lines changed

5 files changed

+229
-5
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import asyncio
2+
import logging
3+
import os
4+
import time
5+
import unittest
6+
7+
from integration_tests.env_variable_names import SLACK_SDK_TEST_GRID_ORG_ADMIN_USER_TOKEN, SLACK_SDK_TEST_GRID_TEAM_ID
8+
from integration_tests.helpers import async_test
9+
from slack_sdk.web import WebClient
10+
from slack_sdk.web.async_client import AsyncWebClient
11+
12+
13+
class TestWebClient(unittest.TestCase):
14+
"""Runs integration tests with real Slack API"""
15+
16+
def setUp(self):
17+
self.logger = logging.getLogger(__name__)
18+
self.org_admin_token = os.environ[SLACK_SDK_TEST_GRID_ORG_ADMIN_USER_TOKEN]
19+
self.team_id = os.environ[SLACK_SDK_TEST_GRID_TEAM_ID]
20+
self.sync_client: WebClient = WebClient(token=self.org_admin_token)
21+
self.async_client: AsyncWebClient = AsyncWebClient(token=self.org_admin_token)
22+
23+
self.channel_name = f"test-channel-{int(round(time.time() * 1000))}"
24+
25+
def tearDown(self):
26+
pass
27+
28+
def test_sync(self):
29+
client = self.sync_client
30+
31+
conv_creation = client.admin_conversations_create(
32+
is_private=False,
33+
name=self.channel_name,
34+
team_id=self.team_id,
35+
)
36+
self.assertIsNotNone(conv_creation)
37+
created_channel_id = conv_creation.data["channel_id"]
38+
39+
self.assertIsNotNone(
40+
client.admin_conversations_setCustomRetention(
41+
channel_id=created_channel_id,
42+
duration_days=365,
43+
)
44+
)
45+
self.assertIsNotNone(
46+
client.admin_conversations_getCustomRetention(
47+
channel_id=created_channel_id,
48+
)
49+
)
50+
self.assertIsNotNone(
51+
client.admin_conversations_removeCustomRetention(
52+
channel_id=created_channel_id,
53+
)
54+
)
55+
56+
time.sleep(2) # To avoid internal_error
57+
self.assertIsNotNone(
58+
client.admin_conversations_delete(
59+
channel_id=created_channel_id,
60+
)
61+
)
62+
63+
@async_test
64+
async def test_async(self):
65+
# await asyncio.sleep(seconds) are included to avoid rate limiting errors
66+
67+
client = self.async_client
68+
69+
conv_creation = await client.admin_conversations_create(
70+
is_private=False,
71+
name=self.channel_name,
72+
team_id=self.team_id,
73+
)
74+
self.assertIsNotNone(conv_creation)
75+
created_channel_id = conv_creation.data["channel_id"]
76+
77+
self.assertIsNotNone(
78+
await client.admin_conversations_setCustomRetention(
79+
channel_id=created_channel_id,
80+
duration_days=365,
81+
)
82+
)
83+
self.assertIsNotNone(
84+
await client.admin_conversations_getCustomRetention(
85+
channel_id=created_channel_id,
86+
)
87+
)
88+
self.assertIsNotNone(
89+
await client.admin_conversations_removeCustomRetention(
90+
channel_id=created_channel_id,
91+
)
92+
)
93+
94+
await asyncio.sleep(2) # To avoid internal_error
95+
self.assertIsNotNone(
96+
await client.admin_conversations_delete(
97+
channel_id=created_channel_id,
98+
)
99+
)

slack_sdk/web/async_client.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,49 @@ async def admin_conversations_getTeams(
777777
)
778778
return await self.api_call("admin.conversations.getTeams", params=kwargs)
779779

780+
async def admin_conversations_getCustomRetention(
781+
self,
782+
*,
783+
channel_id: str,
784+
**kwargs,
785+
) -> AsyncSlackResponse:
786+
"""Get a channel's retention policy
787+
https://api.slack.com/methods/admin.conversations.getCustomRetention
788+
"""
789+
kwargs.update({"channel_id": channel_id})
790+
return await self.api_call(
791+
"admin.conversations.getCustomRetention", params=kwargs
792+
)
793+
794+
async def admin_conversations_removeCustomRetention(
795+
self,
796+
*,
797+
channel_id: str,
798+
**kwargs,
799+
) -> AsyncSlackResponse:
800+
"""Remove a channel's retention policy
801+
https://api.slack.com/methods/admin.conversations.removeCustomRetention
802+
"""
803+
kwargs.update({"channel_id": channel_id})
804+
return await self.api_call(
805+
"admin.conversations.removeCustomRetention", params=kwargs
806+
)
807+
808+
async def admin_conversations_setCustomRetention(
809+
self,
810+
*,
811+
channel_id: str,
812+
duration_days: int,
813+
**kwargs,
814+
) -> AsyncSlackResponse:
815+
"""Set a channel's retention policy
816+
https://api.slack.com/methods/admin.conversations.setCustomRetention
817+
"""
818+
kwargs.update({"channel_id": channel_id, "duration_days": duration_days})
819+
return await self.api_call(
820+
"admin.conversations.setCustomRetention", params=kwargs
821+
)
822+
780823
async def admin_emoji_add(
781824
self,
782825
*,

slack_sdk/web/client.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,43 @@ def admin_conversations_getTeams(
746746
)
747747
return self.api_call("admin.conversations.getTeams", params=kwargs)
748748

749+
def admin_conversations_getCustomRetention(
750+
self,
751+
*,
752+
channel_id: str,
753+
**kwargs,
754+
) -> SlackResponse:
755+
"""Get a channel's retention policy
756+
https://api.slack.com/methods/admin.conversations.getCustomRetention
757+
"""
758+
kwargs.update({"channel_id": channel_id})
759+
return self.api_call("admin.conversations.getCustomRetention", params=kwargs)
760+
761+
def admin_conversations_removeCustomRetention(
762+
self,
763+
*,
764+
channel_id: str,
765+
**kwargs,
766+
) -> SlackResponse:
767+
"""Remove a channel's retention policy
768+
https://api.slack.com/methods/admin.conversations.removeCustomRetention
769+
"""
770+
kwargs.update({"channel_id": channel_id})
771+
return self.api_call("admin.conversations.removeCustomRetention", params=kwargs)
772+
773+
def admin_conversations_setCustomRetention(
774+
self,
775+
*,
776+
channel_id: str,
777+
duration_days: int,
778+
**kwargs,
779+
) -> SlackResponse:
780+
"""Set a channel's retention policy
781+
https://api.slack.com/methods/admin.conversations.setCustomRetention
782+
"""
783+
kwargs.update({"channel_id": channel_id, "duration_days": duration_days})
784+
return self.api_call("admin.conversations.setCustomRetention", params=kwargs)
785+
749786
def admin_emoji_add(
750787
self,
751788
*,

slack_sdk/web/legacy_client.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,43 @@ def admin_conversations_getTeams(
757757
)
758758
return self.api_call("admin.conversations.getTeams", params=kwargs)
759759

760+
def admin_conversations_getCustomRetention(
761+
self,
762+
*,
763+
channel_id: str,
764+
**kwargs,
765+
) -> Union[Future, SlackResponse]:
766+
"""Get a channel's retention policy
767+
https://api.slack.com/methods/admin.conversations.getCustomRetention
768+
"""
769+
kwargs.update({"channel_id": channel_id})
770+
return self.api_call("admin.conversations.getCustomRetention", params=kwargs)
771+
772+
def admin_conversations_removeCustomRetention(
773+
self,
774+
*,
775+
channel_id: str,
776+
**kwargs,
777+
) -> Union[Future, SlackResponse]:
778+
"""Remove a channel's retention policy
779+
https://api.slack.com/methods/admin.conversations.removeCustomRetention
780+
"""
781+
kwargs.update({"channel_id": channel_id})
782+
return self.api_call("admin.conversations.removeCustomRetention", params=kwargs)
783+
784+
def admin_conversations_setCustomRetention(
785+
self,
786+
*,
787+
channel_id: str,
788+
duration_days: int,
789+
**kwargs,
790+
) -> Union[Future, SlackResponse]:
791+
"""Set a channel's retention policy
792+
https://api.slack.com/methods/admin.conversations.setCustomRetention
793+
"""
794+
kwargs.update({"channel_id": channel_id, "duration_days": duration_days})
795+
return self.api_call("admin.conversations.setCustomRetention", params=kwargs)
796+
760797
def admin_emoji_add(
761798
self,
762799
*,

tests/slack_sdk_async/web/test_web_client_coverage.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616

1717
class TestWebClientCoverage(unittest.TestCase):
18-
# 247 endpoints as of Aug 10, 2021
18+
# 240 endpoints as of Sept 4, 2021
1919
# Can be fetched by running `var methodNames = [].slice.call(document.getElementsByClassName('apiReferenceFilterableList__listItemLink')).map(e => e.href.replace("https://api.slack.com/methods/", ""));console.log(methodNames.toString());console.log(methodNames.length);` on https://api.slack.com/methods
20-
all_api_methods = "admin.analytics.getFile,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.requests.list,admin.apps.restricted.list,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.convertToPrivate,admin.conversations.create,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.setSettings,api.test,apps.connections.open,apps.event.authorizations.list,apps.uninstall,auth.revoke,auth.test,auth.teams.list,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.unfurl,chat.update,chat.scheduledMessages.list,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.comments.delete,files.delete,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,migration.exchange,oauth.access,oauth.token,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.profile.get,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,apps.permissions.info,apps.permissions.request,apps.permissions.resources.list,apps.permissions.scopes.list,apps.permissions.users.list,apps.permissions.users.request,channels.archive,channels.create,channels.history,channels.info,channels.invite,channels.join,channels.kick,channels.leave,channels.list,channels.mark,channels.rename,channels.replies,channels.setPurpose,channels.setTopic,channels.unarchive,groups.archive,groups.create,groups.createChild,groups.history,groups.info,groups.invite,groups.kick,groups.leave,groups.list,groups.mark,groups.open,groups.rename,groups.replies,groups.setPurpose,groups.setTopic,groups.unarchive,im.close,im.history,im.list,im.mark,im.open,im.replies,mpim.close,mpim.history,mpim.list,mpim.mark,mpim.open,mpim.replies".split(
20+
all_api_methods = "admin.analytics.getFile,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.requests.list,admin.apps.restricted.list,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.convertToPrivate,admin.conversations.create,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.setSettings,api.test,apps.connections.open,apps.event.authorizations.list,apps.uninstall,auth.revoke,auth.test,auth.teams.list,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.unfurl,chat.update,chat.scheduledMessages.list,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.comments.delete,files.delete,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,migration.exchange,oauth.access,oauth.token,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.profile.get,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,apps.permissions.info,apps.permissions.request,apps.permissions.resources.list,apps.permissions.scopes.list,apps.permissions.users.list,apps.permissions.users.request,channels.archive,channels.create,channels.history,channels.info,channels.invite,channels.join,channels.leave,channels.list,channels.mark,channels.replies,channels.setPurpose,channels.setTopic,channels.unarchive,groups.archive,groups.create,groups.history,groups.info,groups.invite,groups.leave,groups.list,groups.mark,groups.open,groups.replies,groups.setPurpose,groups.setTopic,groups.unarchive,im.history,im.list,im.mark,im.open,im.replies,mpim.history,mpim.list,mpim.mark,mpim.open,mpim.replies".split(
2121
","
2222
)
2323

@@ -48,9 +48,6 @@ def setUp(self):
4848
"openid.connect.token",
4949
"openid.connect.userInfo",
5050
"users.setActive",
51-
"admin.conversations.getCustomRetention",
52-
"admin.conversations.removeCustomRetention",
53-
"admin.conversations.setCustomRetention",
5451
]:
5552
continue
5653
self.api_methods_to_call.append(api_method)
@@ -1017,6 +1014,17 @@ async def run_method(self, method_name, method, async_method):
10171014
):
10181015
self.api_methods_to_call.remove(method()["method"])
10191016
await async_method()
1017+
elif method_name == "admin_conversations_getCustomRetention":
1018+
self.api_methods_to_call.remove(method(channel_id="C123")["method"])
1019+
await async_method(channel_id="C123")
1020+
elif method_name == "admin_conversations_removeCustomRetention":
1021+
self.api_methods_to_call.remove(method(channel_id="C123")["method"])
1022+
await async_method(channel_id="C123")
1023+
elif method_name == "admin_conversations_setCustomRetention":
1024+
self.api_methods_to_call.remove(
1025+
method(channel_id="C123", duration_days=365)["method"]
1026+
)
1027+
await async_method(channel_id="C123", duration_days=365)
10201028
else:
10211029
self.api_methods_to_call.remove(method(*{})["method"])
10221030
await async_method(*{})

0 commit comments

Comments
 (0)