Skip to content

feat(channels): create & add bot participants#4265

Open
dev-rb wants to merge 12 commits into
mainfrom
rahul/feat-channels-bot-participants
Open

feat(channels): create & add bot participants#4265
dev-rb wants to merge 12 commits into
mainfrom
rahul/feat-channels-bot-participants

Conversation

@dev-rb

@dev-rb dev-rb commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@dev-rb dev-rb marked this pull request as draft June 22, 2026 20:50
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added bot creation interface with avatar upload and webhook token management
    • Added bot management capabilities in channel participants panel
    • Added dropdown menu to add existing bots or create new bots within channels
    • Added ability to copy bot webhook tokens for integration
    • Bot feature is controlled by feature flag for gradual rollout
  • Enhancements

    • Refactored channel participants display to support both users and bots
    • Updated loading component with customizable styling support

Walkthrough

This PR adds bot management to the channel participants UI. A new storage service client gains HTTP methods for listing, creating, and channel-scoping bots and their tokens. Solid-Query hooks (useBotsQuery, useCreateBotWithTokenMutation, useChannelBotsQuery, useAddBotToChannelMutation, useRemoveBotFromChannelMutation, useCreateChannelScopedBotMutation) with associated query key factories wrap those methods. The ParticipantsList and ParticipantsListItem components are refactored from a ChannelParticipant model to a generic ParticipantsListItemData model. New AddBotDialog (multi-step Zod-validated creation with webhook token display) and AddBotMenu (dropdown to add existing or create new bots) components are introduced. ChannelParticipantsTab is updated to show a separate Bots panel controlled by an ENABLE_CHANNEL_BOTS_FLAG feature flag. A Select UI wrapper component is also added.

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request lacks a description entirely, making it impossible to assess whether it relates to the changeset. Add a detailed description explaining the bot participant feature, the new components added, and how they integrate with the existing participant system.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title follows conventional commits format with 'feat:' prefix and clearly describes the main changes: bot participant creation and addition to channels.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4eae7c6c-e18b-4bc0-a924-b7291c42a39d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

@dev-rb dev-rb marked this pull request as ready for review June 22, 2026 22:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@js/app/packages/channel/Participants/AddBotDialog.tsx`:
- Around line 128-131: The close function in AddBotDialog dismisses the dialog
but does not prevent in-flight mutations from completing and executing their
onSuccess callbacks. To fix this, track whether the dialog is currently open
using a state variable, and update this state in the close function before
calling reset(). Then modify the mutation's onSuccess handler (around lines
160-174) to check if the dialog is still open before executing side effects like
props.onCreated(bot). This prevents the bot creation callback from executing
after the user has dismissed the dialog.

In `@js/app/packages/channel/Participants/ChannelParticipantsTab.tsx`:
- Around line 43-49: The useChannelBotsQuery hook is being executed
unconditionally regardless of the channelBotsFlag feature flag state, which
causes unnecessary requests when bots are disabled. Update the
useChannelBotsQuery call to include an enabled configuration option in its
options parameter that is set to the value of channelBotsFlag, ensuring the
query only executes when the ENABLE_CHANNEL_BOTS_FLAG feature flag is active.
This will prevent unnecessary network requests and errors in environments where
channel bots are not enabled.
- Around line 169-173: The removeBotFromChannelMutation.mutate call in the
isBotSenderId block does not handle errors, causing bot removal failures to fail
silently and only log to the hook. Add an onError handler to the mutate call
that triggers user-facing error feedback such as a toast notification or error
message to provide immediate visual feedback when the bot removal operation
fails.

In `@js/app/packages/queries/bots/bots.ts`:
- Around line 46-74: The mutationFn in the createBotWithToken mutation performs
two sequential dependent writes (createBot followed by createBotToken). If the
second operation fails after the first succeeds, an orphaned bot remains in the
backend. Refactor this to use a single atomic backend operation that creates
both the bot and token together in one call, or implement explicit compensation
logic that rolls back the bot creation if the token creation fails. Reference
the storageServiceClient.createBot and storageServiceClient.createBotToken calls
within the mutationFn to determine the best approach with your backend team.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d017ea38-1498-4f16-8c53-b7ae894f48d3

📥 Commits

Reviewing files that changed from the base of the PR and between 0fc81b7 and f0843e4.

📒 Files selected for processing (14)
  • js/app/packages/channel/Participants/AddBotDialog.tsx
  • js/app/packages/channel/Participants/AddBotMenu.tsx
  • js/app/packages/channel/Participants/ChannelParticipantsTab.tsx
  • js/app/packages/channel/Participants/ParticipantsList.tsx
  • js/app/packages/channel/Participants/ParticipantsListItem.tsx
  • js/app/packages/core/component/LoadingSpinner.tsx
  • js/app/packages/core/constant/featureFlags.ts
  • js/app/packages/queries/bots/bots.ts
  • js/app/packages/queries/bots/keys.ts
  • js/app/packages/queries/channel/channel-bots.ts
  • js/app/packages/queries/channel/keys.ts
  • js/app/packages/service-clients/service-storage/client.ts
  • js/app/packages/ui/components/Select.tsx
  • js/app/packages/ui/index.ts

Comment on lines +128 to +131
const close = () => {
props.onOpenChange(false);
reset();
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent hidden post-close side effects while create is in flight.

The dialog can be closed during step 1, but the in-flight mutation still runs and later executes onSuccess (including props.onCreated(bot)). This can create/add a bot after the user already dismissed the flow.

Suggested fix
   const close = () => {
+    if (step() === 1) return;
     props.onOpenChange(false);
     reset();
   };

   return (
     <Dialog
       open={props.open}
       onOpenChange={(open) => {
         if (open) props.onOpenChange(true);
-        else close();
+        else if (step() !== 1) close();
       }}
     >
@@
           <Dialog.CloseButton
             as={Button}
             class="ml-auto"
             variant="ghost"
             size="icon-sm"
+            disabled={step() === 1}
           >
             <IconX />
           </Dialog.CloseButton>

Also applies to: 160-174

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/channel/Participants/AddBotDialog.tsx` around lines 128 -
131, The close function in AddBotDialog dismisses the dialog but does not
prevent in-flight mutations from completing and executing their onSuccess
callbacks. To fix this, track whether the dialog is currently open using a state
variable, and update this state in the close function before calling reset().
Then modify the mutation's onSuccess handler (around lines 160-174) to check if
the dialog is still open before executing side effects like
props.onCreated(bot). This prevents the bot creation callback from executing
after the user has dismissed the dialog.

