Skip to content

feat: add zapier no-show support#28927

Closed
thegreatalxx wants to merge 1 commit into
calcom:mainfrom
thegreatalxx:main
Closed

feat: add zapier no-show support#28927
thegreatalxx wants to merge 1 commit into
calcom:mainfrom
thegreatalxx:main

Conversation

@thegreatalxx
Copy link
Copy Markdown

Adds a new listNoShowBookings endpoint and exports it to the Zapier API to support no-show triggers. Updated documentation and app metadata to include no-show event support. Fixes #18992.

@github-actions
Copy link
Copy Markdown
Contributor

Welcome to Cal.diy, @thegreatalxx! Thanks for opening this pull request.

A few things to keep in mind:

  • This is Cal.diy, not Cal.com. Cal.diy is a community-driven, fully open-source fork of Cal.com licensed under MIT. Your changes here will be part of Cal.diy — they will not be deployed to the Cal.com production app.
  • Please review our Contributing Guidelines if you haven't already.
  • Make sure your PR title follows the Conventional Commits format.

A maintainer will review your PR soon. Thanks for contributing!

@github-actions github-actions Bot added app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar ✨ feature New feature or request labels Apr 18, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

📝 Walkthrough

Walkthrough

This pull request extends the Zapier integration with support for no-show booking events. Changes include updating documentation and configuration files (DESCRIPTION.md, README.md, _metadata.ts, config.json) to list "no-show" as an additional booking-event trigger type. A new API route listNoShowBookings is implemented in packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts, which validates API key authorization with READ_BOOKING permission, derives scope based on userId or teamId context, queries the database for recent no-show bookings, and returns results formatted as webhook-style responses with the trigger event set to BOOKING_NO_SHOW_UPDATED. The endpoint is exported and wired as a GET route using the default handler pattern.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add zapier no-show support' clearly and concisely summarizes the main change—adding no-show support to the Zapier integration.
Description check ✅ Passed The description directly relates to the changeset, explaining the addition of the listNoShowBookings endpoint and updates to documentation and metadata for no-show support.
Linked Issues check ✅ Passed The PR successfully implements the requirement from issue #18992 to add no-show support to Zapier by creating a new listNoShowBookings endpoint and updating all relevant documentation and metadata.
Out of Scope Changes check ✅ Passed All changes are directly related to adding no-show support to Zapier: new API endpoint, documentation updates, metadata changes, and configuration adjustments. No out-of-scope modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts`:
- Around line 11-13: The endpoint currently calls validateAccountOrApiKey and
only requests the "READ_BOOKING" permission but then returns profile fields
(user/attendee names, emails, time zones); update the authorization to require
both "READ_BOOKING" and "READ_PROFILE" (mirror listBookings) by changing the
permissions array passed to validateAccountOrApiKey in listNoShowBookings.ts
(the destructured result assigned to authorizedAccount and validKey) so that
profile fields are only returned when READ_PROFILE is granted, or alternatively
strip profile fields if READ_PROFILE is absent—ensure the check location uses
validateAccountOrApiKey and the behavior matches listBookings.
- Line 4: The query that builds the no-show sample list in listNoShowBookings.ts
currently returns bookings where noShowHost or attendee.noShow is set but does
not restrict by booking status; update the query to include status:
BookingStatus.ACCEPTED so only accepted bookings are returned. Locate the query
construction in listNoShowBookings (and related blocks around lines ~18-28) and
add the BookingStatus.ACCEPTED filter (using the BookingStatus enum) alongside
the existing noShowHost / attendee.noShow conditions so the results match the
no-show trigger eligibility.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7315c20-d814-4e64-843a-02e91585e7d0

📥 Commits

Reviewing files that changed from the base of the PR and between 9efd0e6 and f5fd64e.

📒 Files selected for processing (6)
  • packages/app-store/zapier/DESCRIPTION.md
  • packages/app-store/zapier/README.md
  • packages/app-store/zapier/_metadata.ts
  • packages/app-store/zapier/api/index.ts
  • packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts
  • packages/app-store/zapier/config.json

import type { NextApiRequest, NextApiResponse } from "next";

import prisma from "@calcom/prisma";
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
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.

⚠️ Potential issue | 🟠 Major

Filter no-show samples to accepted bookings.

The query currently returns any booking with noShowHost or attendee noShow, including cancelled/rejected/pending bookings if those flags remain set. Add status: BookingStatus.ACCEPTED so this list mirrors actual no-show trigger eligibility.

🛠️ Proposed fix
-import { WebhookTriggerEvents } from "@calcom/prisma/enums";
+import { BookingStatus, WebhookTriggerEvents } from "@calcom/prisma/enums";
@@
   const where = teamId
     ? {
+        status: BookingStatus.ACCEPTED,
         eventType: {
           OR: [{ teamId }, { parent: { teamId } }],
         },
         OR: [{ noShowHost: true }, { attendees: { some: { noShow: true } } }],
       }
     : {
+        status: BookingStatus.ACCEPTED,
         eventType: { userId },
         OR: [{ noShowHost: true }, { attendees: { some: { noShow: true } } }],
       };

Based on learnings, all side effects including no-show triggers are gated on booking.status === ACCEPTED.

Also applies to: 18-28

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts` at line 4,
The query that builds the no-show sample list in listNoShowBookings.ts currently
returns bookings where noShowHost or attendee.noShow is set but does not
restrict by booking status; update the query to include status:
BookingStatus.ACCEPTED so only accepted bookings are returned. Locate the query
construction in listNoShowBookings (and related blocks around lines ~18-28) and
add the BookingStatus.ACCEPTED filter (using the BookingStatus enum) alongside
the existing noShowHost / attendee.noShow conditions so the results match the
no-show trigger eligibility.

