Skip to content

fix(office365video): use PATCH for updateMeeting and implement deleteMeeting#29508

Open
NamanYadav11 wants to merge 1 commit into
calcom:mainfrom
NamanYadav11:fix/teams-update-delete-meeting
Open

fix(office365video): use PATCH for updateMeeting and implement deleteMeeting#29508
NamanYadav11 wants to merge 1 commit into
calcom:mainfrom
NamanYadav11:fix/teams-update-delete-meeting

Conversation

@NamanYadav11
Copy link
Copy Markdown

What does this PR do?

Fixes #29498

The Office 365 Video (MS Teams) adapter had two broken methods:

1. updateMeeting created duplicates on every reschedule

It was calling POST /onlineMeetings (which creates a new meeting) instead of PATCH /onlineMeetings/{meetingId} (which updates the existing one). Every time a user rescheduled a booking, a brand-new Teams meeting was created and the old one was left orphaned.

2. deleteMeeting was a no-op

The implementation was return Promise.resolve([]) — it never made an HTTP request, so the remote Teams meeting stayed alive after the booking was deleted on the Cal side.

Both methods now call the correct Microsoft Graph API endpoints using the meeting ID that's already stored in the booking reference.

Visual Demo (For contributors especially)

N/A — backend adapter fix.

Before reschedule: two Teams meetings visible in the organizer's Teams calendar (original + duplicate).

After: only one meeting, updated with the new time.

Before cancel: Teams meeting stays active after booking is deleted.

After: Teams meeting is removed via DELETE /onlineMeetings/{id}.

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 if this PR makes changes that would require a documentation change. N/A.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works. Updated existing updateMeeting tests (they were asserting the broken POST behavior) and added a full deleteMeeting test suite.

How should this be tested?

Requires an Office 365 / MS Teams account connected to Cal.

Reschedule path:

  1. Create a booking with MS Teams as the conferencing provider
  2. Reschedule the booking to a different time
  3. Expected: the existing Teams meeting is updated (single meeting in Teams calendar); before this fix a second meeting was created

Cancellation path:

  1. Cancel a booking with a Teams meeting attached
  2. Expected: the Teams meeting is deleted from the calendar; before this fix it remained active

Unit tests:

  • yarn vitest packages/app-store/office365video — all tests pass

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • My PR is too large (>500 lines or >10 files) and should be split into smaller PRs

…Meeting

updateMeeting was calling POST /onlineMeetings, creating a new meeting on
every reschedule instead of updating the existing one via PATCH.
deleteMeeting was a no-op that returned an empty array without making any
HTTP request, leaving the remote Teams meeting alive after deletion.

Also updates existing updateMeeting tests (which were asserting the broken
POST behavior) and adds deleteMeeting tests covering success, 404, and error.

Fixes calcom#29498
@github-actions github-actions Bot added the 🐛 bug Something isn't working label Jun 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Welcome to Cal.diy, @NamanYadav11! 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!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates the Office365 Teams video adapter to properly handle meeting lifecycle operations. The updateMeeting method now validates that a meetingId is present in the booking reference and performs a PATCH request to update an existing online meeting instead of creating a new one. The deleteMeeting method replaces a previous no-op implementation with a real DELETE request that treats 404 responses as idempotent success. Tests verify both success paths with correct HTTP methods and endpoints, error handling including missing IDs and server failures, and proper response parsing.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the two main changes: using PATCH for updateMeeting and implementing deleteMeeting, matching the core fixes in the changeset.
Description check ✅ Passed The description comprehensively explains what was broken, why it matters, what the fix does, how to test it, and confirms automated tests are in place—fully related to the changeset.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #29498: updateMeeting now uses PATCH to update existing meetings, deleteMeeting now sends DELETE requests, and both use the stored meetingId from the booking reference.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the two broken methods in VideoApiAdapter and updating/adding corresponding tests—no out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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: 1

🤖 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 `@packages/app-store/office365video/lib/VideoApiAdapter.ts`:
- Around line 233-236: Replace uses of HttpError in the new non‑tRPC error
branches with ErrorWithCode: add imports "ErrorCode" and "ErrorWithCode" from
"`@calcom/lib/errorCodes`" and "`@calcom/lib/errors`" respectively, then change
throws like the ones in VideoApiAdapter (e.g. the meeting update/delete branches
that currently throw new HttpError(...)) to throw new
ErrorWithCode(ErrorCode.BadRequest, "<message>") or use
ErrorWithCode.Factory.BadRequest("<message>") so all new error paths use
ErrorWithCode instead of HttpError.
🪄 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: 6fd6aacf-5944-4197-8de6-a5d58efc4ec1

📥 Commits

Reviewing files that changed from the base of the PR and between d1ad4ea and 66db7c5.

📒 Files selected for processing (2)
  • packages/app-store/office365video/lib/VideoApiAdapter.test.ts
  • packages/app-store/office365video/lib/VideoApiAdapter.ts

Comment on lines +233 to +236
throw new HttpError({
statusCode: 400,
message: "Meeting ID is required to update a Teams meeting",
});
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 | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify how ErrorWithCode is imported/constructed across the repo,
# then migrate this file's newly added throws consistently.

rg -n --type=ts -C2 '\bErrorWithCode\b'
rg -n --type=ts -C2 'new HttpError\(' packages/app-store/office365video/lib/VideoApiAdapter.ts

