2026-10-09 00:38:17 +02:00
2026-10-09 00:38:17 +02:00
2026-10-09 00:38:17 +02:00
2026-10-09 00:38:17 +02:00
2026-10-09 00:38:17 +02:00

77th EV Calendar Notify Service

A TypeScript + Node.js service that polls the 77th JSOC events API, exposes its events through a REST API, stores them in SQLite, publishes an ICS feed, and sends change notifications through an Apprise server.

Requirements

  • Node.js 22.9 or newer
  • npm

Run

npm install
Copy-Item .env.example .env
npm run dev

The service requests https://77th-jsoc.com/service.php?action=get_events for each calendar month touched by today through the next 60 days. It sets year, month, and timezone=-120 on every request and polls every 15 minutes. The API's uid is the event identity in SQLite, the REST API, and ICS UID; the event title remains the display summary.

Each successful poll stores source events in data/events.sqlite (or the path configured by DB_PATH). When opening the older title-keyed database schema, the service preserves its old table under an events_legacy_title_* name and starts a silent UID-based baseline. If the events table is empty, the poll is treated as an initial snapshot and sends no notifications. Later additions, changes, and removals are queued durably in SQLite and sent through Apprise. Failed sends remain queued for retry. Events removed from the source remain in SQLite as cancelled ICS entries.

Apprise and notification configuration

Copy .env.example to .env and set the Apprise host, ntfy host/topic, and Discord webhook. dc_webhook accepts WEBHOOK_ID/WEBHOOK_TOKEN or the full Discord webhook URL. ntfy credentials are optional, but set both username and password if authentication is required. Leave notification_mock=false to send; set it to true to log and consume notifications without sending.

The service posts a JSON payload to Apprise /notify with both the ntfy and Discord URLs. Apprise supports multiple destination URLs in one request. Apprise API

A .env file is optional at startup; without one, the server still runs, but notification sends will remain queued until the notification settings are configured. PORT defaults to 3000; DB_PATH defaults to ./data/events.sqlite.

For production, run npm run build followed by npm start, and keep the process running with your preferred process manager or service host.

Docker

Build and start the service with Docker Compose:

Copy-Item .env.example .env
# Edit .env and configure Apprise, ntfy, and Discord settings.
docker compose up -d --build

The service listens on port 3000; set HOST_PORT in the shell or Compose .env file to change the host port. SQLite data is stored in the persistent event-data Docker volume. Follow logs with docker compose logs -f, stop with docker compose down, and remove the database volume only when you intend to delete the stored events and notification history (docker compose down -v).

To build and run without Compose:

docker build -t 77th-ev-cal-ntfy-srv .
docker run -d --name 77th-ev-cal-ntfy-srv --restart unless-stopped \
  --env-file .env -p 3000:3000 -v event-data:/app/data \
  77th-ev-cal-ntfy-srv

Endpoints

  • GET /health — service and polling status
  • GET /api/events — latest active events and polling status
  • POST /api/refresh — trigger an immediate poll
  • GET /calendar.ics — active events and cancellation entries for calendar subscription
S
Description
No description provided
Readme
70 KiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 96.6%
Dockerfile 3.4%