feat: migrate to cloudflare d1 and queues
This commit is contained in:
@@ -159,7 +159,7 @@ app.openapi(route, async (c) => {
|
||||
mediaListEntry.status,
|
||||
);
|
||||
if (wasAdded) {
|
||||
await maybeScheduleNextAiringEpisode(c.req, media.id);
|
||||
await maybeScheduleNextAiringEpisode(media.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { zValidator } from "@hono/zod-validator";
|
||||
import { Hono } from "hono";
|
||||
import { z } from "zod";
|
||||
|
||||
import { getEpisodesFromAniwatch } from "~/controllers/episodes/getByAniListId/aniwatch";
|
||||
import { fetchEpisodeUrl } from "~/controllers/episodes/getEpisodeUrl";
|
||||
import { getAdminSdkCredentials } from "~/libs/gcloud/getAdminSdkCredentials";
|
||||
import { sendFcmMessage } from "~/libs/gcloud/sendFcmMessage";
|
||||
@@ -16,6 +17,46 @@ import {
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
export async function onNewEpisode(aniListId: number, episodeNumber: number) {
|
||||
console.log(
|
||||
`On new episode, aniListId: ${aniListId}, episodeNumber: ${episodeNumber}`,
|
||||
);
|
||||
|
||||
if (!(await isWatchingTitle(aniListId))) {
|
||||
console.log(`Title ${aniListId} is no longer being watched`);
|
||||
return { success: true, result: { isNoLongerWatching: true } };
|
||||
}
|
||||
|
||||
const episodes = await getEpisodesFromAniwatch(aniListId);
|
||||
const fetchUrlResult = await fetchEpisodeUrl({ aniListId, episodeNumber });
|
||||
if (!fetchUrlResult) {
|
||||
console.error(`Failed to fetch episode URL for episode`);
|
||||
return { success: false, message: "Failed to fetch episode URL" };
|
||||
}
|
||||
|
||||
const tokens = await getTokensSubscribedToTitle(aniListId);
|
||||
|
||||
await Promise.allSettled(
|
||||
tokens.map(async (token) => {
|
||||
return sendFcmMessage(getAdminSdkCredentials(), {
|
||||
token,
|
||||
data: {
|
||||
type: "new_episode",
|
||||
episodes: JSON.stringify(episodes),
|
||||
episodeStreamInfo: JSON.stringify(fetchUrlResult),
|
||||
aniListId: aniListId.toString(),
|
||||
episodeNumber: episodeNumber.toString(),
|
||||
},
|
||||
android: { priority: "high" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
await maybeScheduleNextAiringEpisode(aniListId);
|
||||
|
||||
return SuccessResponse;
|
||||
}
|
||||
|
||||
app.post(
|
||||
"/",
|
||||
zValidator(
|
||||
@@ -30,48 +71,13 @@ app.post(
|
||||
aniListId: number;
|
||||
episodeNumber: number;
|
||||
}>();
|
||||
console.log(
|
||||
`Internal new episode route, aniListId: ${aniListId}, episodeNumber: ${episodeNumber}`,
|
||||
);
|
||||
|
||||
if (!(await isWatchingTitle(aniListId))) {
|
||||
console.log(`Title ${aniListId} is no longer being watched`);
|
||||
return c.json(
|
||||
{ success: true, result: { isNoLongerWatching: true } },
|
||||
200,
|
||||
);
|
||||
const result = await onNewEpisode(aniListId, episodeNumber, c.req);
|
||||
if (result.success) {
|
||||
return c.json(result, 200);
|
||||
} else {
|
||||
return c.json(result, 500);
|
||||
}
|
||||
|
||||
const fetchUrlResult = await fetchEpisodeUrl({ aniListId, episodeNumber });
|
||||
if (!fetchUrlResult) {
|
||||
console.error(`Failed to fetch episode URL for episode`);
|
||||
return c.json(
|
||||
{ success: false, message: "Failed to fetch episode URL" },
|
||||
500,
|
||||
);
|
||||
}
|
||||
|
||||
const tokens = await getTokensSubscribedToTitle(aniListId);
|
||||
|
||||
await Promise.allSettled(
|
||||
tokens.map(async (token) => {
|
||||
return sendFcmMessage(getAdminSdkCredentials(), {
|
||||
token,
|
||||
data: {
|
||||
type: "new_episode",
|
||||
episodes: JSON.stringify(episodes),
|
||||
episodeStreamInfo: JSON.stringify(fetchUrlResult),
|
||||
aniListId: aniListId.toString(),
|
||||
episodeNumber: episodeNumber.toString(),
|
||||
},
|
||||
android: { priority: "high" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
await maybeScheduleNextAiringEpisode(c.req, aniListId);
|
||||
|
||||
return c.json(SuccessResponse, 200);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ export async function getUpcomingTitlesFromAnilist(req: HonoRequest) {
|
||||
|
||||
await Promise.all(
|
||||
Array.from(plannedToWatchTitles).map((titleId) =>
|
||||
maybeScheduleNextAiringEpisode(req, titleId),
|
||||
maybeScheduleNextAiringEpisode(titleId),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ export const maybeUpdateLastConnectedAt = createMiddleware(async (c, next) => {
|
||||
return next();
|
||||
}
|
||||
|
||||
await updateDeviceLastConnectedAt(c.env, deviceId);
|
||||
await updateDeviceLastConnectedAt(deviceId);
|
||||
return next();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
||||
import type { HonoRequest } from "hono";
|
||||
|
||||
import { AnilistUpdateType } from "~/libs/anilist/updateType.ts";
|
||||
import { maybeScheduleNextAiringEpisode } from "~/libs/maybeScheduleNextAiringEpisode";
|
||||
import { buildNewEpisodeTaskId } from "~/libs/tasks/id";
|
||||
import { queueTask } from "~/libs/tasks/queueTask";
|
||||
@@ -76,9 +77,9 @@ export async function updateWatchStatus(
|
||||
watchStatus,
|
||||
);
|
||||
if (wasAdded) {
|
||||
await maybeScheduleNextAiringEpisode(req, titleId);
|
||||
await maybeScheduleNextAiringEpisode(titleId);
|
||||
} else if (wasDeleted) {
|
||||
await removeTask("new-episode", buildNewEpisodeTaskId(titleId));
|
||||
await removeTask("NEW_EPISODE", buildNewEpisodeTaskId(titleId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,13 +116,12 @@ app.openapi(route, async (c) => {
|
||||
}
|
||||
|
||||
await queueTask(
|
||||
"anilist-updates",
|
||||
"ANILIST_UPDATES",
|
||||
{
|
||||
deviceId,
|
||||
watchStatus,
|
||||
titleId,
|
||||
isRetrying: true,
|
||||
nameSuffix: "watch-status",
|
||||
updateType: AnilistUpdateType.UpdateWatchStatus,
|
||||
},
|
||||
{ req: c.req, scheduleConfig: { delay: { minute: 1 } } },
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user