Skip to content

Comments

feat: allow inserting webhook variables into custom payload template#22835

Merged
CarinaWolli merged 9 commits intocalcom:mainfrom
keerthikumanduri:custom-payload-guide
Aug 11, 2025
Merged

feat: allow inserting webhook variables into custom payload template#22835
CarinaWolli merged 9 commits intocalcom:mainfrom
keerthikumanduri:custom-payload-guide

Conversation

@keerthikumanduri
Copy link
Contributor

What does this PR do?

This PR adds a option to add webhook variables in the custom webhook field section by introducing a dropdown with the webhook variables (found in docs) that can be inserted into the custom payload text area with a click.

Video Demo (if applicable):

Before:
Screenshot 2025-07-31 at 12 15 20 PM

After:
https://www.loom.com/share/c9cebe0d78f842659958fddead627b95?sid=51820dfd-4db7-46b2-a8e6-13300d190747

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

@vercel
Copy link

vercel bot commented Jul 31, 2025

@keerthikumanduri is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLAassistant commented Jul 31, 2025

CLA assistant check
All committers have signed the CLA.

@graphite-app graphite-app bot requested a review from a team July 31, 2025 06:51
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Jul 31, 2025
@github-actions github-actions bot added Low priority Created by Linear-GitHub Sync webhooks area: webhooks, callback, webhook payload ✨ feature New feature or request 🧹 Improvements Improvements to existing features. Mostly UX/UI labels Jul 31, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 31, 2025

Walkthrough

This update to the WebhookForm component introduces a categorized list of available template variables for webhook payloads, defined in a new constant. It adds a helper function for inserting or updating variables within a JSON-formatted payload template string. The form interface now includes a toggleable section to display these variables, allowing users to insert them directly into the payload template textarea, which has been expanded from 3 to 8 rows and given a placeholder of {}. The changes are contained within the same file and focus on improving the custom payload editing experience by providing interactive guidance.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Assessment against linked issues

