Skip to content

Conversation

@akanshaaa19
Copy link
Member

@akanshaaa19 akanshaaa19 commented Nov 10, 2025

Summary by CodeRabbit

  • New Features

    • Webhook router now supports dynamic function selection, allowing users to select from available webhook functions instead of manually entering URLs.
  • Chores

    • Version bump to 1.43.0-4.

@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Walkthrough

The pull request introduces dynamic webhook function selection for the webhook router component, replacing static URL input with a dropdown selector for FUNCTION method type. It updates state management to track selected webhook functions and fetches options from an async endpoint.

Changes

Cohort / File(s) Summary
Version bump
package.json
Minor version increment from 1.43.0-3 to 1.43.0-4
Webhook router dynamic function selection
src/components/flow/routers/webhook/WebhookRouterForm.tsx
Replaces URL TextInputElement with TembaSelectElement for FUNCTION method; adds webhookFunction and webhookOptions state fields; implements handleWebhookFunctionChanged to sync function, URL, and body; adds contextTypes to access config; initializes webhookOptions on mount from async endpoint; adjusts body validation to skip JSON validation for empty FUNCTION method bodies
Webhook router state initialization
src/components/flow/routers/webhook/helpers.ts
Adds webhookFunction and webhookOptions initialization to nodeToState function

Sequence Diagram

sequenceDiagram
    participant User
    participant Form as WebhookRouterForm
    participant API as Webhook API
    participant State as Form State

    Note over Form: Component Mount
    Form->>API: Fetch webhook options
    API-->>Form: Return webhookOptions
    Form->>State: Initialize webhookOptions
    
    User->>Form: Select webhook function
    Form->>Form: handleWebhookFunctionChanged()
    
    rect rgb(200, 220, 255)
    Note over Form: Update state with selected function
    Form->>State: Set webhookFunction
    Form->>State: Set URL from webhook metadata
    Form->>State: Set body (if applicable)
    end
    
    alt Function Selected
        Form-->>User: Display function details
    else Function Cleared
        Form-->>User: Reset form fields
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Area for extra attention: The conditional rendering logic in WebhookRouterForm between FUNCTION and non-FUNCTION methods—ensure form state transitions are handled correctly when switching methods
  • Area for extra attention: Validation logic for body field when using FUNCTION method; confirm empty body handling doesn't bypass necessary checks
  • Area for extra attention: Async initialization of webhookOptions on mount; verify error handling if the endpoint fails

Possibly related PRs

Suggested reviewers

  • madclaws
  • priyanshu6238

Poem

🐰 A webhook hops with functions new,
No longer bound to static URLs,
Dynamic selectors hop on through,
Async endpoints pull their cues,
State and sync now dance as one! 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Dropdown for webhooks' directly describes the main change: replacing URL input with a dropdown/select element for webhook function selection.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dropdown_for_webhooks

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/flow/routers/webhook/WebhookRouterForm.tsx (1)

270-285: Critical: Add validation to ensure webhook function is selected for FUNCTION method.

Currently, the FUNCTION method only validates the result name. This allows saving a webhook without selecting a function, resulting in an empty URL that will cause runtime failures.

