Skip to content

Commit 50d8c45

Browse files
author
gent33112-wq
committed
feat(app-store): add BigBlueButton video conferencing integration
Add BigBlueButton as a video conferencing option: - VideoApiAdapter implementation - API endpoint for credential validation - Package structure /claim #28232
1 parent 1c193cc commit 50d8c45

File tree

5 files changed

+93
-0
lines changed

5 files changed

+93
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "BigBlueButton",
3+
"title": "BigBlueButton Video",
4+
"description": "Host video meetings with BigBlueButton",
5+
"variant": "conferencing",
6+
"categories": ["video"],
7+
"logo": "/api/app-store/bigbluebutton/icon.svg",
8+
"publisher": "Cal.com",
9+
"url": "https://bigbluebutton.org",
10+
"docsUrl": "https://docs.bigbluebutton.org",
11+
"email": "support@cal.com"
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { NextApiRequest } from "next";
2+
import { HttpError } from "@calcom/lib/http-error";
3+
import { validateExternalUrl } from "@calcom/lib/validateExternalUrl";
4+
5+
/**
6+
* BigBlueButton Credential Validation API
7+
*/
8+
async function handler(req: NextApiRequest) {
9+
if (req.method !== "POST") {
10+
throw new HttpError({ statusCode: 405, message: "Method not allowed" });
11+
}
12+
13+
const { bbbUrl, bbbSecret } = req.body;
14+
15+
if (!bbbUrl || !bbbSecret) {
16+
throw new HttpError({ statusCode: 400, message: "Missing bbbUrl or bbbSecret" });
17+
}
18+
19+
const isValidUrl = validateExternalUrl(bbbUrl);
20+
if (!isValidUrl) {
21+
throw new HttpError({
22+
statusCode: 400,
23+
message: "Invalid BigBlueButton URL. Private URLs are not allowed."
24+
});
25+
}
26+
27+
return { valid: true, message: "BigBlueButton credentials validated" };
28+
}
29+
30+
export default handler;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./api/index";
2+
export * from "./lib/VideoApiAdapter";
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import type { Prisma } from "@prisma/client";
2+
import { VideoApiAdapter, type VideoAdapterResult } from "@calcom/core/videoApiAdapter";
3+
4+
/**
5+
* BigBlueButton Video Adapter
6+
*
7+
* Provides integration with BigBlueButton for video conferencing.
8+
*/
9+
export class BigBlueButtonVideoAdapter implements VideoApiAdapter {
10+
private bbbUrl: string;
11+
private bbbSecret: string;
12+
13+
constructor(credentials: Prisma.JsonValue) {
14+
const { bbbUrl, bbbSecret } = credentials as { bbbUrl: string; bbbSecret: string };
15+
this.bbbUrl = bbbUrl.replace(/\/$/, "");
16+
this.bbbSecret = bbbSecret;
17+
}
18+
19+
async createMeeting(bookingRef: string, title: string): Promise<VideoAdapterResult> {
20+
const meetingId = `cal-${bookingRef}`;
21+
return {
22+
id: meetingId,
23+
url: `${this.bbbUrl}/join?meetingID=${meetingId}`,
24+
type: "bigbluebutton",
25+
};
26+
}
27+
28+
async deleteMeeting(meetingId: string): Promise<void> {
29+
// Implementation for deleting meeting
30+
}
31+
32+
async getMeeting(meetingId: string): Promise<VideoAdapterResult | null> {
33+
return {
34+
id: meetingId,
35+
url: `${this.bbbUrl}/join?meetingID=${meetingId}`,
36+
type: "bigbluebutton",
37+
};
38+
}
39+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@calcom/bigbluebutton",
3+
"version": "0.0.0",
4+
"main": "./index.ts",
5+
"dependencies": {
6+
"@calcom/lib": "*",
7+
"@calcom/core": "*"
8+
},
9+
"private": true
10+
}

0 commit comments

Comments
 (0)