Comment on lines +11 to +13
const { account: authorizedAccount, appApiKey: validKey } = await validateAccountOrApiKey(req, [
"READ_BOOKING",
]);
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.

⚠️ Potential issue | 🟠 Major

Require profile read permission before returning profile fields.

This endpoint authorizes only READ_BOOKING, but returns user and attendee names/emails/time zones. The existing listBookings endpoint requires both READ_BOOKING and READ_PROFILE before returning attendee email, so this should keep the same permission boundary.

🔐 Proposed fix
   const { account: authorizedAccount, appApiKey: validKey } = await validateAccountOrApiKey(req, [
     "READ_BOOKING",
+    "READ_PROFILE",
   ]);

Also applies to: 51-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts` around
lines 11 - 13, The endpoint currently calls validateAccountOrApiKey and only
requests the "READ_BOOKING" permission but then returns profile fields
(user/attendee names, emails, time zones); update the authorization to require
both "READ_BOOKING" and "READ_PROFILE" (mirror listBookings) by changing the
permissions array passed to validateAccountOrApiKey in listNoShowBookings.ts
(the destructured result assigned to authorizedAccount and validKey) so that
profile fields are only returned when READ_PROFILE is granted, or alternatively
strip profile fields if READ_PROFILE is absent—ensure the check location uses
validateAccountOrApiKey and the behavior matches listBookings.

@Qodo-Free-For-OSS
Copy link
Copy Markdown

Hi, listNoShowBookings returns booking.metadata verbatim, which can include arbitrary keys and values and is broader than the sanitized metadata returned by the existing Zapier booking listing logic. This can leak unintended internal metadata to Zapier consumers and makes the payload inconsistent across booking-related triggers.

Severity: action required | Category: security

How to fix: Sanitize booking metadata output

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts returns booking.metadata raw, which can contain arbitrary keys (per bookingMetadataSchema) and is broader than the sanitized metadata returned by Zapier’s existing booking listing behavior.

Issue Context

The existing Zapier booking listing path (packages/features/webhooks/lib/scheduleTrigger.ts -> listBookings) parses metadata and only returns a safe subset. The new no-show listing should align with that contract.

Fix Focus Areas

  • packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts[30-95]
  • packages/features/webhooks/lib/scheduleTrigger.ts[182-270]
  • packages/prisma/zod-utils.ts[460-467]

Implementation notes

  • Reuse the same normalization as listBookings (parse metadata and return only safe keys like videoCallUrl).
  • Consider extracting a shared “Zapier booking projection/normalizer” to avoid divergence across endpoints.

We noticed a couple of other issues in this PR as well - happy to share if helpful.


Found by Qodo code review

@github-actions
Copy link
Copy Markdown
Contributor

This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active.

@github-actions github-actions Bot added the Stale label Apr 27, 2026
@Qodo-Free-For-OSS
Copy link
Copy Markdown

Hi, listNoShowBookings returns triggerEvent: BOOKING_NO_SHOW_UPDATED but wraps the full booking under payload.booking, which does not match the no-show webhook payload shape used by the webhook system for this trigger. This will make Zapier trigger “test/sample data” differ from real BOOKING_NO_SHOW_UPDATED webhook deliveries and can break Zaps built from the sample schema.

Severity: action required | Category: correctness

How to fix: Return standard no-show payload

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

GET /api/integrations/zapier/listNoShowBookings returns triggerEvent: BOOKING_NO_SHOW_UPDATED but uses a booking-shaped payload (payload.booking). The webhook ecosystem expects a no-show payload for this trigger: { message, bookingUid, bookingId?, attendees }.

Issue Context

Zapier uses these list endpoints to fetch sample data / polling results. If the sample payload differs from the real webhook payload, users will build Zaps against the wrong schema.

Fix Focus Areas

  • packages/app-store/zapier/api/subscriptions/listNoShowBookings.ts[87-95]

What to change

  • Replace payload: { booking } with the standard no-show payload fields:
    • bookingUid: booking.uid
    • bookingId: (if selected; add id` to the select if needed)
    • attendees: booking.attendees.filter(...).map(({ email, noShow }) => ({ email, noShow: !!noShow }))
    • message: <some consistent message> (or fetch/construct similarly to the existing no-show webhook emitter)
  • If you need bookingId, add id: true to the Prisma select.
  • Keep createdAt semantics consistent (currently updatedAt ?? createdAt).

Found by Qodo. Free code review for open-source maintainers.

@github-actions github-actions Bot removed the Stale label Apr 28, 2026
@romitg2
Copy link
Copy Markdown
Member

romitg2 commented Apr 30, 2026

we've decided to close the issue.

@romitg2 romitg2 closed this Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar ✨ feature New feature or request size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CAL-5107] add no-show to zapier (its a webhook only right now)

3 participants