From c9a609b7d8419834cfaa704fbc3b06600b447da4 Mon Sep 17 00:00:00 2001 From: rkuo-danswer Date: Wed, 23 Apr 2025 13:00:03 -0700 Subject: [PATCH] Bugfix/slack bot channel config (#4585) * friendlier handling of slack channel retrieval * retry on downgrade_postgres deadlock * fix comment * text --------- Co-authored-by: Richard Kuo (Onyx) --- backend/onyx/server/manage/slack_bot.py | 23 ++++++--------- .../tests/integration/common_utils/reset.py | 4 +++ .../channels/SlackChannelConfigFormFields.tsx | 29 +++++++++++++++---- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/backend/onyx/server/manage/slack_bot.py b/backend/onyx/server/manage/slack_bot.py index fade2aa7ff..ef008a18e2 100644 --- a/backend/onyx/server/manage/slack_bot.py +++ b/backend/onyx/server/manage/slack_bot.py @@ -36,6 +36,8 @@ from onyx.utils.logger import setup_logger from onyx.utils.telemetry import create_milestone_and_report from shared_configs.contextvars import get_current_tenant_id +SLACK_API_CHANNELS_PER_PAGE = 100 +SLACK_MAX_RETURNED_CHANNELS = 500 logger = setup_logger() @@ -355,10 +357,6 @@ def list_bot_configs( ] -MAX_SLACK_PAGES = 5 -SLACK_API_CHANNELS_PER_PAGE = 100 - - @router.get( "/admin/slack-app/bots/{bot_id}/channels", ) @@ -368,6 +366,9 @@ def get_all_channels_from_slack_api( _: User | None = Depends(current_admin_user), ) -> list[SlackChannel]: """ + Returns a list of available slack channels for the slack bot, limited to + SLACK_MAX_RETURNED_CHANNELS. + Fetches all channels in the Slack workspace using the conversations_list API. This includes both public and private channels that are visible to the app, not just the ones the bot is a member of. @@ -380,15 +381,12 @@ def get_all_channels_from_slack_api( ) client = WebClient(token=tokens["bot_token"], timeout=1) - all_channels = [] + all_channels: list[dict] = [] next_cursor = None - current_page = 0 try: # Use conversations_list to get all channels in the workspace (including ones the bot is not a member of) - while current_page < MAX_SLACK_PAGES: - current_page += 1 - + while len(all_channels) < SLACK_MAX_RETURNED_CHANNELS: # Make API call with cursor if we have one if next_cursor: response = client.conversations_list( @@ -415,16 +413,13 @@ def get_all_channels_from_slack_api( ): next_cursor = response["response_metadata"]["next_cursor"] if next_cursor: - if current_page == MAX_SLACK_PAGES: - raise HTTPException( - status_code=400, - detail="Workspace has too many channels to paginate over in this call.", - ) continue # If we get here, no more pages break + del all_channels[SLACK_MAX_RETURNED_CHANNELS:] # truncate the list + channels = [ SlackChannel(id=channel["id"], name=channel["name"]) for channel in all_channels diff --git a/backend/tests/integration/common_utils/reset.py b/backend/tests/integration/common_utils/reset.py index 955d728f56..1194dc745c 100644 --- a/backend/tests/integration/common_utils/reset.py +++ b/backend/tests/integration/common_utils/reset.py @@ -273,6 +273,10 @@ def reset_postgres( logger.warning( f"Postgres downgrade timed out, retrying... ({_ + 1}/{NUM_TRIES})" ) + except RuntimeError: + logger.warning( + f"Postgres downgrade exceptioned, retrying... ({_ + 1}/{NUM_TRIES})" + ) if not success: raise RuntimeError("Postgres downgrade failed after 10 timeouts.") diff --git a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx index c6c2e11e66..04a2236d5c 100644 --- a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx +++ b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx @@ -190,6 +190,25 @@ export function SlackChannelConfigFormFields({ } ); + // Define the helper text based on the state + const channelHelperText = useMemo(() => { + if (isLoading || error) { + // No helper text needed during loading or if there's an error + // (error message is shown separately) + return null; + } + if (!channelOptions || channelOptions.length === 0) { + return "No channels found. You can type any channel name in directly."; + } + + let helpText = `Select a channel from the dropdown list or type any channel name in directly.`; + if (channelOptions.length >= 500) { + return `${helpText} (Retrieved the first ${channelOptions.length} channels.)`; + } + + return helpText; + }, [isLoading, error, channelOptions]); + if (isLoading) { return ; } @@ -257,11 +276,11 @@ export function SlackChannelConfigFormFields({ /> )} -

- Note: This list shows existing public and private channels (up - to 500). You can either select from the list or type any - channel name directly. -

+ {channelHelperText && ( +

+ {channelHelperText} +

+ )} )}