import { blockDevice } from "@/actions/omada-actions"; import prisma from "@/lib/db"; import { validateApiKey } from "@/lib/utils"; import { addDays, addMonths, isAfter, isWithinInterval } from "date-fns"; const lastRunTime = new Date(); export async function GET(request: Request) { try { // Validate API key before proceeding validateApiKey(request); const currentTime = new Date(); const hoursSinceLastRun = (currentTime.getTime() - lastRunTime.getTime()) / (1000 * 60 * 60); // Get all active and unblocked devices with their latest payment const devices = await prisma.device.findMany({ where: { isActive: true, blocked: false, }, include: { payments: true, User: { include: { devices: true, }, }, }, }); let devicesNeedingNotification = 0; let devicesBlocked = 0; for (const device of devices) { let expiryDate = new Date(); const payment = device.payments[0]; expiryDate = addMonths( payment?.paidAt || new Date(), payment?.numberOfMonths || 0, ); // Calculate notification threshold (5 days before expiry) const notificationThreshold = addDays(expiryDate, -5); const currentDate = new Date(); console.log("device name -> ", device.name); console.log("paid date -> ", device.payments[0]?.paidAt); console.log("no of months paid -> ", device.payments[0]?.numberOfMonths); console.log("calculated expire date -> ", expiryDate); console.log("notification threshold -> ", notificationThreshold); console.log("current date -> ", currentDate); // Check if device is within notification period if ( isWithinInterval(currentDate, { start: notificationThreshold, end: expiryDate, }) ) { // Device is within 5 days of expiring if (device.User?.phoneNumber) { await sendNotifySms( new Date(expiryDate), device.User?.phoneNumber ?? "", device.name, ); devicesNeedingNotification++; } } // Check if device has expired if (isAfter(currentDate, expiryDate)) { // Device has expired, block it // TODO: add a reason for blocking await blockDevice({ macAddress: device.mac, type: "block", }); await prisma.device.update({ where: { id: device.id }, data: { isActive: false, blocked: true, }, }); devicesBlocked++; } } if (hoursSinceLastRun < 24) { return Response.json({ totalActiveDevices: devices.length, devicesChecked: { notified: devicesNeedingNotification, blocked: devicesBlocked, }, message: "Check was run recently", nextCheckIn: `${Math.round(24 - hoursSinceLastRun)} hours`, }); } return Response.json({ success: true, totalActiveDevices: devices.length, devicesChecked: { notified: devicesNeedingNotification, blocked: devicesBlocked, }, runAt: currentTime, }); } catch (error) { if (error instanceof Error) { if (error.message === "API key is missing") { return Response.json({ error: "API key is required" }, { status: 401 }); } if (error.message === "Invalid API key") { return Response.json({ error: "Invalid API key" }, { status: 403 }); } } console.error("Error in device check:", error); return Response.json({ error: "Failed to check devices" }, { status: 500 }); } } // Mock function - replace with your actual SMS implementation async function sendNotifySms( expireDate: Date, phoneNumber: string, deviceName?: string, ) { const respose = await fetch(`${process.env.SMS_API_BASE_URL}/api/sms`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.SMS_API_KEY}`, }, body: JSON.stringify({ check_delivery: false, number: phoneNumber, message: `REMINDER! Your device [${deviceName}] will expire on ${new Date(expireDate)}.`, }), }); const data = await respose.json(); console.log(data); return data; // Implement your SMS logic here }