Files
Devon HudsonandClaude Opus 5 734734e076 Add a task to send room invite emails
Takes a room ID and a list of email addresses, and sends each recipient a
templated email containing a link to join the room.

This is split into two jobs. `SendRoomInviteEmailsJob` only fans out: it
schedules one `SendRoomInviteEmailJob` per unique address and commits them
in a single transaction, so either every recipient got a job or none did.
`SendRoomInviteEmailJob` sends exactly one email.

Splitting it this way makes each address its own retry unit. A single job
looping over the list would re-send to everyone it had already reached when
a later address fails and the job is retried, which is why
`SendAccountRecoveryEmailsJob` swallows send errors mid-loop instead. Here a
bad address or a transient SMTP failure retries just that one email.

The list is carried in the job payload rather than paginated with a cursor:
a continuation job would have to carry the remaining addresses, making the
total bytes written quadratic in the size of the list. The practical bound
is therefore the payload size of a single row, and a caller with a very
large list should split it across several jobs.

Sends are spread out at a fixed interval so a large batch doesn't burst
against the SMTP server, in the same way device syncs are spaced out when
expiring inactive sessions.

The invite link itself is stubbed: it points at matrix.to, and a real
implementation will need to decide what the link targets and most likely
create a third-party invite on the homeserver first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:51:56 -06:00
..