Objective Addressed Explanation
Add structure and guidance for defining custom payload in webhook form (#18407, CAL-4974)
Add placeholder in the custom payload input to reduce user confusion (#18407, CAL-4974)
Provide a list or reference of available variables for custom payloads (#18407, CAL-4974)
Enable direct insertion of template variables into the custom payload (#18407, CAL-4974)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes were found.

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d13e8e and a9ed03f.

📒 Files selected for processing (1)
  • apps/web/public/static/locales/en/common.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/public/static/locales/en/common.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Codacy Static Code Analysis
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dosubot dosubot bot added the ui area: UI, frontend, button, form, input label Jul 31, 2025
@dosubot dosubot bot added this to the v5.6 milestone Jul 31, 2025
@graphite-app
Copy link

graphite-app bot commented Jul 31, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (07/31/25)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add community label" took an action on this PR • (07/31/25)

1 label was added to this PR based on Keith Williams's automation.

"Add ready-for-e2e label" took an action on this PR • (08/11/25)

1 label was added to this PR based on Keith Williams's automation.

Copy link
Contributor

@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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0cc2367 and a8a4064.

📒 Files selected for processing (1)
  • packages/features/webhooks/components/WebhookForm.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/webhooks/components/WebhookForm.tsx
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/webhooks/components/WebhookForm.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check for E2E label
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (5)
packages/features/webhooks/components/WebhookForm.tsx (5)

76-210: Well-structured webhook variables constant with comprehensive coverage.

The WEBHOOK_VARIABLES constant provides a well-organized categorization of available webhook template variables with clear descriptions and proper typing information. The structure facilitates easy UI rendering and user understanding.


281-300: Robust JSON template insertion logic with good error handling.

The insertVariableIntoTemplate function handles multiple scenarios well:

  • Valid JSON parsing and formatting
  • Empty/minimal JSON handling
  • Partial JSON string manipulation
  • Proper comma insertion logic

The implementation correctly handles edge cases like empty strings, malformed JSON, and maintains proper JSON formatting.


302-302: State management for variable visibility toggle looks good.

The showVariables state is properly initialized and will be used to control the visibility of the variables list.


501-510: Enhanced textarea configuration improves user experience.

The expanded textarea (8 rows instead of 3) and {} placeholder provide better visual space and guidance for users creating custom payload templates.


526-536: Variable insertion logic correctly integrates with form state.

The click handler properly:

  • Retrieves current payload template value
  • Uses the helper function to insert the variable
  • Updates the form state with shouldDirty: true

This ensures the form correctly tracks changes and enables the save button.

Copy link
Contributor

@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

♻️ Duplicate comments (2)
packages/features/webhooks/components/WebhookForm.tsx (2)

512-514: Use localization for button text.

The button text is hardcoded instead of using the t() function for localization.

-                  <Button type="button" color="secondary" onClick={() => setShowVariables(!showVariables)}>
-                    {showVariables ? t("Hide Variables") : t("Show Available Variables")}
-                  </Button>
+                  <Button type="button" color="secondary" onClick={() => setShowVariables(!showVariables)}>
+                    {showVariables ? t("hide_variables") : t("show_available_variables")}
+                  </Button>

516-547: Variable insertion UI needs localization and accessibility improvements.

Multiple issues identified:

  1. Localization violations: Category names, descriptions, and "Click to add to template" text are hardcoded
  2. Accessibility: Missing proper ARIA labels and keyboard navigation support
  3. Styling: Hardcoded color classes should use design system tokens

Apply these critical localization fixes:

-                          <h4 className="mb-2 text-sm font-medium">{category}</h4>
+                          <h4 className="mb-2 text-sm font-medium">{t(category.toLowerCase().replace(/ /g, '_'))}</h4>
-                                <div className="text-muted mt-1 text-xs">{description}</div>
+                                <div className="text-muted mt-1 text-xs">{t(description.toLowerCase().replace(/ /g, '_'))}</div>
-                                <div className="text-muted mt-1 text-xs">{t("Click to add to template")}</div>
+                                <div className="text-muted mt-1 text-xs">{t("click_to_add_to_template")}</div>

Additionally:

  • Add role="button" and tabIndex={0} to clickable elements
  • Add keyboard event handlers for Enter/Space keys
  • Replace hardcoded text-white with appropriate design system class
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8a4064 and 95cfd37.

📒 Files selected for processing (1)
  • packages/features/webhooks/components/WebhookForm.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/webhooks/components/WebhookForm.tsx
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/webhooks/components/WebhookForm.tsx
🧠 Learnings (3)
📚 Learning: applies to **/*.tsx : always use `t()` for text localization in frontend code; direct text embedding...
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: Applies to **/*.tsx : Always use `t()` for text localization in frontend code; direct text embedding should trigger a warning

Applied to files:

  • packages/features/webhooks/components/WebhookForm.tsx
📚 Learning: in signup-view.tsx, when checking if redirecturl contains certain strings, using explicit && checks ...
Learnt from: Anshumancanrock
PR: calcom/cal.com#22570
File: apps/web/modules/signup-view.tsx:253-253
Timestamp: 2025-07-21T21:33:23.371Z
Learning: In signup-view.tsx, when checking if redirectUrl contains certain strings, using explicit && checks (redirectUrl && redirectUrl.includes()) is preferred over optional chaining (redirectUrl?.includes()) to ensure the result is always a boolean rather than potentially undefined. This approach provides cleaner boolean contracts for downstream conditional logic.

Applied to files:

  • packages/features/webhooks/components/WebhookForm.tsx
📚 Learning: when making localization changes for new features, it's often safer to add new strings rather than m...
Learnt from: bandhan-majumder
PR: calcom/cal.com#22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.

Applied to files:

  • packages/features/webhooks/components/WebhookForm.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests / Unit
  • GitHub Check: Type check / check-types
  • GitHub Check: Linters / lint
🔇 Additional comments (4)
packages/features/webhooks/components/WebhookForm.tsx (4)

76-210: LGTM! Well-structured webhook variables definition.

The WEBHOOK_VARIABLES constant is well-organized with clear categorization and comprehensive documentation. The structure with category, variables, and detailed metadata (name, variable, type, description) provides excellent developer experience.


281-300: Robust JSON template insertion function with good error handling.

The insertVariableIntoTemplate function handles multiple scenarios well:

  • Valid JSON parsing and formatting
  • Empty/default object initialization
  • Graceful fallback for malformed JSON
  • Proper comma handling for JSON structure

The implementation correctly maintains JSON formatting with proper indentation.


302-302: LGTM! State management for variables visibility.

The showVariables state is appropriately added to control the visibility of the webhook variables section.


501-510: Good improvements to the textarea component.

The changes enhance the user experience:

  • Increased rows from 3 to 8 provides better visibility
  • Added helpful placeholder {\n\n} guides users on JSON structure
  • Proper form integration maintained

Comment on lines +526 to +536
onClick={() => {
const currentValue = formMethods.getValues("payloadTemplate") || "{}";
const updatedValue = insertVariableIntoTemplate(
currentValue,
name,
variable
);
formMethods.setValue("payloadTemplate", updatedValue, {
shouldDirty: true,
});
}}>
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify template insertion functionality.

The variable insertion logic looks correct, but ensure that the JSON structure is maintained properly when multiple variables are added sequentially.


🏁 Script executed:

#!/bin/bash
# Description: Check if there are any existing tests for the insertVariableIntoTemplate function
# Expected: Find test files that verify the JSON template insertion functionality

echo "Searching for test files related to webhook template insertion..."
rg -l "insertVariableIntoTemplate|webhook.*template" --type test

echo "Searching for webhook form test files..."
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx | xargs rg -l "WebhookForm"

echo "Checking for existing webhook payload template tests..."
rg -A 5 -B 5 "payloadTemplate.*test" 

Length of output: 564


🏁 Script executed:

#!/bin/bash
set -e

echo "1. Locating definition of insertVariableIntoTemplate..."
rg -n "insertVariableIntoTemplate" -g '*.ts' -g '*.tsx'

echo
echo "2. Searching for tests referencing insertVariableIntoTemplate..."
rg -n "insertVariableIntoTemplate" -g '*.spec.ts*' -g '*.test.ts*' || true

echo
echo "3. Identifying directory of the function to look for nearby tests..."
func_file=$(rg -l "insertVariableIntoTemplate" -g '*.ts' -g '*.tsx' | head -n1)
echo "Function file: $func_file"

if [ -n "$func_file" ]; then
  search_dir=$(dirname "$func_file")
  echo
  echo "4. Listing any test files in $search_dir..."
  find "$search_dir" -type f \( -name '*.spec.ts' -o -name '*.spec.tsx' -o -name '*.test.ts' -o -name '*.test.tsx' \) -print

  echo
  echo "5. Searching those tests for payloadTemplate usage..."
  find "$search_dir" -type f \( -name '*.spec.ts' -o -name '*.spec.tsx' -o -name '*.test.ts' -o -name '*.test.tsx' \) -print0 \
    | xargs -0 grep -H "payloadTemplate" || true
fi

Length of output: 1946


Add unit tests for JSON template insertion
There’s currently no test coverage for the insertVariableIntoTemplate helper, which lives in packages/features/webhooks/components/WebhookForm.tsx. To ensure the JSON structure remains valid—especially when inserting multiple variables in sequence—please add focused tests that cover:

  • Inserting into an empty template ("{}")
  • Single-variable insertion
  • Multiple insertions back-to-back
  • Edge cases (e.g. reserved characters, nested braces)
  • Round-trip parsing (assert JSON.parse(insertedString) succeeds)

Suggested locations:

  • Create a new spec alongside the component, e.g.
    packages/features/webhooks/components/WebhookForm.spec.ts
  • Import and unit-test insertVariableIntoTemplate directly
🤖 Prompt for AI Agents
In packages/features/webhooks/components/WebhookForm.tsx around lines 526 to
536, there are no unit tests for the insertVariableIntoTemplate helper function.
To fix this, create a new test file named WebhookForm.spec.ts in the same
directory. Import insertVariableIntoTemplate into this test file and write
focused unit tests covering inserting into an empty template ("{}"),
single-variable insertion, multiple sequential insertions, edge cases like
reserved characters and nested braces, and verify that the output string can be
parsed by JSON.parse without errors.

Copy link
Contributor

@Devanshusharma2005 Devanshusharma2005 left a comment

Choose a reason for hiding this comment

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

PR looks good. but lets wait for @CarinaWolli review too.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
apps/web/public/static/locales/en/common.json (1)

3420-3444: Standardize wording & refine a couple of variable descriptions

All new keys are syntactically valid JSON – great.
Tiny copy-editing tweaks will keep the doc-strings uniform and easier for translators:

-"webhook_reschedule_uid": "The UID for rescheduling",
+"webhook_reschedule_uid": "The UID of the rescheduled booking",

-"webhook_type": "The event type slug",
+"webhook_type": "The event-type slug",

-"webhook_video_call_url": "Video call URL for the meeting",
+"webhook_video_call_url": "Video-call URL for the meeting",

This aligns tense/possessive usage with neighbouring strings (“event’s start time”, “organizer’s email” etc.) and removes a minor plural-noun clash.
No functional impact – purely polish.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95cfd37 and 79190ca.

📒 Files selected for processing (2)
  • apps/web/public/static/locales/en/common.json (1 hunks)
  • packages/features/webhooks/components/WebhookForm.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/features/webhooks/components/WebhookForm.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: when making localization changes for new features, it's often safer to add new strings rather than m...
Learnt from: bandhan-majumder
PR: calcom/cal.com#22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.

Applied to files:

  • apps/web/public/static/locales/en/common.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache

Copy link
Member

@CarinaWolli CarinaWolli left a comment

Choose a reason for hiding this comment

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

Just some more missing translations. Everything else works great

@CarinaWolli CarinaWolli enabled auto-merge (squash) August 11, 2025 07:16
@CarinaWolli CarinaWolli merged commit 1fa8a5e into calcom:main Aug 11, 2025
52 of 57 checks passed
@github-actions
Copy link
Contributor

E2E results are ready!

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

Labels

community Created by Linear-GitHub Sync ✨ feature New feature or request 🧹 Improvements Improvements to existing features. Mostly UX/UI Low priority Created by Linear-GitHub Sync ready-for-e2e ui area: UI, frontend, button, form, input webhooks area: webhooks, callback, webhook payload

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CAL-4974] Add custom payload Input format

4 participants