Repository: calcom/cal.diy

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/app-store/office365video/lib/VideoApiAdapter.ts"

echo "== Imports in $FILE (first 120 lines) =="
sed -n '1,120p' "$FILE"

echo
echo "== Error usage in $FILE (ErrorWithCode / HttpError) =="
rg -n --type=ts '\bErrorWithCode\b' "$FILE" || true
rg -n --type=ts '\bHttpError\b' "$FILE" || true
rg -n --type=ts 'new HttpError\(' "$FILE" || true

echo
echo "== Relevant sections (around 220-310) =="
sed -n '210,310p' "$FILE"

Repository: calcom/cal.diy

Length of output: 8861


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/app-store/office365video/lib/VideoApiAdapter.ts"

echo "== ErrorWithCode usage in $FILE =="
rg -n --type=ts '\bErrorWithCode\b' "$FILE" || true

echo
echo "== ErrorCode values used in typical ErrorWithCode throws (spot check) =="
ls -1 packages/lib | head -n 50 || true
# Try common errorCodes locations
rg -n --type=ts "enum ErrorCode|export (const )?ErrorCode|ErrorCode\.(BadRequest|InternalServerError|NotFound)" packages/lib/errorCodes* packages/lib/*errorCodes* 2>/dev/null || true
rg -n --type=ts "BadRequest|InternalServerError|NotFound" packages/lib/errorCodes* 2>/dev/null || true

echo
echo "== HttpError definition/contract =="
rg -n --type=ts "export (class|function) HttpError|class HttpError" packages -S -g'*.ts' -g'*.tsx' | head -n 50
if [ -f "packages/lib/http-error.ts" ]; then
  sed -n '1,200p' packages/lib/http-error.ts
elif [ -f "packages/lib/http-error/index.ts" ]; then
  sed -n '1,200p' packages/lib/http-error/index.ts
fi

echo
echo "== How updateMeeting/deleteMeeting errors are consumed (search for office365_video usage) =="
rg -n --type=ts "office365_video" packages | head -n 50

echo
echo "== Call sites for updateMeeting/deleteMeeting =="
rg -n --type=ts "updateMeeting\\s*:\\s*async|updateMeeting\\s*\\(" packages | head -n 50
rg -n --type=ts "deleteMeeting\\s*:\\s*async|deleteMeeting\\s*\\(" packages | head -n 50

echo
echo "== Search for handling of HttpError vs ErrorWithCode near video adapters =="
rg -n --type=ts "instanceof HttpError|instanceof ErrorWithCode" packages/features packages/app-store packages/lib | head -n 80

Repository: calcom/cal.diy

Length of output: 11879


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect how conferencing layer handles errors thrown by video adapters
sed -n '1,220p' packages/features/conferencing/lib/videoClient.ts

echo
echo "== Other VideoApiAdapter implementations using HttpError? =="
rg -n --type=ts "import \\{ HttpError \\} from \"`@calcom/lib/http-error`\"" packages/app-store/*/lib/VideoApiAdapter.ts || true
rg -n --type=ts "\bnew HttpError\(" packages/app-store/*/lib/VideoApiAdapter.ts || true

echo
echo "== Error mapping helpers (client/server) =="
sed -n '1,220p' packages/lib/getClientErrorFromUnknown.ts
sed -n '1,220p' packages/lib/server/getServerErrorFromUnknown.ts

Repository: calcom/cal.diy

Length of output: 16378


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,120p' packages/lib/errors.ts

Repository: calcom/cal.diy

Length of output: 3191


Use ErrorWithCode (not HttpError) in the new non‑tRPC error branches of VideoApiAdapter.ts.

packages/app-store/office365video/lib/VideoApiAdapter.ts currently throws new HttpError({ statusCode: 400, ... }) (and other HttpError instances) for the new meeting update/delete error paths (lines 233-236, 248-251, 280-283, 291-294). Switch these to ErrorWithCode using import { ErrorCode } from "@calcom/lib/errorCodes"; import { ErrorWithCode } from "@calcom/lib/errors"; and throw new ErrorWithCode(ErrorCode.BadRequest, "…") (or ErrorWithCode.Factory.*).

🤖 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 `@packages/app-store/office365video/lib/VideoApiAdapter.ts` around lines 233 -
236, Replace uses of HttpError in the new non‑tRPC error branches with
ErrorWithCode: add imports "ErrorCode" and "ErrorWithCode" from
"`@calcom/lib/errorCodes`" and "`@calcom/lib/errors`" respectively, then change
throws like the ones in VideoApiAdapter (e.g. the meeting update/delete branches
that currently throw new HttpError(...)) to throw new
ErrorWithCode(ErrorCode.BadRequest, "<message>") or use
ErrorWithCode.Factory.BadRequest("<message>") so all new error paths use
ErrorWithCode instead of HttpError.

@NamanYadav11
Copy link
Copy Markdown
Author

Thanks for the review! This suggestion doesn't align with the existing patterns in VideoApiAdapter files — the createMeeting method (pre-existing code) already uses HttpError throughout, as does the tandemvideo adapter. ErrorWithCode is used in payment service adapters, not video adapters. Using it here would introduce an inconsistency and would also break the instanceof HttpError guards in the catch blocks. Keeping HttpError is intentional for consistency.

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

Labels

🐛 bug Something isn't working size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: MS Teams updateMeeting creates duplicates, deleteMeeting is a no-op

1 participant