How to read educational calendar events (NIP-52) from relay.edufeed.org and render them in different designs. The write side — publishing events with educational metadata (registration, price, attendance mode, educational level) — is covered in the Educational Calendar Events integration guide (draft); both pages describe the same events. The educational extension attributes are a draft — this demo reads the plain NIP-52 events published today.
The relay wss://relay.edufeed.org publishes educational calendar events as NIP-52 events on the Nostr protocol. There are four kinds:
Full-day or multi-day events. start / end are YYYY-MM-DD strings.
Events with a specific time. start / end are unix timestamps; optional start_tzid.
A collection that references other events via a-tags. Used to group events into named calendars.
A reply to an event with a status tag of accepted, declined, or tentative.
Nostr is a plain WebSocket protocol. Open a socket, send a REQ frame describing the kinds you want, then collect EVENT messages until you receive EOSE (end of stored events). This is exactly what the demo below does:
const ws = new WebSocket("wss://relay.edufeed.org");
ws.onopen = () => {
ws.send(JSON.stringify([
"REQ", "cal-sub",
{ kinds: [31922, 31923], limit: 500 }
]));
};
ws.onmessage = (msg) => {
const [type, sub, payload] = JSON.parse(msg.data);
if (type === "EVENT") render(payload);
if (type === "EOSE") ws.send(JSON.stringify(["CLOSE", sub]));
};
nak)For scripts and backups, the nak tool works well:
nak req --paginate --paginate-interval 1s \
-k 31922 -k 31923 -k 31924 -k 31925 \
relay.edufeed.org > calendar-events.jsonl
Standalone — no build step, no external scripts. Save this file and open it in a browser.