{"id":23376118,"url":"https://github.com/xevion/bus-reminder","last_synced_at":"2026-05-01T02:34:07.762Z","repository":{"id":118245668,"uuid":"605869188","full_name":"Xevion/bus-reminder","owner":"Xevion","description":"A serverless function system for reminding me when the UTSA bus system is about to shutdown.","archived":false,"fork":false,"pushed_at":"2023-11-16T23:58:41.000Z","size":354,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-31T14:13:51.671Z","etag":null,"topics":["cron","cronjob","reminder","serverless","vercel"],"latest_commit_sha":null,"homepage":"https://bus.xevion.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xevion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-24T04:17:48.000Z","updated_at":"2023-03-11T06:28:47.000Z","dependencies_parsed_at":"2024-12-21T17:33:49.411Z","dependency_job_id":"a4ee7534-6b72-40ba-907d-a853728f2755","html_url":"https://github.com/Xevion/bus-reminder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Xevion/bus-reminder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xevion%2Fbus-reminder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xevion%2Fbus-reminder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xevion%2Fbus-reminder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xevion%2Fbus-reminder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xevion","download_url":"https://codeload.github.com/Xevion/bus-reminder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xevion%2Fbus-reminder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32483406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","cronjob","reminder","serverless","vercel"],"created_at":"2024-12-21T17:33:43.512Z","updated_at":"2026-05-01T02:34:07.745Z","avatar_url":"https://github.com/Xevion.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bus-reminder\n\n![Location Check](https://cronitor.io/badges/8frC2k/production/XcmWhvdYm0OyCRuinS1IP6MEUiE.svg)\n\nA cron-job based personal notification system for myself.\n\n## Purpose\n\nI have a problem with letting time get away from me, and in turn, I have\naccidentally missed the last bus of the day several times.\n\nAdditionally, I allow my parentals (who live 200+ miles away from me) to make\nsure that I'm safe using the location tracking app 'Life360'. For background, I\nconsented to this and brought up it's usage in the first place, so I do not mind\nit.\n\nAfter thinking about it, I thought it might be a great idea to use their\nlocation data for myself: I could check my location occasionally, and if I'm\nstill at the library on weekdays right before the bus stops running, I can send\nmyself a notification.\n\nAnd that's pretty much the whole idea.\n\n## Features\n\n- 90% TypeScript\n- Cronitor monitoring\n- Fully validated `.env`\n- Interface for modifying configuration remotely, real-time\n  - Real-time syntax highlighting\n  - Client-side + Server-side validation of configuration via Zod\n- Discord notifications\n- Logging via [`winston`][winston] + Loki\n\n## Stack\n\nNext.js was complete overkill for this, and in retrospect, using something like\nAWS Lambda or Azure Functions may be much more ideal. Even Cloudflare Workers\nmight be easier (although I require Node APIs, I believe).\n\n- [Next.js][nextjs]\n  - Overkill for the most part, but hosting on Vercel is free, fast, and easy.\n- [`life360-node-api`][life360-node-api] for the Life360 API\n- [Vercel][vercel] for Serverless Functions (free)\n- [Cronitor][cronitor] for Cron Job Monitoring (free)\n- [cron-jobs.org][cron-jobs] for Cron Job Execution\n  - Why both, you may ask? I prefer Cronitor's more verbose telemetry API, and I\n    plan to switch off Vercel eventually.\n  - Vercel has cron jobs, why not use that? Because Vercel requires a Pro plan\n    for cron jobs that execute more than once a day. I unfortunately do not need\n    anything other than cron jobs.\n- [Upstash][upstash] for Redis (free)\n- [Discord][discord] to deliver notifications via Bot account.\n- [Graphana Loki][graphana-loki] for logging (free)\n\n## Setup\n\n- Requires Node v18 (`Intl.supportedValuesOf` will issue type errors otherwise)\n- Requires credentials specified in `.env` (use [`.env.example`](./.env.example) as a template)\n  - Redis\n  - Discord\n  - Life360 (username, password)\n  - Optional: Loki (logging)\n\n## Live Testing\n\n- `/api/cron` is the primary cron-job endpoint. Authorization required.\n    - `?report=true` is assumed, and when `true`, Cronitor will be notified of the job's status. \n    - `?dry=true` will not send any notifications or effects, but will still perform all checks and logging for runtime testing.\n- `/api/health` is a simple health check endpoint. Authorization optional.\n- `/api/check` is a simple endpoint to check authorization.\n- `/api/config` is the configuration endpoint. Authorization required.\n  - `GET` will return the current configuration.\n  - `POST` will update the configuration. Requires a valid configuration object. Validation will be performed.\n\n[nextjs]: https://nextjs.org/\n[life360-node-api]: https://github.com/kaylathedev/life360-node-api\n[vercel]: https://vercel.com\n[cronitor]: https://cronitor.io\n[cron-jobs]: https://cron-jobs.org\n[upstash]: https://upstash.com\n[discord]: https://discord.com\n[winston]: https://github.com/winstonjs/winston\n[graphana-loki]: https://grafana.com/oss/loki/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxevion%2Fbus-reminder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxevion%2Fbus-reminder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxevion%2Fbus-reminder/lists"}