fix(calendar): send invitation emails client-side via iMIP
Publish Docker Image / prepare (push) Successful in 7s
Publish Docker Image / build (linux/amd64, ubuntu-latest) (push) Failing after 7s
Publish Docker Image / build (linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Publish Docker Image / merge (push) Canceled after 0s
Publish Docker Image / prepare (push) Successful in 7s
Publish Docker Image / build (linux/amd64, ubuntu-latest) (push) Failing after 7s
Publish Docker Image / build (linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Publish Docker Image / merge (push) Canceled after 0s
This commit is contained in:
@@ -487,9 +487,16 @@ export const useCalendarStore = create<CalendarStore>()(
|
||||
}
|
||||
|
||||
set((state) => ({ events: [...state.events, mappedCreated] }));
|
||||
// Invitation emails are sent by the server: `sendSchedulingMessages`
|
||||
// on CalendarEvent/set makes Stalwart queue the iTIP REQUEST itself.
|
||||
// Sending a client-side iMIP copy here produced duplicate emails.
|
||||
// Send invitation emails (iTIP REQUEST) to participants. Stalwart
|
||||
// 0.16 does not reliably queue these server-side via
|
||||
// `sendSchedulingMessages`, so fall back to a client-side iMIP send.
|
||||
if (sendSchedulingMessages && created.participants) {
|
||||
try {
|
||||
await client.sendImipInvitation(created);
|
||||
} catch (e) {
|
||||
debug.error('Failed to send invitation emails:', e);
|
||||
}
|
||||
}
|
||||
return mappedCreated;
|
||||
} catch (error) {
|
||||
debug.error('Failed to create event:', error);
|
||||
@@ -559,9 +566,23 @@ export const useCalendarStore = create<CalendarStore>()(
|
||||
return merged;
|
||||
}),
|
||||
}));
|
||||
// Update emails (iTIP REQUEST/REPLY) are sent by the server via the
|
||||
// `sendSchedulingMessages` argument already passed above - a manual
|
||||
// iMIP send here produced duplicate emails.
|
||||
// Send invitation emails (iTIP REQUEST) when scheduling is requested.
|
||||
if (sendSchedulingMessages) {
|
||||
const mergedParticipants = cleanUpdates.participants ?? storeEvent?.participants;
|
||||
if (mergedParticipants) {
|
||||
const eventForInvitation = {
|
||||
...(storeEvent ?? {}),
|
||||
...cleanUpdates,
|
||||
id: realId,
|
||||
participants: mergedParticipants,
|
||||
} as CalendarEvent;
|
||||
try {
|
||||
await client.sendImipInvitation(eventForInvitation);
|
||||
} catch (e) {
|
||||
debug.error('Failed to send invitation emails:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
debug.error('Failed to update event:', error);
|
||||
if (isNetworkError(error)) {
|
||||
@@ -808,9 +829,6 @@ export const useCalendarStore = create<CalendarStore>()(
|
||||
try {
|
||||
// Resolve shared event IDs and client-side expanded occurrence IDs
|
||||
client = resolveAccountClient(client, storeEvent?.localAccountId);
|
||||
// Cancellation emails (iTIP CANCEL) are sent by the server via the
|
||||
// `sendSchedulingMessages` argument on the destroy below - a manual
|
||||
// iMIP send here produced duplicate emails.
|
||||
debug.log('calendar', 'Calendar deleteEvent', {
|
||||
storeId: id,
|
||||
realId,
|
||||
@@ -823,6 +841,14 @@ export const useCalendarStore = create<CalendarStore>()(
|
||||
events: state.events.filter(e => e.id !== id),
|
||||
selectedEventId: state.selectedEventId === id ? null : state.selectedEventId,
|
||||
}));
|
||||
// Send cancellation emails (iTIP CANCEL) to participants.
|
||||
if (sendSchedulingMessages && storeEvent?.participants) {
|
||||
try {
|
||||
await client.sendImipCancellation(storeEvent);
|
||||
} catch (e) {
|
||||
debug.error('Failed to send cancellation emails:', e);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
debug.error('Failed to delete event:', error);
|
||||
if (isNetworkError(error)) {
|
||||
|
||||
Reference in New Issue
Block a user