Comment on lines +43 to +49
const channelBotsFlag = useFeatureFlag(ENABLE_CHANNEL_BOTS_FLAG, {
enabledOverride: ENABLE_CHANNEL_BOTS_OVERRIDE,
});
const participantsQuery = useChannelParticipantsQuery(() => props.channelId);
const channelBotsQuery = useChannelBotsQuery(() => ({
channelId: props.channelId,
}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Gate useChannelBotsQuery execution behind the feature flag.

The bots panel is feature-gated, but useChannelBotsQuery still runs even when the flag is off. That can produce unnecessary requests/errors in environments where bots are disabled.

Suggested direction
- const channelBotsQuery = useChannelBotsQuery(() => ({
-   channelId: props.channelId,
- }));
+ const channelBotsQuery = useChannelBotsQuery(() => ({
+   channelId: props.channelId,
+   enabled: channelBotsFlag().enabled,
+ }));

And update useChannelBotsQuery options to honor enabled in the query config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/channel/Participants/ChannelParticipantsTab.tsx` around lines
43 - 49, The useChannelBotsQuery hook is being executed unconditionally
regardless of the channelBotsFlag feature flag state, which causes unnecessary
requests when bots are disabled. Update the useChannelBotsQuery call to include
an enabled configuration option in its options parameter that is set to the
value of channelBotsFlag, ensuring the query only executes when the
ENABLE_CHANNEL_BOTS_FLAG feature flag is active. This will prevent unnecessary
network requests and errors in environments where channel bots are not enabled.

Comment on lines +169 to +173
if (isBotSenderId(participantId)) {
removeBotFromChannelMutation.mutate({
channelId: props.channelId,
botId: senderFromStorageId(participantId).id,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add user-facing error feedback for bot removal failures.

Bot removal currently fails silently in UI (hook logs only). Provide an onError handler here so users get immediate feedback when removal fails.

Suggested fix
     if (isBotSenderId(participantId)) {
-      removeBotFromChannelMutation.mutate({
-        channelId: props.channelId,
-        botId: senderFromStorageId(participantId).id,
-      });
+      removeBotFromChannelMutation.mutate(
+        {
+          channelId: props.channelId,
+          botId: senderFromStorageId(participantId).id,
+        },
+        {
+          onError: () => toast.failure('Failed to remove bot from channel'),
+        }
+      );
       return;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/channel/Participants/ChannelParticipantsTab.tsx` around lines
169 - 173, The removeBotFromChannelMutation.mutate call in the isBotSenderId
block does not handle errors, causing bot removal failures to fail silently and
only log to the hook. Add an onError handler to the mutate call that triggers
user-facing error feedback such as a toast notification or error message to
provide immediate visual feedback when the bot removal operation fails.

Comment on lines +46 to +74
mutationFn: async (
vars: CreateBotWithTokenParams
): Promise<CreateBotWithTokenResponse> => {
const bot = await throwOnErr(() =>
storageServiceClient.createBot({
avatar_url: vars.avatarUrl,
description: vars.description,
handle: vars.handle,
name: vars.name,
team_id: vars.teamId,
})
);
const tokenResponse = await throwOnErr(() =>
storageServiceClient.createBotToken({
bot_id: bot.id,
expires_at: vars.tokenExpiresAt,
label: vars.tokenLabel,
})
);

return {
bot,
token: tokenResponse.token,
bot_token: tokenResponse.bearer_token,
};
},
onSuccess: () => {
void invalidateBots();
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make bot+token creation atomic (or add compensation) to prevent partial writes.

This mutation does two dependent writes; if token creation fails after bot creation, the operation surfaces as failed while backend state is already mutated. That creates orphaned bots and retry hazards. Please move to a single atomic backend operation (preferred) or implement explicit compensation/idempotency semantics for this flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/queries/bots/bots.ts` around lines 46 - 74, The mutationFn in
the createBotWithToken mutation performs two sequential dependent writes
(createBot followed by createBotToken). If the second operation fails after the
first succeeds, an orphaned bot remains in the backend. Refactor this to use a
single atomic backend operation that creates both the bot and token together in
one call, or implement explicit compensation logic that rolls back the bot
creation if the token creation fails. Reference the
storageServiceClient.createBot and storageServiceClient.createBotToken calls
within the mutationFn to determine the best approach with your backend team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant