Surface channel delivery failures on agent replies instead of swallowing them
The previous fix made a broken SMTP/Telegram account non-fatal — the reply gets recorded either way now — but that also made delivery failures completely invisible: an agent sees their reply "sent" successfully with no indication the customer never actually received it. Added messages.deliveryFailed, set whenever the outbound send throws, and a warning badge on the message bubble so this is now visible instead of silent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
This commit is contained in:
1 parent
8d1f91187a
commit
b92d9801ff
8 files changed
+1258
-14
No files matched your search
+20
-13
@@ -56,7 +56,13 @@ export async function deliverAgentMessage(params: {
|
||||
// shown in the thread) and the API route's catch-all turned it into a
|
||||
// misleading "Ticket not found". A broken mail/bot account should degrade
|
||||
// to "reply saved internally, not delivered" — never silent data loss.
|
||||
// A ticket only ever has one channel, so at most one of the two branches
|
||||
// below runs — this single flag is the outcome of whichever one does, and
|
||||
// is what lets the agent tell "saved" from "the customer actually got
|
||||
// this" in the UI (see messages.deliveryFailed).
|
||||
let emailMessageId: string | undefined;
|
||||
let deliveryFailed = false;
|
||||
|
||||
if (ticket.channel === "email") {
|
||||
const context = await getEmailThreadContext(params.ticketId);
|
||||
if (context) {
|
||||
@@ -72,22 +78,12 @@ export async function deliverAgentMessage(params: {
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Failed to send reply email for ticket ${params.ticketId}:`, err);
|
||||
deliveryFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const result = await recordAgentReply({
|
||||
ticketId: params.ticketId,
|
||||
agentId: params.agentId,
|
||||
agentName: params.agentName,
|
||||
body: params.body,
|
||||
emailMessageId,
|
||||
attachments: attachmentInput ? [attachmentInput] : undefined,
|
||||
});
|
||||
|
||||
if (result.ticket.channel === "telegram") {
|
||||
} else if (ticket.channel === "telegram") {
|
||||
const customer = await db.query.customers.findFirst({
|
||||
where: eq(customers.id, result.ticket.customerId),
|
||||
where: eq(customers.id, ticket.customerId),
|
||||
});
|
||||
if (customer?.telegramChatId) {
|
||||
try {
|
||||
@@ -102,9 +98,20 @@ export async function deliverAgentMessage(params: {
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to deliver reply via Telegram for ticket ${params.ticketId}:`, err);
|
||||
deliveryFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const result = await recordAgentReply({
|
||||
ticketId: params.ticketId,
|
||||
agentId: params.agentId,
|
||||
agentName: params.agentName,
|
||||
body: params.body,
|
||||
emailMessageId,
|
||||
deliveryFailed,
|
||||
attachments: attachmentInput ? [attachmentInput] : undefined,
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user