- Shipped
- September 7, 2026 at 1:18 AM UTC
- Author
- Kamo
- Commit
- b77417c
InternalCalendarService wrote the attendee rows and stopped. It never set sendInvites and never called EventInviteService, so a guest arriving through the service-to-service path — the whole of the lead-callback feature — was stored on the event and heard nothing, ever. Adding a checkbox to the lead page on top of that would have shipped a control that did nothing. It now honours the invite flags, syncs the guest list on update through MemberCalendarService rather than ignoring it, raises the SEQUENCE when the meeting actually moves, and retracts the event from anybody it had already told who is then taken off it. Every one of those is something the session-scoped path has always done; this one had none of them, so a rescheduled call could not reach the guest holding the old invitation — an iCalendar client ignores an update arriving at a sequence it has. Delivery now branches on the ATTENDEE rather than the event. The guest an event is ABOUT — named by the new subjectEmail field, marked SUBJECT_SOURCE_KIND on the row — gets the organisation's own branded letter through LeadCallbackInviteMailer; a colleague on the same call keeps the plain invitation unchanged. Writing to a colleague as though they were the customer being rung is not something anybody would file a bug about; they would quietly stop using the checkbox. That mark does a second job: it keeps the lead on the guest list when the event is edited from the calendar page, which knows nothing about leads and sends an audience that cannot contain one. Without it, an unrelated edit takes a customer off their own call, silently, with their calendar still holding the time. The letter goes out from the booking member's own mailbox when they have one — so the address in the lead's inbox is a person's, a reply reaches whoever is calling them, and the copy in Sent is what puts it on the lead's Communications timeline. A member with no provisioned mailbox now falls back to the organisation's transactional address with Reply-To pointed at them. The behaviour it replaces was a warning in a log: a member who ticked the box, and a lead who was never told. EmailTemplateService.sendToUser is split into render and deliver so the branded body can be built without being sent, and so the From address, the SPF decision and the platform fallback are still decided in exactly one place. Rendered carries the merged orgName rather than re-reading the organization: several callers override it, and the From's "on behalf of" must not say something the body contradicts.