77 lines
2.3 KiB
TypeScript
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;
|