Skip to content

feat(webhook): add variable selector to response body field#32919

Open
abesticode wants to merge 10 commits intolanggenius:mainfrom
abesticode:feat/webhook-trigger-variable-selector
Open

feat(webhook): add variable selector to response body field#32919
abesticode wants to merge 10 commits intolanggenius:mainfrom
abesticode:feat/webhook-trigger-variable-selector

Conversation

@abesticode
Copy link
Copy Markdown
Contributor

Summary

This PR enhances the Webhook Trigger node by enabling a variable selector for the Response Body field, allowing users to dynamically reference incoming request data without manually typing variable paths.

Problem

Previously, the Response Body field in the webhook trigger node was a plain text input. Users had to manually type variable placeholders (e.g., {{req_body_params.name}}), which was error-prone and not discoverable. Additionally, the webhook trigger's own variables (req_body_params, req_query_params, req_header_params) were not available in the workflow variable selector.

Changes

  • Frontend — Replaced the plain textarea with InputWithVar component in the trigger-webhook panel, enabling the variable selector dropdown in the Response Body field.
  • Frontend — Exposed req_body_params, req_query_params, and req_header_params as a dedicated variable group within the webhook trigger node so they appear alongside system variables in the selector.
  • Frontend — Fixed the variable group structure (selector paths and type schema) to pass the workflow editor's schema validation, preventing mapping errors on load.
  • Backend — Added _interpolate_variables to WebhookService to resolve {{namespace.key}} placeholders in the response body at runtime, supporting both the plain format ({{req_body_params.field}}) and the workflow-editor format ({{#nodeId.namespace.key#}}). Unresolvable placeholders are left unchanged.
  • Backend — Added Args/Returns docstring to _interpolate_variables for consistency with the rest of the service.

Screenshots

Before After
image image

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint and make type-check (backend) and cd web && npx lint-staged (frontend) to appease the lint gods

- Integrate InputWithVar component in trigger-webhook panel for response body
- Expose req_body_params, req_query_params, and req_header_params as selectable
  variables in the webhook trigger node's own variable group
- Fix variable group structure to pass schema validation in the workflow editor
- Add _interpolate_variables to resolve {{namespace.key}} placeholders at
  response time, supporting both plain and workflow-editor {{#nodeId.ns.key#}} formats
- Add docstring (Args/Returns) to _interpolate_variables for consistency
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 3, 2026
@github-actions github-actions bot added the web This relates to changes on the web. label Mar 3, 2026
@dosubot dosubot bot added the 💪 enhancement New feature or request label Mar 3, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the usability of the Webhook Trigger node by introducing dynamic variable selection for its response body. Previously, users had to manually construct variable paths, which was error-prone. The changes integrate a variable selector into the frontend and implement a robust backend interpolation mechanism, allowing for seamless and dynamic customization of webhook responses based on incoming request data.

Highlights

  • Dynamic Variable Selection for Webhook Response Body: The Webhook Trigger node now supports a variable selector in the Response Body field, allowing users to dynamically insert data from incoming requests (body, query, headers) without manual typing.
  • Backend Variable Interpolation: A new backend utility _interpolate_variables was added to WebhookService to resolve {{namespace.key}} and {{#nodeId.namespace.key#}} placeholders in the response body at runtime, ensuring dynamic content is correctly rendered.
  • Enhanced Frontend Variable Availability: Webhook trigger's own variables (req_body_params, req_query_params, req_header_params) are now exposed as a dedicated variable group within the workflow editor's variable selector, improving discoverability and usability.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • api/controllers/trigger/webhook.py
    • Updated handle_webhook and handle_webhook_debug to pass webhook_data to WebhookService.generate_webhook_response.
  • api/services/trigger/webhook_service.py
    • Modified generate_webhook_response method signature to accept an optional webhook_data parameter.
    • Implemented variable interpolation in generate_webhook_response by calling the new _interpolate_variables method before parsing the response body.
    • Added a new private method _interpolate_variables to handle the replacement of {{...}} placeholders in a given template string with values from webhook_data.
    • Updated the generic except: block to except Exception: for better error handling.
  • web/app/components/workflow/nodes/trigger-webhook/panel.tsx
    • Imported necessary components and hooks including useWorkflow, useAvailableVarList, InputWithVar, and VarType.
    • Removed the ParagraphInput component import.
    • Introduced logic to construct selfOutputVars from the webhook's own output variables, making req_body_params, req_query_params, and req_header_params available in the variable selector.
    • Adjusted availableVars and availableNodes to include the webhook trigger's self-output variables for proper display in the variable selector.
    • Replaced the plain ParagraphInput component with InputWithVar for the response body field, enabling the variable selection dropdown.
Activity
  • The pull request introduces new features and backend logic, indicating initial development and implementation work.
  • No specific human activity (comments, reviews) has been recorded in the provided context.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

No changes detected.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the Webhook Trigger node by adding a variable selector to the response body field, improving usability by allowing dynamic data from the request to be easily referenced. However, the current implementation is vulnerable to JSON injection. The interpolation logic performs raw string substitution without context-aware escaping, which could allow an attacker to manipulate the JSON response structure through malicious input in the webhook request. While the backend implementation for variable interpolation is solid and frontend changes correctly integrate webhook variables, there is a minor suggestion regarding Python import conventions.

Comment thread api/services/trigger/webhook_service.py Outdated
- Move import re to top-level imports per PEP 8
- Fix JSON injection in _interpolate_variables: string values are now
  JSON-escaped when the response body template is a JSON structure
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 14:12:42.861884680 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 14:12:35.094896039 +0000
@@ -1272,7 +1272,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 14:21:40.245267112 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 14:21:32.153198165 +0000
@@ -1272,7 +1272,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

abesticode and others added 2 commits March 3, 2026 21:31
Sort output-vars (components) before use-available-var-list (hooks)
to comply with eslint import/order rule.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 14:32:56.630973296 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 14:32:48.458931135 +0000
@@ -1272,7 +1272,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 14:33:32.153869095 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 14:33:23.371051510 +0000
@@ -1272,7 +1272,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

abesticode and others added 2 commits March 3, 2026 22:03
- Move InputWithVar (components) before useAvailableVarList (hooks)
  to satisfy eslint import/order rule
- Remove unnecessary parentheses around type assertion on line 95
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 15:04:55.027178883 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 15:04:45.375052942 +0000
@@ -1262,7 +1262,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 15:05:13.115509210 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 15:05:05.346487236 +0000
@@ -1262,7 +1262,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

Group all _base/components/* (field, output-vars, prompt/editor, split)
before _base/hooks/* (use-available-var-list) per eslint import/order rule
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-03 15:16:42.335441478 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-03 15:16:33.013456912 +0000
@@ -1262,7 +1262,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

@abesticode
Copy link
Copy Markdown
Contributor Author

Hi @Yeuoly , I’ve submitted this PR to enhance the Webhook Trigger node by adding a variable selector for the Response Body. This should make it much easier for users to reference request data dynamically.

Could you please take a look when you have a moment? I've ensured it passes schema validation and includes backend interpolation. Thanks!

@abesticode
Copy link
Copy Markdown
Contributor Author

/gemini review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-04 21:48:26.762577061 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-04 21:48:18.440601863 +0000
@@ -1262,7 +1262,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully enhances the Webhook Trigger node by integrating a variable selector into the Response Body field. The backend now supports variable interpolation within the response body, handling both plain {{namespace.key}} and workflow-editor {{#nodeId.namespace.key#}} formats. The frontend changes correctly replace the plain textarea with an InputWithVar component and expose webhook-specific variables for selection. The overall implementation addresses the problem of manual variable entry, making the feature more user-friendly and less error-prone.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-03-05 02:26:24.020168853 +0000
+++ /tmp/pyrefly_pr.txt	2026-03-05 02:26:16.171138632 +0000
@@ -1262,7 +1262,7 @@
 ERROR Argument `Mapping[str, str] | dict[LaxStr, LaxStr]` is not assignable to parameter `credentials` with type `Mapping[LaxStr, LaxStr]` in function `core.trigger.entities.api_entities.SubscriptionBuilderApiEntity.__init__` [bad-argument-type]
    --> services/trigger/trigger_subscription_builder_service.py:385:25
 ERROR Argument `dict[str, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `services.workflow.entities.WebhookTriggerData.__init__` [bad-argument-type]
-   --> services/trigger/webhook_service.py:756:28
+   --> services/trigger/webhook_service.py:757:28
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Object of class `dict` has no attribute `encode`
 ERROR Argument `Mapping[str, Any] | dict[LaxStr, Any]` is not assignable to parameter `inputs` with type `Mapping[LaxStr, Any]` in function `core.app.entities.task_entities.Data.__init__` [bad-argument-type]

@abesticode
Copy link
Copy Markdown
Contributor Author

Gentle ping to @iamjoel and @Mairuis for a review on this enhancement. It aims to simplify how users reference webhook data. I've already ensured it passes the schema validation. Let me know if there's anything I should adjust!

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

Labels

💪 enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files. web This relates to changes on the web.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant