import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; import { env } from "hono/adapter"; import { getAdminSdkCredentials } from "~/libs/gcloud/getAdminSdkCredentials"; import { verifyFcmToken } from "~/libs/gcloud/verifyFcmToken"; import { saveToken } from "~/models/token"; import { ErrorResponse, ErrorResponseSchema, SuccessResponse, SuccessResponseSchema, } from "~/types/schema"; const app = new OpenAPIHono(); const SaveTokenRequest = z.object({ token: z.string(), deviceId: z.string(), }); const SaveTokenResponse = SuccessResponseSchema(); const route = createRoute({ tags: ["aniplay", "notifications"], operationId: "saveToken", summary: "Saves FCM token", method: "post", path: "/", request: { body: { content: { "application/json": { schema: SaveTokenRequest, }, }, }, }, responses: { 200: { content: { "application/json": { schema: SaveTokenResponse, }, }, description: "Saved token successfully", }, 412: { content: { "application/json": { schema: ErrorResponseSchema, }, }, description: "Token already exists", }, 500: { content: { "application/json": { schema: ErrorResponseSchema, }, }, description: "Unknown error occurred", }, }, }); app.openapi(route, async (c) => { const { token, deviceId } = await c.req.json(); try { const isValidToken = await verifyFcmToken(token, getAdminSdkCredentials()); if (!isValidToken) { return c.json(ErrorResponse, 401); } await saveToken(deviceId, token); } catch (error) { console.error("Failed to save token"); console.error(error); return c.json(ErrorResponse, 500); } return c.json(SuccessResponse); }); export default app;