Apply this diff to add validation:

 private handleSave(): void {
   let valid = false;
   if (this.state.method.value.name === 'FUNCTION') {
-    valid = this.handleUpdate({ resultName: this.state.resultName.value }, true);
+    // Validate that a function is selected
+    if (!this.state.webhookFunction.value) {
+      const updates: Partial<WebhookRouterFormState> = {
+        webhookFunction: {
+          value: null,
+          validationFailures: [{ message: i18n.t('forms.function_required', 'Please select a function') }]
+        }
+      };
+      this.setState(mergeForm(this.state, updates) as WebhookRouterFormState);
+      return;
+    }
+    valid = this.handleUpdate({ resultName: this.state.resultName.value }, true);
   } else {
     valid = this.handleUpdate(
       { url: this.state.url.value, resultName: this.state.resultName.value },
       true
     );
   }

   if (valid) {
     this.props.updateRouter(stateToNode(this.props.nodeSettings, this.state));
     this.props.onClose(false);
   }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5690d16 and 30d568e.

⛔ Files ignored due to path filters (1)
  • src/components/flow/routers/webhook/__snapshots__/WebhookRouterForm.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • package.json (1 hunks)
  • src/components/flow/routers/webhook/WebhookRouterForm.tsx (7 hunks)
  • src/components/flow/routers/webhook/helpers.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/flow/routers/webhook/WebhookRouterForm.tsx (7)
src/store/nodeEditor.ts (2)
  • FormEntry (22-25)
  • mergeForm (63-156)
src/components/flow/props.ts (1)
  • RouterFormProps (35-47)
src/config/ConfigProvider.tsx (1)
  • fakePropType (4-4)
src/components/flow/routers/webhook/helpers.ts (3)
  • nodeToState (55-110)
  • getDefaultBody (156-158)
  • isValidJson (160-170)
src/store/validators.ts (1)
  • validate (118-132)
src/temba/TembaSelectElement.tsx (1)
  • TembaSelectElement (13-26)
src/components/form/textinput/TextInputElement.tsx (1)
  • TextInputElement (35-94)
🔇 Additional comments (8)
package.json (1)

5-5: LGTM!

The version bump is appropriate for the webhook dropdown feature additions in this PR.

src/components/flow/routers/webhook/helpers.ts (1)

66-67: LGTM with a minor concern about stale function references.

The additions to the initial state properly support the FUNCTION method workflow. The WebhookRouterForm handles pre-selection in componentDidMount (lines 90-101 in WebhookRouterForm.tsx).

However, if a previously saved function name no longer exists in the fetched options (e.g., deleted or renamed), the webhookFunction will be set to null, potentially creating a confusing UX where the URL field contains a function name but nothing is selected in the dropdown.

Consider adding fallback logic in WebhookRouterForm.tsx componentDidMount to display a warning or create a placeholder option when a saved function name doesn't match current options.

src/components/flow/routers/webhook/WebhookRouterForm.tsx (6)

19-19: LGTM!

The new imports are properly utilized for the FUNCTION method dropdown implementation.

Also applies to: 36-36


52-53: LGTM!

The state interface additions and context setup properly enable dynamic webhook function loading from the config endpoint.

Also applies to: 60-62


103-125: LGTM!

The webhook function selection handler properly synchronizes the webhookFunction, URL, and body fields when a function is selected or cleared.


155-158: LGTM!

Correctly skips setting default body for FUNCTION methods since the body is populated from the selected webhook function.


197-205: LGTM!

The conditional JSON validation appropriately allows empty bodies for FUNCTION methods while maintaining validation for non-empty content.


394-415: LGTM!

The conditional rendering appropriately switches between the webhook function dropdown for FUNCTION methods and the URL input field for other HTTP methods.

Comment on lines +77 to +101
async componentDidMount() {
const endpoint = this.context.config.endpoints.completion;
const response = await fetch(endpoint);
const data = await response.json();

const webhookOptions = (data.webhook || []).map((webhook: any) => ({
name: webhook.name,
value: webhook.name,
id: webhook.name,
label: webhook.name,
body: webhook.body
}));

if (this.state.method.value.value === Methods.FUNCTION && this.state.url.value) {
const functionName = this.state.url.value;
const selectedOption = webhookOptions.find((opt: any) => opt.name === functionName);

this.setState({
webhookOptions,
webhookFunction: { value: selectedOption || null }
});
} else {
this.setState({ webhookOptions });
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling and loading state for the async fetch.

The fetch call lacks error handling, which could cause unhandled promise rejections or a broken component state if the endpoint fails or returns unexpected data.

Apply this diff to add proper error handling:

 async componentDidMount() {
-  const endpoint = this.context.config.endpoints.completion;
-  const response = await fetch(endpoint);
-  const data = await response.json();
-
-  const webhookOptions = (data.webhook || []).map((webhook: any) => ({
-    name: webhook.name,
-    value: webhook.name,
-    id: webhook.name,
-    label: webhook.name,
-    body: webhook.body
-  }));
-
-  if (this.state.method.value.value === Methods.FUNCTION && this.state.url.value) {
-    const functionName = this.state.url.value;
-    const selectedOption = webhookOptions.find((opt: any) => opt.name === functionName);
-
-    this.setState({
-      webhookOptions,
-      webhookFunction: { value: selectedOption || null }
-    });
-  } else {
-    this.setState({ webhookOptions });
-  }
+  try {
+    const endpoint = this.context.config.endpoints.completion;
+    const response = await fetch(endpoint);
+    
+    if (!response.ok) {
+      console.error('Failed to fetch webhook options:', response.statusText);
+      return;
+    }
+    
+    const data = await response.json();
+    const webhookOptions = (data.webhook || []).map((webhook: any) => ({
+      name: webhook.name,
+      value: webhook.name,
+      id: webhook.name,
+      label: webhook.name,
+      body: webhook.body
+    }));
+
+    if (this.state.method.value.value === Methods.FUNCTION && this.state.url.value) {
+      const functionName = this.state.url.value;
+      const selectedOption = webhookOptions.find((opt: any) => opt.name === functionName);
+
+      this.setState({
+        webhookOptions,
+        webhookFunction: { value: selectedOption || null }
+      });
+    } else {
+      this.setState({ webhookOptions });
+    }
+  } catch (error) {
+    console.error('Error loading webhook options:', error);
+  }
 }
🤖 Prompt for AI Agents
In src/components/flow/routers/webhook/WebhookRouterForm.tsx around lines 77 to
101, the async fetch has no error handling or loading state; wrap the fetch and
JSON parse in a try/catch/finally, set a loading flag in state before the
request and clear it in finally, check response.ok and handle non-200 responses
by throwing or setting an error state, and on error set webhookOptions to an
empty array (and webhookFunction to null if applicable) so the component remains
stable; also optionally store the error message in state for UI/display.

@akanshaaa19 akanshaaa19 merged commit 0125720 into glific-master Nov 10, 2025
7 checks passed
@akanshaaa19 akanshaaa19 deleted the dropdown_for_webhooks branch November 10, 2025 18:18
This was referenced Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants