refactor: move non-public routes to internal subfolder

"non-public" in this case means only used for event handling (and not supposed to be called by clients)
This commit is contained in:
2024-09-08 14:35:00 -05:00
parent ff5e81f5d1
commit d4a5a4fbb1
5 changed files with 16 additions and 10 deletions

View File

@@ -0,0 +1,109 @@
import { zValidator } from "@hono/zod-validator";
import { Hono } from "hono";
import { env } from "hono/adapter";
import mapKeys from "lodash.mapkeys";
import { DateTime } from "luxon";
import { z } from "zod";
import { Case, changeStringCase } from "~/libs/changeStringCase";
import type { AdminSdkCredentials } from "~/libs/fcm/getGoogleAuthToken";
import { sendFcmMessage } from "~/libs/fcm/sendFcmMessage";
import { verifyQstashHeader } from "~/libs/qstash/verifyQstashHeader";
import { readEnvVariable } from "~/libs/readEnvVariable";
import { getTokensSubscribedToTitle } from "~/models/token";
import type { Env } from "~/types/env";
import type { EpisodesResponseSchema } from "~/types/episode";
import type { FetchUrlResponse } from "~/types/episode/fetch-url-response";
import {
AniListIdSchema,
EpisodeNumberSchema,
ErrorResponse,
SuccessResponse,
} from "~/types/schema";
const app = new Hono();
app.post(
"/",
zValidator(
"json",
z.object({
aniListId: AniListIdSchema,
episodeNumber: EpisodeNumberSchema,
}),
),
async (c) => {
const { aniListId, episodeNumber } = await c.req.json<{
aniListId: number;
episodeNumber: number;
}>();
if (!(await verifyQstashHeader(env<Env, typeof c>(c, "workerd"), c.req))) {
return c.json(ErrorResponse, { status: 401 });
}
const domain = c.req.url.replace(c.req.path, "");
const { success, result: fetchEpisodesResult } = await fetch(
`${domain}/episodes/${aniListId}`,
).then((res) => res.json<EpisodesResponseSchema>());
if (!success) {
return c.json(ErrorResponse, { status: 500 });
}
const { episodes, providerId } = fetchEpisodesResult;
const episode = episodes.find(
(episode) => episode.number === episodeNumber,
);
if (!episode) {
return c.json(ErrorResponse, { status: 404 });
}
const { success: fetchUrlSuccess, result: fetchUrlResult } = await fetch(
`${domain}/episodes/${aniListId}/url`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: episode.id,
provider: providerId,
}),
},
).then((res) => res.json<FetchUrlResponse>());
if (!fetchUrlSuccess) {
return c.json(ErrorResponse, { status: 500 });
}
const tokens = await getTokensSubscribedToTitle(
env<Env, typeof c>(c, "workerd"),
aniListId,
);
await Promise.all(
tokens.map(async (token) => {
return sendFcmMessage(
mapKeys(
readEnvVariable<AdminSdkCredentials>(c.env, "ADMIN_SDK_JSON"),
(_, key) => changeStringCase(key, Case.snake_case, Case.camelCase),
) as unknown as AdminSdkCredentials,
{
token,
data: {
type: "new_episode",
episodes: JSON.stringify(episodes),
episodeStreamInfo: JSON.stringify(fetchUrlResult),
aniListId: aniListId.toString(),
episodeNumber: episodeNumber.toString(),
},
android: { priority: "high" },
},
);
}),
);
return c.json(SuccessResponse, 200);
},
);
export default app;