Sends each user their weekly digest and monthly recap, unless they turned it off. main.ts starts digestJob, which every quarter of an hour sends the digests that are due; digest_schedule remembers, for each user and cadence, the start of the period their next one covers.

A period is 7 days or 30, rolling from when the user's schedule began, so the digests spread over the week instead of leaving together. A digest covers the period just ended, or the last full period when the server was down longer than one; a digest with nothing to show isn't sent, and either way the next period begins. The top dumps and the community section come from community-service.ts, which the /community page reads too.

Functions

f
buildDigest(
readerId: string,
reader: string,
cadence: DigestCadence,
from: Date,
to: Date,
token: string
): DigestContent | null

Returns the digest of user readerId for the period from from to to, or null when it would show nothing. The links are absolute; the unsubscribe one carries token, which turns off cadence.

f
sendDueDigests(now?: Date): Promise<number>

Sends every digest due at now, one after the other, and returns how many went out. A digest that fails to send is logged and not retried: its period is over either way, and the next one starts.

f
syncDigestSchedules(now: Date): void

Brings digest_schedule in line with the settings: a user who turned a cadence off loses its row, and one who receives it without a row, being new or having turned it back on, starts a period at now.

Variables

v
digestJob: Job

Sends the due digests a minute after the server starts, then every quarter of an hour. main.ts starts it.