From 64a3afe86af4967118b4aaa290e5eb775620ff68 Mon Sep 17 00:00:00 2001 From: Weves Date: Wed, 9 Jul 2025 09:45:14 -0700 Subject: [PATCH] Stop fetching channel info to make pages load faster --- backend/onyx/server/manage/slack_bot.py | 83 ---------------- .../channels/SlackChannelConfigFormFields.tsx | 94 ++----------------- web/src/app/admin/bots/[bot-id]/lib.ts | 14 --- 3 files changed, 6 insertions(+), 185 deletions(-) diff --git a/backend/onyx/server/manage/slack_bot.py b/backend/onyx/server/manage/slack_bot.py index 63b9bcc29cf..e43e23f227d 100644 --- a/backend/onyx/server/manage/slack_bot.py +++ b/backend/onyx/server/manage/slack_bot.py @@ -1,8 +1,6 @@ from fastapi import APIRouter from fastapi import Depends from fastapi import HTTPException -from slack_sdk import WebClient -from slack_sdk.errors import SlackApiError from sqlalchemy.orm import Session from onyx.auth.users import current_admin_user @@ -13,7 +11,6 @@ from onyx.db.models import User from onyx.db.persona import get_persona_by_id from onyx.db.slack_bot import fetch_slack_bot -from onyx.db.slack_bot import fetch_slack_bot_tokens from onyx.db.slack_bot import fetch_slack_bots from onyx.db.slack_bot import insert_slack_bot from onyx.db.slack_bot import remove_slack_bot @@ -27,7 +24,6 @@ from onyx.onyxbot.slack.config import validate_channel_name from onyx.server.manage.models import SlackBot from onyx.server.manage.models import SlackBotCreationRequest -from onyx.server.manage.models import SlackChannel from onyx.server.manage.models import SlackChannelConfig from onyx.server.manage.models import SlackChannelConfigCreationRequest from onyx.server.manage.validate_tokens import validate_app_token @@ -355,82 +351,3 @@ def list_bot_configs( SlackChannelConfig.from_model(slack_bot_config_model) for slack_bot_config_model in slack_bot_config_models ] - - -@router.get( - "/admin/slack-app/bots/{bot_id}/channels", -) -def get_all_channels_from_slack_api( - bot_id: int, - db_session: Session = Depends(get_session), - _: 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. - Handles pagination with a limit to avoid excessive API calls. - """ - tokens = fetch_slack_bot_tokens(db_session, bot_id) - if not tokens or "bot_token" not in tokens: - raise HTTPException( - status_code=404, detail="Bot token not found for the given bot ID" - ) - - client = WebClient(token=tokens["bot_token"], timeout=1) - all_channels: list[dict] = [] - next_cursor = None - - try: - # Use conversations_list to get all channels in the workspace (including ones the bot is not a member of) - while len(all_channels) < SLACK_MAX_RETURNED_CHANNELS: - # Make API call with cursor if we have one - if next_cursor: - response = client.conversations_list( - types="public_channel,private_channel", - exclude_archived=True, - cursor=next_cursor, - limit=SLACK_API_CHANNELS_PER_PAGE, - ) - else: - response = client.conversations_list( - types="public_channel,private_channel", - exclude_archived=True, - limit=SLACK_API_CHANNELS_PER_PAGE, - ) - - # Add channels to our list - if "channels" in response and response["channels"]: - all_channels.extend(response["channels"]) - - # Check if we need to paginate - if ( - "response_metadata" in response - and "next_cursor" in response["response_metadata"] - ): - next_cursor = response["response_metadata"]["next_cursor"] - if next_cursor: - 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 - ] - - return channels - - except SlackApiError as e: - # Handle rate limiting or other API errors - logger.exception("Error fetching channels from Slack API") - raise HTTPException( - status_code=500, - detail=f"Error fetching channels from Slack API: {str(e)}", - ) 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 33517637ec3..a198411c772 100644 --- a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx +++ b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx @@ -29,11 +29,7 @@ import { TooltipProvider } from "@radix-ui/react-tooltip"; import { SourceIcon } from "@/components/SourceIcon"; import Link from "next/link"; import { AssistantIcon } from "@/components/assistants/AssistantIcon"; -import { SearchMultiSelectDropdown } from "@/components/Dropdown"; -import { fetchSlackChannels } from "../lib"; import { Badge } from "@/components/ui/badge"; -import useSWR from "swr"; -import { ThreeDotsLoader } from "@/components/Loading"; import { Accordion, AccordionContent, @@ -171,48 +167,6 @@ export function SlackChannelConfigFormFields({ ); }, [documentSets]); - const { - data: channelOptions, - error, - isLoading, - } = useSWR( - `/api/manage/admin/slack-app/bots/${slack_bot_id}/channels`, - async () => { - const channels = await fetchSlackChannels(slack_bot_id); - return channels.map((channel: any) => ({ - name: channel.name, - value: channel.id, - })); - }, - { - shouldRetryOnError: false, // don't spam the Slack API - dedupingInterval: 60000, // Limit re-fetching to once per minute - } - ); - - // 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 ; - } - return ( <>
@@ -241,48 +195,12 @@ export function SlackChannelConfigFormFields({ )} {!isDefault && ( <> - {" "} - {error ? ( -
-
- {error.message || "Unable to fetch Slack channels."} - {" Please enter the channel name manually."} -
- -
- ) : ( - <> - - {({ field, form }: { field: any; form: any }) => ( - { - form.setFieldValue("channel_name", selected.name); - }} - initialSearchTerm={field.value} - onSearchTermChange={(term) => { - form.setFieldValue("channel_name", term); - }} - allowCustomValues={true} - /> - )} - - {channelHelperText && ( -

- {channelHelperText} -

- )} - - )} + )}
diff --git a/web/src/app/admin/bots/[bot-id]/lib.ts b/web/src/app/admin/bots/[bot-id]/lib.ts index 4ba58805f37..5a1e506b96b 100644 --- a/web/src/app/admin/bots/[bot-id]/lib.ts +++ b/web/src/app/admin/bots/[bot-id]/lib.ts @@ -94,17 +94,3 @@ export const deleteSlackChannelConfig = async (id: number) => { export function isPersonaASlackBotPersona(persona: Persona) { return persona.name.startsWith("__slack_bot_persona__"); } - -export const fetchSlackChannels = async (botId: number) => { - return fetch(`/api/manage/admin/slack-app/bots/${botId}/channels`, { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - }).then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch Slack channels"); - } - return response.json(); - }); -};