mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-12 07:36:42 +08:00
0bd8160ed4
#### PR Dependency Tree * **PR #14247** 👈 * **PR #14248** This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Google Calendar integration (disabled by default): link/unlink accounts, OAuth flow, webhooks, real-time push, background sync, workspace calendars with customizable items and date-range event viewing. * **GraphQL / Client** * New queries & mutations for accounts, subscriptions, events, providers, and workspace calendar management. * **Localization** * Added localized error message for calendar provider request failures. * **Tests** * Backend tests covering sync, webhook renewal, and error/error-recovery scenarios. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { Cron, CronExpression } from '@nestjs/schedule';
|
|
|
|
import { Models } from '../../models';
|
|
import { CalendarService } from './service';
|
|
|
|
@Injectable()
|
|
export class CalendarCronJobs {
|
|
constructor(
|
|
private readonly models: Models,
|
|
private readonly calendar: CalendarService
|
|
) {}
|
|
|
|
@Cron(CronExpression.EVERY_MINUTE)
|
|
async pollAccounts() {
|
|
const subscriptions =
|
|
await this.models.calendarSubscription.listAllWithAccountForSync();
|
|
|
|
const accountDueAt = new Map<
|
|
string,
|
|
{ refreshInterval: number; lastSyncAt: Date | null }
|
|
>();
|
|
|
|
for (const subscription of subscriptions) {
|
|
const interval = subscription.account.refreshIntervalMinutes ?? 60;
|
|
const lastSyncAt = subscription.lastSyncAt ?? null;
|
|
const existing = accountDueAt.get(subscription.accountId);
|
|
if (!existing) {
|
|
accountDueAt.set(subscription.accountId, {
|
|
refreshInterval: interval,
|
|
lastSyncAt,
|
|
});
|
|
continue;
|
|
}
|
|
|
|
const earliest =
|
|
existing.lastSyncAt && lastSyncAt
|
|
? existing.lastSyncAt < lastSyncAt
|
|
? existing.lastSyncAt
|
|
: lastSyncAt
|
|
: (existing.lastSyncAt ?? lastSyncAt);
|
|
accountDueAt.set(subscription.accountId, {
|
|
refreshInterval: interval,
|
|
lastSyncAt: earliest,
|
|
});
|
|
}
|
|
|
|
const now = Date.now();
|
|
await Promise.allSettled(
|
|
Array.from(accountDueAt.entries()).map(([accountId, info]) => {
|
|
if (
|
|
!info.lastSyncAt ||
|
|
now - info.lastSyncAt.getTime() >= info.refreshInterval * 60 * 1000
|
|
) {
|
|
return this.calendar.syncAccount(accountId);
|
|
}
|
|
return Promise.resolve();
|
|
})
|
|
);
|
|
}
|
|
}
|