diff --git a/src/location.ts b/src/location.ts index 9883fb2..8b34c85 100644 --- a/src/location.ts +++ b/src/location.ts @@ -1,79 +1,97 @@ -import { env } from "@/env/server.mjs"; +import { env } from '@/env/server.mjs'; // @ts-ignore -import * as life360 from "life360-node-api"; +import * as life360 from 'life360-node-api'; const center = { - longitude: env.CENTER_LONGITUDE, - latitude: env.CENTER_LATITUDE, + longitude: env.CENTER_LONGITUDE, + latitude: env.CENTER_LATITUDE }; const MILES_PER_NAUTICAL_MILE = 1.15078; const KILOMETERS_PER_MILE = 1.60934; export type Position = { - longitude: number; - latitude: number; + longitude: number; + latitude: number; }; // K = Kilometers, N = Nautical Miles, M = Miles (default: M) export function distance( - a: Position, - b: Position, - unit: "K" | "N" | "M" = "M" + a: Position, + b: Position, + unit: 'K' | 'N' | 'M' = 'M' ) { - if (a.latitude == b.latitude && a.longitude == b.longitude) { - return 0; - } else { - const radlat1 = (Math.PI * a.latitude) / 180; - const radlat2 = (Math.PI * b.latitude) / 180; - const theta = a.longitude - b.longitude; - const radtheta = (Math.PI * theta) / 180; - let dist = - Math.sin(radlat1) * Math.sin(radlat2) + - Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); + if (a.latitude == b.latitude && a.longitude == b.longitude) { + return 0; + } else { + const radlat1 = (Math.PI * a.latitude) / 180; + const radlat2 = (Math.PI * b.latitude) / 180; + const theta = a.longitude - b.longitude; + const radtheta = (Math.PI * theta) / 180; + let dist = + Math.sin(radlat1) * Math.sin(radlat2) + + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); - if (dist > 1) dist = 1; + if (dist > 1) dist = 1; - dist = Math.acos(dist); - dist = (dist * 180) / Math.PI; - dist = dist * 60 * MILES_PER_NAUTICAL_MILE; // Convert to miles + dist = Math.acos(dist); + dist = (dist * 180) / Math.PI; + dist = dist * 60 * MILES_PER_NAUTICAL_MILE; // Convert to miles - // Convert to the specified unit - switch (unit) { - case "K": - return dist * KILOMETERS_PER_MILE; - case "N": - return dist / MILES_PER_NAUTICAL_MILE; - case "M": - default: - return dist; - } - } + // Convert to the specified unit + switch (unit) { + case 'K': + return dist * KILOMETERS_PER_MILE; + case 'N': + return dist / MILES_PER_NAUTICAL_MILE; + case 'M': + default: + return dist; + } + } } /** * @returns The distance in meters between me and the center */ export async function getDistance(): Promise { - // Setup the Life360 API client - const client = await life360.login( - env.LIFE360_USERNAME, - env.LIFE360_PASSWORD - ); + let client; + try { + // Setup the Life360 API client + client = await life360.login( + env.LIFE360_USERNAME, + env.LIFE360_PASSWORD + 'a' + ); + } catch (e) { + throw new Error( + `Failed while logging in to Life360: ${ + e instanceof Error ? e.message : e + }` + ); + } - // Get my current location - const circles = await client.listCircles(); - const myCircle = circles[0]; - const members = await myCircle.listMembers(); - const me = members.findById(env.LIFE360_MEMBER_ID); + let me; + try { + // Get my current location + const circles = await client.listCircles(); + const myCircle = circles[0]; + const members = await myCircle.listMembers(); + me = members.findById(env.LIFE360_MEMBER_ID); + } catch (e) { + throw new Error( + `Failed while getting my location from Life360: ${ + e instanceof Error ? e.message : e + }` + ); + } - // Parse my location into latitude and longitude - const current = { - latitude: parseFloat(me.location.latitude), - longitude: parseFloat(me.location.longitude), - }; + // Parse my location into latitude and longitude + const current = { + latitude: parseFloat(me.location.latitude), + longitude: parseFloat(me.location.longitude) + }; - // Calculate the distance between my location and the center - const difference = distance(current, center, "K") * 1000; + // Calculate the distance between my location and the center + const difference = distance(current, center, 'K') * 1000; - return difference; + return difference; } diff --git a/src/pages/api/cron.ts b/src/pages/api/cron.ts index aeb0cad..d9d2bf9 100644 --- a/src/pages/api/cron.ts +++ b/src/pages/api/cron.ts @@ -1,40 +1,49 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from "next"; -import { getDistance } from "@/location"; -import { env } from "@/env/server.mjs"; -import monitorAsync from "@/monitor"; +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getDistance } from '@/location'; +import { env } from '@/env/server.mjs'; +import monitorAsync from '@/monitor'; type ResponseData = { - diff: number; - inRange: boolean; + diff: number; + inRange: boolean; }; type StatusData = { status: string }; const center = { - latitude: env.CENTER_LATITUDE, - longitude: env.CENTER_LONGITUDE, + latitude: env.CENTER_LATITUDE, + longitude: env.CENTER_LONGITUDE }; export default async function handler( - req: NextApiRequest, - res: NextApiResponse<(ResponseData & StatusData) | StatusData> + req: NextApiRequest, + res: NextApiResponse<(ResponseData & StatusData) | StatusData> ) { - if (req.query.key != env.API_KEY) { - // auth failed - res.status(401).json({ status: "Unauthorized" }); - return; - } + if (req.query.key != env.API_KEY) { + // auth failed + res.status(401).json({ status: 'Unauthorized' }); + return; + } - await monitorAsync(async function () { - const diff = await getDistance(); - // auth passed - res.setHeader( - "Cache-Control", - `max-age=0, s-maxage=${env.EDGE_CACHE_TIME_SECONDS}, stale-while-revalidate` - ); - res - .status(200) - .json({ diff, inRange: diff < env.MAX_DISTANCE, status: "Authorized" }); - }); + async function innerFunction() { + const diff = await getDistance(); + // auth passed + res.setHeader( + 'Cache-Control', + `max-age=0, s-maxage=${env.EDGE_CACHE_TIME_SECONDS}, stale-while-revalidate` + ); + res + .status(200) + .json({ diff, inRange: diff < env.MAX_DISTANCE, status: 'Success' }); + } + + try { + if (process.env.NODE_ENV === 'production') + await monitorAsync(innerFunction); + else await innerFunction(); + } catch (e) { + console.error(e); + res.status(500).json({ status: 'Error' }); + } } diff --git a/src/timing.ts b/src/timing.ts index f0b3f29..6e84a98 100644 --- a/src/timing.ts +++ b/src/timing.ts @@ -215,7 +215,6 @@ export async function getMatchingTime( ): Promise { const times = config.times.filter((time) => { // If the day doesn't match, skip. - console.log(dayAsNumber[now.getDay().toString()]); if (!time.days.has(dayAsNumber[now.getDay().toString()])) return false; const startTime = time.time;