forked from calcom/cal.com
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 11642 app shimmer video (calcom#12159)
* added initial app * created basic functionality for Shimmer Video app with tracking of Daily rooms * changed the type config value in the shimmer video config.json * re-fixed update to shimmer-video config type * updated static images for shimmer video app * fixed tracking Shimmer video event parameter * Add zod files * Allow query for "conferencing" apps * Move to shimmer video * Redirect to shimmer app * Remove console.logs * Remove legacy use of seed-app-store. --------- Co-authored-by: Peer Richelsen <[email protected]> Co-authored-by: Vik <[email protected]> Co-authored-by: pathaksarvesh <[email protected]> Co-authored-by: Joe Au-Yeung <[email protected]> Co-authored-by: Joe Au-Yeung <[email protected]> Co-authored-by: Hariom <[email protected]>
- Loading branch information
1 parent
09fc7e1
commit 6848362
Showing
21 changed files
with
291 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
items: | ||
- 1.jpeg | ||
- 2.jpeg | ||
--- | ||
|
||
{DESCRIPTION} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { createDefaultInstallation } from "@calcom/app-store/_utils/installation"; | ||
import type { AppDeclarativeHandler } from "@calcom/types/AppHandler"; | ||
|
||
import appConfig from "../config.json"; | ||
|
||
const handler: AppDeclarativeHandler = { | ||
appType: appConfig.type, | ||
variant: appConfig.variant, | ||
slug: appConfig.slug, | ||
supportsMultipleInstalls: false, | ||
handlerType: "add", | ||
createCredential: ({ appType, user, slug, teamId }) => | ||
createDefaultInstallation({ appType, userId: user.id, slug, key: {}, teamId }), | ||
}; | ||
|
||
export default handler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as add } from "./add"; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"/*": "Don't modify slug - If required, do it using cli edit command", | ||
"name": "Shimmer Video", | ||
"slug": "shimmervideo", | ||
"type": "shimmer_video", | ||
"logo": "icon.png", | ||
"url": "https://shimmer.care", | ||
"variant": "conferencing", | ||
"categories": ["conferencing"], | ||
"publisher": "Shimmer.care", | ||
"email": "[email protected]", | ||
"description": "The #1 Expert ADHD Coach. Weekly calls and in-app support so that you can reach your full potential", | ||
"isTemplate": false, | ||
"__createdUsingCli": true, | ||
"__template": "basic", | ||
"appData": { | ||
"location": { | ||
"linkType": "dynamic", | ||
"type": "integrations:shimmer_video", | ||
"label": "Shimmer Video" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * as api from "./api"; | ||
export * as lib from "./lib"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
import { z } from "zod"; | ||
|
||
import { handleErrorsJson } from "@calcom/lib/errors"; | ||
import type { GetRecordingsResponseSchema, GetAccessLinkResponseSchema } from "@calcom/prisma/zod-utils"; | ||
import { getRecordingsResponseSchema, getAccessLinkResponseSchema } from "@calcom/prisma/zod-utils"; | ||
import type { CalendarEvent } from "@calcom/types/Calendar"; | ||
import type { PartialReference } from "@calcom/types/EventManager"; | ||
import type { VideoApiAdapter, VideoCallData } from "@calcom/types/VideoApiAdapter"; | ||
|
||
import { getShimmerAppKeys } from "./getShimmerAppKeys"; | ||
|
||
/** Shimmer Video app type in the config.json | ||
* changed to 'shimmer_video' to support video conferencing | ||
*/ | ||
|
||
/** @link https://docs.daily.co/reference/rest-api/rooms/create-room */ | ||
const dailyReturnTypeSchema = z.object({ | ||
/** Long UID string ie: 987b5eb5-d116-4a4e-8e2c-14fcb5710966 */ | ||
id: z.string(), | ||
/** Not a real name, just a random generated string ie: "ePR84NQ1bPigp79dDezz" */ | ||
name: z.string(), | ||
api_created: z.boolean(), | ||
privacy: z.union([z.literal("private"), z.literal("public")]), | ||
/** https://api-demo.daily.co/ePR84NQ1bPigp79dDezz */ | ||
url: z.string(), | ||
created_at: z.string(), | ||
config: z.object({ | ||
enable_prejoin_ui: z.boolean(), | ||
enable_people_ui: z.boolean(), | ||
enable_emoji_reactions: z.boolean(), | ||
enable_pip_ui: z.boolean(), | ||
enable_hand_raising: z.boolean(), | ||
enable_network_ui: z.boolean(), | ||
enable_video_processing_ui: z.boolean(), | ||
enable_noise_cancellation_ui: z.boolean(), | ||
enable_advanced_chat: z.boolean(), | ||
//above flags are for prebuilt daily | ||
enable_chat: z.boolean(), | ||
enable_knocking: z.boolean(), | ||
}), | ||
}); | ||
|
||
export interface DailyEventResult { | ||
id: string; | ||
name: string; | ||
api_created: boolean; | ||
privacy: string; | ||
url: string; | ||
created_at: string; | ||
config: Record<string, unknown>; | ||
} | ||
|
||
export interface DailyVideoCallData { | ||
type: string; | ||
id: string; | ||
password: string; | ||
url: string; | ||
} | ||
|
||
export const fetcher = async (endpoint: string, init?: RequestInit | undefined) => { | ||
const { api_key } = await getShimmerAppKeys(); | ||
const response = await fetch(`https://api.daily.co/v1${endpoint}`, { | ||
method: "GET", | ||
headers: { | ||
Authorization: `Bearer ${api_key}`, | ||
"Content-Type": "application/json", | ||
...init?.headers, | ||
}, | ||
...init, | ||
}).then(handleErrorsJson); | ||
return response; | ||
}; | ||
|
||
export const fetcherShimmer = async (endpoint: string, init?: RequestInit | undefined) => { | ||
const { api_key, api_route } = await getShimmerAppKeys(); | ||
|
||
if (!api_route) { | ||
//if no api_route, then we wont push to shimmer | ||
return Promise.resolve([]); | ||
} | ||
|
||
const response = await fetch(`${api_route}${endpoint}`, { | ||
method: "GET", | ||
headers: { | ||
Authorization: `Bearer ${api_key}`, | ||
"Content-Type": "application/json", | ||
...init?.headers, | ||
}, | ||
...init, | ||
}); | ||
|
||
return response; | ||
}; | ||
|
||
export const postToShimmerAPI = async ( | ||
event: CalendarEvent, | ||
endpoint: string, | ||
body: Record<string, unknown> | ||
) => { | ||
return fetcherShimmer(endpoint, { | ||
method: "POST", | ||
body: JSON.stringify({ | ||
cal: event, | ||
daily: body, | ||
}), | ||
}); | ||
}; | ||
|
||
function postToDailyAPI(endpoint: string, body: Record<string, unknown>) { | ||
return fetcher(endpoint, { | ||
method: "POST", | ||
body: JSON.stringify(body), | ||
}); | ||
} | ||
|
||
const ShimmerDailyVideoApiAdapter = (): VideoApiAdapter => { | ||
async function createOrUpdateMeeting(endpoint: string, event: CalendarEvent): Promise<VideoCallData> { | ||
if (!event.uid) { | ||
throw new Error("We need need the booking uid to create the Daily reference in DB"); | ||
} | ||
const body = await translateEvent(); | ||
const dailyEvent = await postToDailyAPI(endpoint, body).then(dailyReturnTypeSchema.parse); | ||
// const meetingToken = await postToDailyAPI("/meeting-tokens", { | ||
// properties: { room_name: dailyEvent.name, exp: dailyEvent.config.exp, is_owner: true }, | ||
// }).then(meetingTokenSchema.parse); | ||
await postToShimmerAPI(event, "trackDailyRoom", dailyEvent); | ||
|
||
return Promise.resolve({ | ||
type: "shimmer_video", | ||
id: dailyEvent.name, | ||
password: "", | ||
// password: meetingToken.token, | ||
url: `https://app.shimmer.care?videoId=${dailyEvent.name}`, | ||
}); | ||
} | ||
|
||
const translateEvent = async () => { | ||
return { | ||
privacy: "private", | ||
properties: { | ||
enable_prejoin_ui: true, | ||
enable_people_ui: true, | ||
enable_emoji_reactions: true, | ||
enable_pip_ui: true, | ||
enable_hand_raising: true, | ||
enable_network_ui: true, | ||
enable_video_processing_ui: true, | ||
enable_noise_cancellation_ui: true, | ||
enable_advanced_chat: true, | ||
//above flags are for prebuilt daily | ||
enable_knocking: true, | ||
enable_screenshare: true, | ||
enable_chat: true, | ||
}, | ||
}; | ||
}; | ||
|
||
return { | ||
/** Daily doesn't need to return busy times, so we return empty */ | ||
getAvailability: () => { | ||
return Promise.resolve([]); | ||
}, | ||
createMeeting: async (event: CalendarEvent): Promise<VideoCallData> => | ||
createOrUpdateMeeting("/rooms", event), | ||
deleteMeeting: async (uid: string): Promise<void> => { | ||
await fetcher(`/rooms/${uid}`, { method: "DELETE" }); | ||
return Promise.resolve(); | ||
}, | ||
updateMeeting: (bookingRef: PartialReference, event: CalendarEvent): Promise<VideoCallData> => | ||
createOrUpdateMeeting(`/rooms/${bookingRef.uid}`, event), | ||
getRecordings: async (roomName: string): Promise<GetRecordingsResponseSchema> => { | ||
try { | ||
const res = await fetcher(`/recordings?room_name=${roomName}`).then( | ||
getRecordingsResponseSchema.parse | ||
); | ||
return Promise.resolve(res); | ||
} catch (err) { | ||
throw new Error("Something went wrong! Unable to get recording"); | ||
} | ||
}, | ||
getRecordingDownloadLink: async (recordingId: string): Promise<GetAccessLinkResponseSchema> => { | ||
try { | ||
const res = await fetcher(`/recordings/${recordingId}/access-link?valid_for_secs=172800`).then( | ||
getAccessLinkResponseSchema.parse | ||
); | ||
return Promise.resolve(res); | ||
} catch (err) { | ||
console.log("err", err); | ||
throw new Error("Something went wrong! Unable to get recording access link"); | ||
} | ||
}, | ||
}; | ||
}; | ||
|
||
export default ShimmerDailyVideoApiAdapter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { z } from "zod"; | ||
|
||
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; | ||
|
||
const shimmerAppKeysSchema = z.object({ | ||
api_key: z.string(), | ||
api_route: z.string(), | ||
}); | ||
|
||
export const getShimmerAppKeys = async () => { | ||
const appKeys = await getAppKeysFromSlug("shimmer-video"); | ||
return shimmerAppKeysSchema.parse(appKeys); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as VideoApiAdapter } from "./VideoApiAdapter"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/package.json", | ||
"private": true, | ||
"name": "@calcom/shimmer-video", | ||
"version": "0.0.0", | ||
"main": "./index.ts", | ||
"dependencies": { | ||
"@calcom/lib": "*" | ||
}, | ||
"devDependencies": { | ||
"@calcom/types": "*" | ||
}, | ||
"description": "The #1 Expert ADHD Coach. Weekly calls and in-app support so that you can reach your full potential" | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { z } from "zod"; | ||
|
||
export const appKeysSchema = z.object({ | ||
api_key: z.string(), | ||
api_route: z.string(), | ||
}); | ||
|
||
export const appDataSchema = z.object({}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters