Files
aniplay-api/src/controllers/upcoming-titles/index.ts

77 lines
2.3 KiB
TypeScript

import { Hono } from "hono";
import { env } from "hono/adapter";
import mapKeys from "lodash.mapkeys";
import { DateTime } from "luxon";
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 type { Env } from "~/types/env";
import { ErrorResponse, SuccessResponse } from "~/types/schema";
import { getUpcomingTitlesFromAnilist } from "./anilist";
const app = new Hono();
app.post("/", async (c) => {
if (
!(await verifyQstashHeader(
env<Env, typeof c>(c, "workerd"),
c.req.path,
c.req.header("Upstash-Signature"),
await c.req.text(),
))
) {
return c.json(ErrorResponse, { status: 401 });
}
const titles = await getUpcomingTitlesFromAnilist(
env<Env, typeof c>(c, "workerd"),
);
await Promise.all(
titles.map(async (title) => {
const titleName =
title.media.title?.userPreferred ??
title.media.title?.english ??
"Unknown Title";
return sendFcmMessage(
mapKeys(
readEnvVariable<AdminSdkCredentials>(c.env, "ADMIN_SDK_JSON"),
(_, key) => changeStringCase(key, Case.snake_case, Case.camelCase),
) as unknown as AdminSdkCredentials,
{
topic: "newTitles",
data: {
type: "new_title",
aniListId: title.media.id.toString(),
title: titleName,
airingAt: title.airingAt.toString(),
},
notification: {
title: "New Series Alert",
body: `${titleName} will be released ${DateTime.fromSeconds(title.airingAt).toRelative({ unit: ["days", "hours", "minutes"] })}`,
image:
title.media.coverImage?.medium ??
title.media.coverImage?.large ??
title.media.coverImage?.extraLarge ??
undefined,
},
android: {
notification: {
click_action: "HANDLE_FCM_NOTIFICATION",
},
},
},
);
}),
);
return c.json(SuccessResponse, 200);
});
export default app;