Files
cal.diy/packages/features/calendar-cache/api/cron.ts
T
Omar LópezandUdit Takkar d294a74aad feat: Populate gCal calendar cache via webhooks (#11928)
* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Update CalendarService.ts

* Type fixes

* WIP

* fix: improve cache hits

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Feedback

* Update CalendarService.ts

* Update CalendarService.ts

* Update _router.ts

* feedback

* WIP

* WIP

* Update schema.prisma

* feedback

* typefixes

* Update Calendar.d.ts

* fix: watches when adding a calendar

* Discard changes to packages/app-store/googlecalendar/api/add.ts

* WIP

Signed-off-by: Omar López <zomars@me.com>

* WIP

Signed-off-by: Omar López <zomars@me.com>

* WP

Signed-off-by: Omar López <zomars@me.com>

* Update calendar.ts

* Update calendar.ts

* Update callback.ts

* Update callback.ts

* Conflicts

* WIP

* WIP

* Update CalendarService.ts

* Cleanup

* Discard changes to packages/features/settings/layouts/SettingsLayout.tsx

* Update calendar-cache.repository.ts

* WIP

* Update getSelectedCalendarsToWatch.sql

* WIP

* Update CalendarService.ts

* Cleanup

* Discard changes to packages/app-store/googlecalendar/lib/CalendarService.ts

* Create CalendarService.wip.ts

* WIP

* Update CalendarService.ts

* Update getSelectedCalendarsToWatch.sql

* Delete CalendarService.wip.ts

* test updates

* cleanup

Signed-off-by: Omar López <zomars@me.com>

* Update CalendarService.test.ts

* Update CalendarService.ts

* type fixes

* Update OAuthManager.ts

* Update CalendarService.ts

* Almost there

* Update CalendarService.test.ts

* Update calendar.ts

* Update callback.ts

* Update toggleFeatureFlag.handler.ts

* fix: feedback

* Update getSelectedCalendarsToWatch.sql

* Fix unit tests

---------

Signed-off-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-11-15 14:59:37 -03:00

63 lines
2.3 KiB
TypeScript

import type { NextRequest } from "next/server";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder.appDir";
import { SelectedCalendarRepository } from "@calcom/lib/server/repository/selectedCalendar";
import { CalendarCache } from "../calendar-cache";
const validateRequest = (req: NextRequest) => {
const searchParams = req.nextUrl.searchParams;
const apiKey = searchParams.get("apiKey") || req.headers.get("authorization");
if (!apiKey || ![process.env.CRON_API_KEY, `Bearer ${process.env.CRON_SECRET}`].includes(apiKey)) {
throw new HttpError({ statusCode: 401, message: "Unauthorized" });
}
};
const handleCalendarsToUnwatch = async () => {
const calendarsToUnwatch = await SelectedCalendarRepository.getNextBatchToUnwatch();
const result = await Promise.allSettled(
calendarsToUnwatch.map(async (sc) => {
if (!sc.credentialId) return;
const cc = await CalendarCache.initFromCredentialId(sc.credentialId);
await cc.unwatchCalendar({ calendarId: sc.externalId });
})
);
return result;
};
const handleCalendarsToWatch = async () => {
const calendarsToWatch = await SelectedCalendarRepository.getNextBatchToWatch();
const result = await Promise.allSettled(
calendarsToWatch.map(async (sc) => {
if (!sc.credentialId) return;
const cc = await CalendarCache.initFromCredentialId(sc.credentialId);
await cc.watchCalendar({ calendarId: sc.externalId });
})
);
return result;
};
// This cron is used to activate and renew calendar subcriptions
export const GET = defaultResponder(async (request: NextRequest) => {
validateRequest(request);
const [watchedResult, unwatchedResult] = await Promise.all([
handleCalendarsToWatch(),
handleCalendarsToUnwatch(),
]);
// TODO: Credentials can be installed on a whole team, check for selected calendars on the team
return {
succeededAt: new Date().toISOString(),
watched: {
successful: watchedResult.filter((x) => x.status === "fulfilled").length,
failed: watchedResult.filter((x) => x.status === "rejected").length,
},
unwatched: {
successful: unwatchedResult.filter((x) => x.status === "fulfilled").length,
failed: unwatchedResult.filter((x) => x.status === "rejected").length,
},
};
});