Alexander 7ce8201082 Initial commit: webtrees Email Newsletter module
Recurring email newsletter for webtrees 2.2+. Each enabled tree
sends upcoming birthdays of living individuals, optional marriage
anniversaries of intact couples, and a once-per-calendar-month
historical section of births and deaths of deceased individuals.

Triggered exclusively by an external scheduler (system cron,
systemd timer, etc.) hitting a token-gated HTTP endpoint — never
on visitor page loads. The "is it due?" decision is idempotent
within the configured frequency window.

Per-user subscription is integrated into the built-in
/my-account/{tree} page via a custom view + a decorated
AccountUpdate handler. Admins can add external addresses and
trigger an immediate send for testing. Email body renders in
German for German-language users; English otherwise. Birthdays
and anniversaries are formatted with the upcoming-event ordinal
age (e.g. "45th birthday" / "45. Geburtstag").
2026-05-15 12:00:39 +02:00

webtrees Email Newsletter

A webtrees 2.2+ custom module that sends recurring email newsletters with:

  • Upcoming birthdays of still-living individuals.
  • Upcoming marriage anniversaries of intact couples (optional — admin toggle, per tree). Marriages with a divorce or annulment fact are excluded automatically.
  • Once-per-month historical section: births and deaths of deceased individuals whose anniversary falls in the upcoming window.

The decision to actually send is made by comparing a stored "last sent" timestamp to the configured frequency, so the dispatch run is idempotent — calling the trigger more often than the frequency simply does nothing extra.

Requirements

  • webtrees ≥ 2.2.0
  • PHP ≥ 8.2
  • A working SMTP / sendmail configuration in webtrees → Control panel → Sending email (this module reuses webtrees' standard mailer).
  • An external scheduler on the host: system cron, a systemd timer, a Kubernetes CronJob, or anything else that can fire an HTTP request at a fixed interval. Newsletter dispatch never runs on visitor page loads — it only runs when the scheduler triggers it.

Installation

  1. Copy this directory into the webtrees modules_v4/ folder, renaming it to email_newsletter (the folder name determines the internal module identifier — the registered name will be _email_newsletter_).

    cp -r webtrees_email_newsletter /var/www/webtrees/modules_v4/email_newsletter
    
  2. In the webtrees control panel, go to Modules → All modules and enable Email Newsletter.

  3. Open Control panel → Modules → Email Newsletter → Preferences and:

    • Enable newsletter dispatch per tree.
    • Pick a frequency (default: 14 days).
    • Optionally toggle marriage anniversaries and add any extra external email addresses.
    • Copy the Cron URL at the bottom — this is the secret-token URL your scheduler must hit.

Setting up the scheduler

Why no built-in scheduler? PHP has no daemon, and frameworks like Laravel rely on a once-per-minute system cron to fire their internal scheduler. This module follows the same convention: the host OS owns the timer, the module owns the "is it actually due?" decision.

System cron

# Run every 15 minutes. The module itself decides whether sending is due.
*/15 * * * *  curl -fsS --max-time 60 'https://example.com/module/_email_newsletter_/Cron?token=YOUR_TOKEN' > /dev/null

systemd timer

/etc/systemd/system/webtrees-newsletter.service:

[Unit]
Description=webtrees newsletter trigger

[Service]
Type=oneshot
ExecStart=/usr/bin/curl -fsS --max-time 60 "https://example.com/module/_email_newsletter_/Cron?token=YOUR_TOKEN"

/etc/systemd/system/webtrees-newsletter.timer:

[Unit]
Description=Trigger webtrees newsletter dispatch

[Timer]
OnCalendar=*-*-* *:00/15
Persistent=true

[Install]
WantedBy=timers.target

Then systemctl enable --now webtrees-newsletter.timer.

Forcing a one-off send

The admin Preferences page has a Send now button for testing. For an unattended one-off send, append &force=1 to the cron URL — that bypasses the "is it due?" check.

Subscribers

Two sources, combined:

  1. Logged-in webtrees users who opt in via the per-tree Newsletter subscription menu entry (visible only to logged-in users on trees where the module is enabled). Only approved and email-verified accounts will receive the newsletter.
  2. External addresses the tree administrator lists in the Extra recipient email addresses textarea (one per line).

Privacy

The dispatch service does not impersonate a webtrees user, so it sees the tree from the visitor access level. Records and facts that your tree settings hide from visitors will be omitted from the newsletter even if a recipient has higher in-app access. This is the safest default for an outbound email — if you need to expose more information, relax the tree's visitor-access settings or hand-curate the Extra recipient list.

License

AGPL-3.0-or-later. See LICENSE for the full text.

S
Description
An email newsletter plugin for upcoming birthdays and marriage anniversaries of living tree members as well as birth and death days for deceased.
Readme 257 KiB
Languages
PHP 50.8%
HTML 49.2%